-
Notifications
You must be signed in to change notification settings - Fork 11
/
CMakeLists.txt
175 lines (149 loc) · 10.1 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# Flow-IPC
# Copyright 2023 Akamai Technologies, Inc.
#
# Licensed under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in
# compliance with the License. You may obtain a copy
# of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in
# writing, software distributed under the License is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing
# permissions and limitations under the License.
cmake_minimum_required(VERSION 3.26.3) # See FlowLikeCodeGenerate.cmake for details.
# See that guy; it'll explain inside. It mandates the following procedure and documents details.
set(PROJ "ipc")
message(CHECK_START "(Project [${PROJ}] root CMake script executing.)")
list(APPEND CMAKE_MESSAGE_INDENT "- ")
set(PROJ_CAMEL "Ipc")
# TODO: Get it from nearest `VERSION` file perhaps.
set(PROJ_VERSION "1.0.0")
set(PROJ_HUMAN "Flow-IPC")
# The children below rely on this being set and its value to detect they're part of the meta-project,
# as opposed to being loaded separately, and then to load needed things off this place.
# So in *nix setting this indicates to each kid below that they're a part of one big `make`.
# (Whereas otherwise each kid is on its own and assumes the all its dependencies have had `make` and `make install`
# done, and the exported stuff is somewhere the `make` will know to search.)
set(FLOW_LIKE_META_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
# The following might be a little tough to realize if looking through multiple layers of CMake scripts, so
# for your convenience let's summarize how we do the whole thing.
# - For each project X of the sub-projects (listed just below in $IPC_META_PROJECTS), in dependency order:
# - Run its X/CMakeLists.txt. It will:
# - include(FlowLikeCodeGenerate). This makes code generation targets (unless turned off via a particular CFG_):
# - Build library (from its X/src/CMakeLists.txt).
# - Build tests (from its X/test/{basic|suite}/CMakeLists.txt); can be enabled/disabled via CFG_ x 2.
# - include(FlowLikeDocGenerate). This makes doc generation targets (unless turned off via a particular CFG_):
# - (As of this writing only X = `flow` has its own documentation. The rest of the docs are monolithic;
# see a few lines down. So only `flow` does that; the rest do not include(FlowLikeDocGenerate).
# - For our own project, which of course depends on ~all of the above: We are already in our CMakeLists.txt;
# you are reading it. So after the above add_subdirectory() x (# of $IPC_META_PROJECTS), we do:
# - include(FlowLikeCodeGenerate). Same as for each guy above.
# - Build tests (from its X/test/{basic|suite}/CMakeLists.txt); can be enabled/disabled via CFG_ x 2.
# - (As of this writing no library to build; though it'd be easy to add it if it made sense.)
# - include(FlowLikeDocGenerate). Same as for each guy above.
# - (This is where we generate the targets for monolithic documentation for all of ipc_* together.
#
# Thus, assuming *nix, after going through each bullet above in order, the following is possible:
# - `make`: Makes all the libraries and all the tests (modulo CFG_* enabling/disabling parts).
# - `make flow_doc_full flow_doc_public`: Makes `flow` docs.
# - `make ipc_doc_full ipc_doc_public`: Makes `ipc_*` monolithic docs.
# - `make install`: Exports the results of `make` (code, not docs) into $CMAKE_INSTALL_PREFIX/{lib|bin|include|...}.
# - There are also a couple of trivial and boring scripts named stage_generated_docs.sh which will package up
# the flow and ipc docs into 2 tarballs suitable for HTTP(S) hosting; and place them in a certain location nearby.
#
# So now let's do the bullet points listed above. First, the sub-projects.
# Load these guys in dependency order (each guy precedes the guy that needs it, matching the required-dependency
# statements present in each guy's own project()y CMakeLists.txt). Normally we'd just add_subdirectory() each
# one, in said dependency order, right here. However we'd like a couple extra features:
# - We want the user to be able to symlink any of the N components to their true location outside of `.`,
# instead of it simply being here (such as after a tar unpack).
# - A simple add_subdirectory(X), where X is a symlink to ../(somewhere), works great... except at least the
# generated Makefile(s) will silently refuse to incrementally build if a source file in ../(somewhere)
# is touched: it'll just do nothing. So add_subdirectory(REAL_X), where X points to REAL_X, appears to be
# necessary.
# - It'd be nice, and in the CMake spirit, to be able to simply specify each guy's location as a CMake cache
# setting. (No known use case truly requires this; a symlink should be possible to set up; but the
# CMake-yness of it feels compelling.)
# So we do both.
#
# Now, in dependency order:
set(IPC_META_PROJECTS flow ipc_core ipc_transport_structured ipc_session ipc_shm ipc_shm_arena_lend)
foreach(ipc_meta_project ${IPC_META_PROJECTS})
block()
message(CHECK_START "(Determining absolute/un-symlinked path for sub-project [${ipc_meta_project}].)")
list(APPEND CMAKE_MESSAGE_INDENT "- ")
# Regardless of anything try to resolve ./${ipc_meta_project} (whether it's simply a dir or a symlink).
set(ipc_meta_project_dir ${CMAKE_CURRENT_SOURCE_DIR}/${ipc_meta_project})
if(EXISTS ${ipc_meta_project_dir})
file(REAL_PATH ${ipc_meta_project_dir} ipc_meta_project_dir)
message(VERBOSE "[./${ipc_meta_project}] exists => [${ipc_meta_project_dir}]. "
"You may override it via cache setting.")
else()
message(VERBOSE "[./${ipc_meta_project}] = [${ipc_meta_project_dir}] does not exist (as a dir or symlink); "
"will need to be supplied via cache setting.")
set(ipc_meta_project_dir "<unknown>")
endif()
set(FLOW_LIKE_META_ROOT_${ipc_meta_project} ${ipc_meta_project_dir} CACHE STRING
"Location of sub-project [${ipc_meta_project}]; defaults to resolved [./${ipc_meta_project}] if exists.")
if(NOT (EXISTS ${FLOW_LIKE_META_ROOT_${ipc_meta_project}}))
message(FATAL_ERROR "[${FLOW_LIKE_META_ROOT_${ipc_meta_project}}] does not exist. Therefore: "
"Unable to determine FLOW_LIKE_META_ROOT_${ipc_meta_project}; either symlink "
"[./${ipc_meta_project}], place sub-project there directly, or set "
"cache setting explicitly. You may need to now clear cache (or blow away build) "
"for the symlink or direct-placement methods to work.")
endif()
list(POP_BACK CMAKE_MESSAGE_INDENT)
message(CHECK_PASS "(Path = [${FLOW_LIKE_META_ROOT_${ipc_meta_project}}]; it exists.)")
endblock()
endforeach()
include("${FLOW_LIKE_META_ROOT_flow}/tools/cmake/FlowLikeProject.cmake") # Determine $PROJ_VERSION, at least.
project(${PROJ_CAMEL} VERSION ${PROJ_VERSION} DESCRIPTION ${PROJ_HUMAN} LANGUAGES CXX)
# Got through that; now actually do the add_subdirectory()s. This needs to below the project() call just above.
# (Also, output/error handling is crisper this way than doing add_subdirectory() within the above loop.)
foreach(ipc_meta_project ${IPC_META_PROJECTS})
# Finally! Note in the build output the name is normalized to simply ${ipc_meta_project} (e.g., "flow").
add_subdirectory(${FLOW_LIKE_META_ROOT_${ipc_meta_project}} ${ipc_meta_project})
endforeach()
# Going back to the summary comment, we're now done with the sub-projects' code generation and, where applicable,
# per-project doc generation. Now finish up by doing our own stuff.
# The code generation, as noted, as of this writing = tests. (Conceivably, if we had src/ stuff to build, then
# that would also get built just as for each of the IPC_META_PROJECTs. We'd still just need the following line;
# no changes.)
include("${FLOW_LIKE_META_ROOT_flow}/tools/cmake/FlowLikeCodeGenerate.cmake")
# As noted in the summary FlowLikeCodeGenerate.cmake does not do doc generation.
# FlowLikeDocGenerate.cmake does that; and it's up to each project root CMake script to include() it.
# So let's do it, much like flow/CMakeLists.txt (which handles its own docs) does.
# See this guy; it'll explain inside. It mandates the following procedure and documents details.
set(DOC_GEN_CMAKE_SCRIPT "${FLOW_LIKE_META_ROOT_flow}/tools/cmake/FlowLikeDocGenerate.cmake")
# It may also be instructive to contrast with `flow`'s CMakeLists.txt.
# - Flow has its own self-contained doc generation, though it uses the same FlowLikeDocGenerate utility.
# - But Flow-IPC has monolithic documentation.
# - Therefore you see several ipc_*/src/ipc source trees being merged together here.
# - And Flow-IPC has a monolithic additional set of *.dox.txt files which add a guided Manual.
# - Therefore you see src/doc/manual, which lives directly inside this meta-project as opposed to any kid.
set(DOC_INPUT
${FLOW_LIKE_META_ROOT_ipc_core}/src/ipc
${FLOW_LIKE_META_ROOT_ipc_transport_structured}/src/ipc
${FLOW_LIKE_META_ROOT_ipc_session}/src/ipc
${FLOW_LIKE_META_ROOT_ipc_shm}/src/ipc
${FLOW_LIKE_META_ROOT_ipc_shm_arena_lend}/src/ipc
src/doc/manual)
# For now I (ygoldfel) am excluding echan's SHM-jemalloc stuff which *has* been integrated into Flow-IPC
# at large; I just have not gone over it and polished and eliminated Doxy-warnings and what-not. echan may have
# partially; anyway it'll be done soon.
# TODO: That.
set(DOC_EXCLUDE_PATTERNS
*/ipc/session/standalone/shm/arena_lend/* */ipc/shm/arena_lend/*)
# Lastly the guided Manual has some images which live here.
set(DOC_IMAGE_PATH src/doc/manual/assets/img)
include(${DOC_GEN_CMAKE_SCRIPT})
# Last note: Indeed there's the Flow-IPC generated docs; and the separate Flow generated docs.
# By doing add_subdirectory(flow) we added the `make` (or equivalent) targets flow_doc_*.
# By doing the stuff immediately above we added the targets ipc_doc_*.
# Yay!
list(POP_BACK CMAKE_MESSAGE_INDENT)
message(CHECK_PASS "(Done, success.)")