-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCMakeLists.txt
278 lines (246 loc) · 11.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# Prologue
cmake_minimum_required(VERSION 3.12)
project(cpp-toolkit C CXX)
# Include
set(GV_extra_dir extra)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${GV_extra_dir}/cmake")
include(common_var)
include(helper)
include(compiler)
#include(external_lib)
macro(setup_platform_environment)
set(ENV{LANG} "en_US.UTF-8")
set(ENV{LC_ALL} "en_US.UTF-8")
## Setup compilation options
compiler_set_compilation_options()
endmacro()
macro(setup_conan)
find_program(V_conan_cmd conan)
if (NOT V_conan_cmd)
message(WARNING "conan is not found!" )
else()
message("Found conan: ${V_conan_cmd}")
if(CMAKE_CONFIGURATION_TYPES) # Multi-configuration
set(V_conan_gen_files "${CMAKE_BINARY_DIR}/build/generators/conan_toolchain.cmake")
else() # Single-configuration
set(V_conan_gen_files "${CMAKE_BINARY_DIR}/build/${CMAKE_BUILD_TYPE}/generators/conan_toolchain.cmake")
endif()
message("Conan toolchain file: ${V_conan_gen_files}")
set(V_conanfile
"${PROJECT_SOURCE_DIR}/${GV_extra_dir}/conanfile.txt")
if (NOT EXISTS ${V_conanfile})
message(WARNING "${V_conanfile} is not found!" )
else()
if (${V_conanfile} IS_NEWER_THAN ${V_conan_gen_files})
file(REMOVE ${V_conan_gen_files})
# Set up compiler settings
set(V_conan_s_compiler "")
set(V_conan_s_compiler_ver "")
set(V_conan_s_compiler_cppstd "")
set(V_conan_s_compiler_libcxx "")
set(V_conan_s_compiler_rt "")
set(V_conan_s_build_type "")
if (NOT V_conan_compiler STREQUAL "")
set(V_conan_s_compiler "-s:a" "compiler=${V_conan_compiler}")
set(V_conan_s_compiler_ver "-s:a" "compiler.version=${CMAKE_CXX_COMPILER_VERSION_MAJOR}")
if (V_conan_compiler STREQUAL "msvc")
# Handle MSVC-specific version formatting
string(SUBSTRING "${CMAKE_CXX_COMPILER_VERSION_MINOR}" 0 1 V_tmp_number)
set(V_conan_s_compiler_ver "-s:a" "compiler.version=${CMAKE_CXX_COMPILER_VERSION_MAJOR}${V_tmp_number}")
set(V_conan_s_compiler_cppstd "-s:a" "compiler.cppstd=${CMAKE_CXX_STANDARD}")
set(V_conan_s_compiler_rt "-s:a" "compiler.runtime=dynamic")
elseif (V_conan_compiler STREQUAL "gcc")
set(V_conan_s_compiler_libcxx "-s:a" "compiler.libcxx=libstdc++11")
elseif (NOT "${CMAKE_CXX_COMPILER_VERSION_MINOR}" STREQUAL "")
# Optionally handle non-MSCV compilers if needed
endif()
endif()
# Set up build type
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(V_conan_s_build_type "-s:a" "build_type=Debug")
else()
set(V_conan_s_build_type "-s:a" "build_type=Release")
endif()
# Prepare the conan install command
set(V_conan_args install
"${V_conanfile}"
${V_conan_s_compiler}
${V_conan_s_compiler_ver}
${V_conan_s_compiler_cppstd}
${V_conan_s_compiler_libcxx}
${V_conan_s_compiler_rt}
${V_conan_s_build_type}
"--build=missing"
"-of=${CMAKE_BINARY_DIR}"
)
# Debug: Show the constructed command
string(REPLACE ";" " " V_conan_cmd_str "${V_conan_cmd} ${V_conan_args}")
message("Executing: ${V_conan_cmd_str}")
# Execute the conan install command
execute_process(COMMAND ${V_conan_cmd} ${V_conan_args})
endif()
## Required by conan
cmake_policy(SET CMP0091 NEW)
set(CMAKE_OSX_SYSROOT_RIGHT "${CMAKE_OSX_SYSROOT}")
include(${V_conan_gen_files})
set(CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT_RIGHT}" CACHE PATH "Sysroot for macOS" FORCE)
endif()
endif()
endmacro()
macro(setup_build_environment)
## Setup Conan
# conan_basic_setup()
setup_conan()
# add_definitions(${CONAN_DEFINES})
find_package(gRPC REQUIRED)
find_package(Boost REQUIRED)
find_package(ftxui REQUIRED)
find_package(json-c REQUIRED)
find_package(httplib REQUIRED)
find_package(nlohmann_json REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(Qt6 REQUIRED)
## Setup product options
### set_product_options()
# Paths
set(GV_external_dir ${GV_extra_dir}/external/${CMAKE_CXX_COMPILER_ID})
message("External library path: ${GV_external_dir}")
get_filename_component(GV_external_dir_a ${GV_external_dir} ABSOLUTE)
## Headers
include_directories(
# include
# ${GV_extra_dir}/gen/grpc/cpp
# ${GV_external_dir_a}/include
)
## Libraries
link_directories(
# ${GV_extra_dir}/gen/lib
# ${GV_external_dir_a}/lib
)
## Output
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
endmacro()
macro(setup_directries)
set(V_dir_gen ${PROJECT_SOURCE_DIR}/${GV_extra_dir}/gen)
set(V_dir_gen_grpc ${V_dir_gen}/grpc)
set(V_dir_gen_grpc_cpp ${V_dir_gen}/grpc/cpp)
set(V_dir_gen_lib ${V_dir_gen}/lib)
add_custom_command(
OUTPUT "${V_dir_gen}"
COMMAND ${CMAKE_COMMAND} -E make_directory ${V_dir_gen}
DEPENDS "${PROJECT_SOURCE_DIR}/${GV_extra_dir}"
)
add_custom_target(GT_dir_gen DEPENDS "${V_dir_gen}")
add_custom_command(
OUTPUT "${V_dir_gen_grpc}"
COMMAND ${CMAKE_COMMAND} -E make_directory ${V_dir_gen_grpc}
DEPENDS GT_dir_gen
)
add_custom_target(GT_dir_gen_grpc DEPENDS "${V_dir_gen_grpc}")
add_custom_command(
OUTPUT "${V_dir_gen_grpc_cpp}"
COMMAND ${CMAKE_COMMAND} -E make_directory ${V_dir_gen_grpc_cpp}
DEPENDS GT_dir_gen_grpc
)
add_custom_target(GT_dir_gen_grpc_cpp DEPENDS "${V_dir_gen_grpc_cpp}")
add_custom_command(
OUTPUT "${V_dir_gen_lib}"
COMMAND ${CMAKE_COMMAND} -E make_directory ${V_dir_gen_lib}
DEPENDS GT_dir_gen
)
add_custom_target(GT_dir_gen_lib DEPENDS "${V_dir_gen_lib}")
endmacro()
macro(setup_grpc_target)
# Target T_gen_grpc, for every proto file, generate code to gen/pb/
set(V_dir_grpc_proto_r ${GV_extra_dir}/code_to_gen/protos)
get_filename_component(V_dir_grpc_proto_a ${V_dir_grpc_proto_r} ABSOLUTE)
file(GLOB V_all_proto_files "${V_dir_grpc_proto_r}/*.proto")
unset(V_ptotoc_cmd CACHE)
get_target_property(V_ptotoc_cmd protobuf::protoc IMPORTED_LOCATION)
if (NOT V_ptotoc_cmd)
message(FATAL_ERROR "protoc is not found!" )
endif()
message("Found protoc: ${V_ptotoc_cmd}")
unset(V_ptotoc_cpp_plugin CACHE)
get_target_property(V_ptotoc_cpp_plugin gRPC::grpc_cpp_plugin IMPORTED_LOCATION)
if (NOT V_ptotoc_cpp_plugin)
message(FATAL_ERROR "grpc_cpp_plugin is not found!")
endif()
message("Found grpc_cpp_plugin: ${V_ptotoc_cpp_plugin}")
foreach(one_proto_file ${V_all_proto_files})
get_filename_component(V_bname ${one_proto_file} NAME_WE)
list(APPEND GV_proto_bnames ${V_bname})
set(V_gen_cpp_grpc_srcs
"${V_dir_gen_grpc_cpp}/${V_bname}.pb.h"
"${V_dir_gen_grpc_cpp}/${V_bname}.pb.cc"
"${V_dir_gen_grpc_cpp}/${V_bname}.grpc.pb.h"
"${V_dir_gen_grpc_cpp}/${V_bname}.grpc.pb.cc"
)
list(APPEND GV_gen_cpp_grpc_srcs ${V_gen_cpp_grpc_srcs})
add_custom_command(
OUTPUT ${V_gen_cpp_grpc_srcs}
COMMAND ${V_ptotoc_cmd}
ARGS --grpc_out "${V_dir_gen_grpc_cpp}"
--cpp_out "${V_dir_gen_grpc_cpp}"
-I "${V_dir_grpc_proto_a}"
--plugin=protoc-gen-grpc=${V_ptotoc_cpp_plugin}
${one_proto_file}
DEPENDS "${one_proto_file}" GT_dir_gen_grpc_cpp
)
add_custom_target(GT_gen_${V_bname}_grpc_cpp_src DEPENDS ${V_gen_cpp_grpc_srcs})
list(APPEND GV_gen_grpc_cpp_src_targets GT_gen_${V_bname}_grpc_cpp_src)
endforeach()
add_custom_target(GT_gen_grpc_src DEPENDS ${GV_gen_grpc_cpp_src_targets})
set(GV_gen_grpc_cpp_lib_bname gen_grpc_cpp_src)
add_library(${GV_gen_grpc_cpp_lib_bname} STATIC ${GV_gen_cpp_grpc_srcs})
target_include_directories(${GV_gen_grpc_cpp_lib_bname} PUBLIC ${V_dir_gen_grpc_cpp})
target_link_libraries(${GV_gen_grpc_cpp_lib_bname} grpc::grpc)
add_dependencies(${GV_gen_grpc_cpp_lib_bname} GT_gen_grpc_src)
set_target_properties(${GV_gen_grpc_cpp_lib_bname} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${V_dir_gen_lib}")
set_target_properties(${GV_gen_grpc_cpp_lib_bname} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${V_dir_gen_lib}")
endmacro()
macro(setup_targets)
set(GV_cpp_toolkit_src "")
get_filename_component(GV_src_path "src" ABSOLUTE)
file(GLOB GV_all_mod "${GV_src_path}/mod_*")
file(GLOB GV_all_app "${GV_src_path}/app_*")
file(GLOB GV_all_exec "${GV_src_path}/exec_*")
setup_directries()
setup_grpc_target()
# Modules library
foreach(one_dir ${GV_all_mod} ${GV_all_app})
get_filename_component(tmp_name ${one_dir} NAME)
file(GLOB GV_${tmp_name}_src "${one_dir}/*.cpp" "${one_dir}/*.c")
file(GLOB tmp_sub_dirs "${one_dir}/*")
foreach(one_sub_dir ${tmp_sub_dirs})
if(IS_DIRECTORY ${one_sub_dir})
file(GLOB tmp_sub_dir_files "${one_sub_dir}/*.cpp" "${one_sub_dir}/*.c")
list(APPEND GV_${tmp_name}_src ${tmp_sub_dir_files})
endif()
endforeach()
list(APPEND GV_cpp_toolkit_src ${GV_${tmp_name}_src})
# add_library(${tmp_name} STATIC ${GV_${tmp_name}_src})
# set_target_properties(${tmp_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${V_dir_gen_lib}")
# add_dependencies(${tmp_name} GT_gen_grpc_src GT_dir_gen_lib)
endforeach()
# Library in one
add_library(cpp_toolkit STATIC ${GV_cpp_toolkit_src})
target_link_libraries(cpp_toolkit
${GV_gen_grpc_cpp_lib_bname}
httplib::httplib ftxui::ftxui nlohmann_json::nlohmann_json
grpc::grpc boost::boost)
target_include_directories(${GV_gen_grpc_cpp_lib_bname} PUBLIC include)
set_target_properties(cpp_toolkit PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${V_dir_gen_lib}")
add_dependencies(cpp_toolkit ${GV_gen_grpc_cpp_lib_bname} GT_gen_grpc_src GT_dir_gen_lib)
# Main executable
foreach(one_dir ${GV_all_exec})
add_subdirectory(${one_dir})
endforeach()
endmacro()
macro(main_func)
setup_platform_environment()
setup_build_environment()
setup_targets()
endmacro()
# TODO Write utils.cmake, put some useful general functions
main_func()