CMake is an open-source, cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice. The suite of CMake tools were created by Kitware in response to the need for a powerful, cross-platform build environment for open-source projects such as ITK and VTK.

Cmake安装

参考官网:https://cmake.org/download/

Cmake工程结构

project
1
2
3
4
5
6
|---include
|---src
|---CMakeLists.txt
|---demo
|---CMakeLists.txt
|---libs

CMakeLists.txt

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
Project CMakeLists.txt
# CMake最低版本号要求
cmake_minimum_required(VERSION 2.8)

# 指定项目名称
project(CMakeDemo)

# 指定版本信息
set(CMAKE_SYSTEM_VERSION 1)

# 若是需要指定编译器路径
# set(CROSS_TOOLCHAIN_PREFIX "/path/arm-linux-")
# 指定编译器
# set(CMAKE_C_COMPILER   "${CROSS_TOOLCHAIN_PREFIX}gcc")
# set(CMAKE_CXX_COMPILER "${CROSS_TOOLCHAIN_PREFIX}g++")

# 使用默认路径的g++指定编译器  
set(CMAKE_CXX_COMPILER "g++")

# 指定编译选项
set(CMAKE_BUILD_TYPE Debug )

# 指定编译目录
set(PROJECT_BINARY_DIR ${PROJECT_SOURCE_DIR}/build)

# 添加子目录,这样进入源码文件src目录可以继续构建  
add_subdirectory(${PROJECT_SOURCE_DIR}/src)

src CMakeLists.txt
# 查找当前目录下的所有源文件,
# 并将名称保存到DIR_LIB_SRCS目录
# aux_source_directory(. DIR_LIB_SRCS)

# 指定头文件目录,PROJECT_SOURCE_DIR为工程的根目录  
include_directories(${PROJECT_SOURCE_DIR}/include)

# 指定可执行文件的输出目录,输出到bin下面  
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

# 生成动态库    
add_library(shared_demo SHARED lib_demo.cpp)
# 设置库输出名为 shared => libshared.so  
set_target_properties(shared_demo PROPERTIES OUTPUT_NAME "shared")
 
# 生成静态库  
add_library(static_demo STATIC lib_demo.cpp)  
# 设置输库出名为 static => libstatic.a  
set_target_properties(static_demo PROPERTIES OUTPUT_NAME "static")

# 指定库文件输出路径  
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

# 在指定目录下查找库,并保存在LIBPATH变量中
find_library(LIBPATHS  shared ${PROJECT_SOURCE_DIR}/lib)  

# 指定生成目标
add_executable(main main.cpp)

# 链接共享库
target_link_libraries(main ${LIBPATHS})

通用型CMakeLists.txt

参考freeopcua开源库的CMakeLists.txt

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
#
# For x64 compile, please use command
# mkdir build && cd build
# cmake ..
# make -j8
# For arm cross compile, please use command
# mkdir build && cd build
# cmake -DPLATFORM=arm ..
# make -j8
#

# Cmake request lowerest version.
cmake_minimum_required(VERSION 3.5)

# For C++ Project
# set_property(TARGET run_demo PROPERTY C_STANDARD 99)
# set_property(TARGET run_demo PROPERTY C_STANDARD_REQUIRED ON)

# For C Project
# set_property(TARGET run_demo PROPERTY CXX_STANDARD 11)
# set_property(TARGET run_demo PROPERTY CXX_STANDARD_REQUIRED ON)

message(STATUS "Project Source path " ${PROJECT_SOURCE_DIR})
message(STATUS "Project Current list dir " ${CMAKE_CURRENT_LIST_DIR})

# Option can use the OFF or ON to build the each mode.
option(BUILD_C++_PROJECT "Build C++ Project" ON)
option(BUILD_C_PROJECT "Build C Project" ON)

# Set output file path.
SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
CACHE PATH
""
)

SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY
${PROJECT_BINARY_DIR}/bin
CACHE PATH
""
)

SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
CACHE PATH
""
)

if(BUILD_C++_PROJECT)
# Arm platform
if (PLATFORM MATCHES "arm")
# Set up the build operating system for Cmake.
set(CMAKE_SYSTEM_NAME Linux)
# Set up the Cmake compiler execution platform.
set(CMAKE_SYSTEM_PROCESSOR arm)

MESSAGE(STATUS "PLATFORM NAME " ${PLATFORM})
# Set up the cross compilation tool for Cmake.
set(CMAKE_CXX_COMPILER /yourpath/arm-none-linux-gnueabi-g++)
set(CMAKE_C_COMPILER /yourpath/arm-none-linux-gnueabi-gcc)

MESSAGE(STATUS "CMAKE_CXX_COMPILER NAME " ${CMAKE_CXX_COMPILER})
MESSAGE(STATUS "CMAKE_C_COMPILER NAME " ${CMAKE_C_COMPILER})
# Set the compile options for g++
set(GNU_FLAGS "-mfpu=vfp -fPIC -g -W -O2 -DBOOST_ASIO_DISABLE_STD_FUTURE")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_FLAGS}")
# Set contains arm third-party library header files
include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/include)
# Set including arm third-party libraries
link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/lib)

else()
# Linux X86 platform.
set(GNU_FLAGS "-DCOM_X64 -g -W")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_FLAGS}")

# Contains x86 third-party library header files
include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/include)
# Including x86 third-party libraries
link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/lib)

endif()

# Add your project header files.
include_directories(${PROJECT_SOURCE_DIR}/include/)

# Add the file to the any_name variable.
set(any_name
${PROJECT_SOURCE_DIR}/src/your_add_1.cpp
${PROJECT_SOURCE_DIR}/src/your_add_2.cpp
${PROJECT_SOURCE_DIR}/src/your_add_3.cpp)

# Build the any_name variable a lib.
# STATIC, SHARED, and MODULE are used to specify the type of library file to be generated.
# Share lib.
add_library(any_name_lib STATIC ${any_name})
# Open build the shared library.
option(BUILD_SHARED_LIBS "Build the shared library" ON)
# Static lib.
# add_library(any_name_lib STATIC ${any_name})

# Build the third-party input your lib, can link share lib or static lib.
target_link_libraries(any_name_lib
dl
pthread
${CMAKE_CURRENT_LIST_DIR}/libs/libjsoncpp.a
)
# Build the third-party header files input your lib, can link share lib or static lib.
target_include_directories(any_name_lib
${CMAKE_CURRENT_LIST_DIR}/libs/json/include)

# Set any_name_lib lib target c++ stand version.
set_property(TARGET any_name_lib PROPERTY CXX_STANDARD 11)
set_property(TARGET any_name_lib PROPERTY CXX_STANDARD_REQUIRED ON)

# Set the lib of version num.
set(MAJOR 1)
set(MINOR 0)
set(PATCH 0)
if(BUILD_SHARED_LIBS)
set_target_properties(any_name_lib
PROPERTIES
SOVERSION ${MAJOR}
VERSION ${MAJOR}.${MINOR}.${PATCH}
)
endif()

# Build with main function to be one run file.
add_executable(main_app
${PROJECT_SOURCE_DIR}/src/main.cpp
)

# Set the main_app target c++ stand version.
set_property(TARGET main_app PROPERTY CXX_STANDARD 11)
set_property(TARGET main_app PROPERTY CXX_STANDARD_REQUIRED ON)

# Link with main function with the link share lib or static lib to be one run file.
target_link_libraries(main_app any_name_lib
pthread
${CMAKE_CURRENT_LIST_DIR}/libs/libjsoncpp.a)
# If no any_name_lib, link with main function with the link share lib or static lib to be one run file.
# target_link_libraries(main_app
# pthread
# ${CMAKE_CURRENT_LIST_DIR}/libs/libjsoncpp.a)

endif()

if(BUILD_C_PROJECT)
# Arm platform
if (PLATFORM MATCHES "arm")
# Set up the build operating system for Cmake.
set(CMAKE_SYSTEM_NAME Linux)
# Set up the Cmake compiler execution platform.
set(CMAKE_SYSTEM_PROCESSOR arm)

MESSAGE(STATUS "PLATFORM NAME " ${PLATFORM})
# Set up the cross compilation tool for Cmake.
set(CMAKE_CXX_COMPILER /yourpath/arm-none-linux-gnueabi-g++)
set(CMAKE_C_COMPILER /yourpath/arm-none-linux-gnueabi-gcc)

MESSAGE(STATUS "CMAKE_CXX_COMPILER NAME " ${CMAKE_CXX_COMPILER})
MESSAGE(STATUS "CMAKE_C_COMPILER NAME " ${CMAKE_C_COMPILER})
# Set the compile options for g++
set(GNU_FLAGS "-mfpu=vfp -fPIC -g -W -O2 -DBOOST_ASIO_DISABLE_STD_FUTURE")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_FLAGS}")
# Set contains arm third-party library header files
include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/include)
# Set including arm third-party libraries
link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/lib)

else()
# Linux X86 platform.
set(GNU_FLAGS "-DCOM_X64 -g -W")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_FLAGS}")

# Contains x86 third-party library header files
include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/include)
# Including x86 third-party libraries
link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/lib)

endif()

# Add your project header files.
include_directories(${PROJECT_SOURCE_DIR}/include/)

# Add the file to the any_name variable.
set(any_name
${PROJECT_SOURCE_DIR}/src/your_add_1.c
${PROJECT_SOURCE_DIR}/src/your_add_2.c
${PROJECT_SOURCE_DIR}/src/your_add_3.c)

# Build the any_name variable a lib.
# STATIC, SHARED, and MODULE are used to specify the type of library file to be generated.
# Share lib.
add_library(any_name_lib STATIC ${any_name})
# Open build the shared library.
option(BUILD_SHARED_LIBS "Build the shared library" ON)
# Static lib.
# add_library(any_name_lib STATIC ${any_name})

# Build the third-party input your lib, can link share lib or static lib.
target_link_libraries(any_name_lib
dl
pthread
${CMAKE_CURRENT_LIST_DIR}/libs/libjsoncpp.a
)
# Build the third-party header files input your lib, can link share lib or static lib.
target_include_directories(any_name_lib
${CMAKE_CURRENT_LIST_DIR}/libs/json/include)

# Set any_name_lib lib target c++ stand version.
set_property(TARGET run_demo PROPERTY C_STANDARD 99)
set_property(TARGET run_demo PROPERTY C_STANDARD_REQUIRED ON)

# Set the lib of version num.
set(MAJOR 1)
set(MINOR 0)
set(PATCH 0)
if(BUILD_SHARED_LIBS)
set_target_properties(any_name_lib
PROPERTIES
SOVERSION ${MAJOR}
VERSION ${MAJOR}.${MINOR}.${PATCH}
)
endif()

# Build with main function to be one run file.
add_executable(main_app
${PROJECT_SOURCE_DIR}/src/main.c
)

# Set the main_app target c++ stand version.
set_property(TARGET run_demo PROPERTY C_STANDARD 99)
set_property(TARGET run_demo PROPERTY C_STANDARD_REQUIRED ON)

# Link with main function with the link share lib or static lib to be one run file.
target_link_libraries(main_app any_name_lib
pthread
${CMAKE_CURRENT_LIST_DIR}/libs/libjsoncpp.a)
# If no any_name_lib, link with main function with the link share lib or static lib to be one run file.
# target_link_libraries(main_app
# pthread
# ${CMAKE_CURRENT_LIST_DIR}/libs/libjsoncpp.a)
endif()

Cmake 参考

Cmake动态库

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
#
# For x64 compile, please use command
# cmake -DCMAKE_BUILD_TYPE=Debug ..
# For arm cross compile, please use command
# cmake -DPLATFORM=arm -DCMAKE_BUILD_TYPE=Release ..
# make -j4 && make install
#
cmake_minimum_required (VERSION 3.5)

# 打开动态库开关
option(BUILD_SHARED_LIBS "Build the math shared library" ON)
# 设置动态库的版本号
set(MAJOR 1)
set(MINOR 0)
set(PATCH 0)

# 设置构建版本
set(CMAKE_BUILD_TYPE Debug)
# 指定项目名称
project(212)
# 设置g++编译版本
set(CMAKE_CXX_STANDARD 11)

MESSAGE(STATUS "PROJECT NAME " ${CMAKE_PROJECT_NAME})
MESSAGE(STATUS "PROJECT NAME " ${CMAKE_})
MESSAGE(STATUS "PROJECT NAME " ${CMAKE_PROJECT_NAME})

if(CMAKE_BUILD_TYPE MATCHES "Debug" OR CMAKE_BUILD_TYPE MATCHES "None")
MESSAGE(STATUS "CMAKE_BUILD_TYPE is Debug")
elseif(CMAKE_BUILD_TYPE MATCHES "Release")
message(STATUS "CMAKE_BUILD_TYPE is Release")
else()
MESSAGE(STATUS "unknown CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE})
endif()

#Arm平台
if (PLATFORM MATCHES "arm")
# 设置Cmake的编译操作系统
set(CMAKE_SYSTEM_NAME Linux)
# 设置Cmake的编译执行平台
set(CMAKE_SYSTEM_PROCESSOR arm)

MESSAGE(STATUS "PLATFORM NAME " ${PLATFORM})
# 设置Cmake的交叉编译工具
set(CMAKE_CXX_COMPILER /opt/arm-2014.05/bin/arm-none-linux-gnueabi-g++)
set(CMAKE_C_COMPILER /opt/arm-2014.05/bin/arm-none-linux-gnueabi-gcc)

MESSAGE(STATUS "CMAKE_CXX_COMPILER NAME " ${CMAKE_CXX_COMPILER})
MESSAGE(STATUS "CMAKE_C_COMPILER NAME " ${CMAKE_C_COMPILER})
# 设置g++的编译选项
set(GNU_FLAGS "-mfpu=vfp -fPIC -g -W -O2 -DBOOST_ASIO_DISABLE_STD_FUTURE")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_FLAGS}")
# 包含第三方含库头文件
include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/jsoncpp/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/glog/include)
# 包含第三方库
link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/jsoncpp/lib)
link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/lib)
link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/glog/lib)

else()
# Linxu X86平台
set(GNU_FLAGS "-DCOM_X64 -g -W")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_FLAGS}")

include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/x64/jsoncpp/include/)

link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/x64/jsoncpp/lib)

endif()

# 添加头文件
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
# 添加工程src文件
aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/src ALL_SRC)

# 编译src文件成可执行文件212_demo
# add_executable(212_demo ${ALL_SRC})

# 添加动态库
add_library(212 SHARED ${ALL_SRC})
set_property(TARGET 212 PROPERTY CXX_STANDARD 11)
set_property(TARGET 212 PROPERTY CXX_STANDARD_REQUIRED ON)

# 编译链接库动态和静态库
if (PLATFORM MATCHES "arm")
target_link_libraries(212 dl glog pthread rt boost_system boost_regex
${CMAKE_CURRENT_LIST_DIR}/libs/arm/jsoncpp/lib/libjsoncpp.a)

else()
target_link_libraries(212 dl glog jsoncpp pthread rt boost_system boost_regex)

endif()

# 设置动态库的版本号
if(BUILD_SHARED_LIBS)
set_target_properties(212
PROPERTIES
SOVERSION ${MAJOR}
VERSION ${MAJOR}.${MINOR}.${PATCH}
)
endif()

# list(APPEND TARGET_LIBRARIES 212)

# file(GLOB ALL_HEADERS ${CMAKE_CURRENT_LIST_DIR}/include/*.h)

# install(FILES ${ALL_HEADERS}
# DESTINATION "${CMAKE_CURRENT_LIST_DIR}/build/include"
# )

# install(TARGETS ${TARGET`_LIBRARIES}
# DESTINATION "${CMAKE_CURRENT_LIST_DIR}/build/lib/${CMAKE_BUILD_TYPE}"
# )


# Other Version

#
# For x64 compile, please use command
# cmake -DCMAKE_BUILD_TYPE=Debug ..
# For arm cross compile, please use command
# cmake -DPLATFORM=arm -DCMAKE_BUILD_TYPE=Release ..
# make -j4 && make install
#

cmake_minimum_required(VERSION 3.5)

project(freeopc_demo)

set(CMAKE_CXX_STANDARD 11)

if(CMAKE_BUILD_TYPE MATCHES "Debug" OR CMAKE_BUILD_TYPE MATCHES "None")
MESSAGE(STATUS "CMAKE_BUILD_TYPE is Debug")
elseif(CMAKE_BUILD_TYPE MATCHES "Release")
MESSAGE(STATUS "CMAKE_BUILD_TYPE is Release")
else()
MESSAGE(STATUS "unknown CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE})
endif()

if(PLATFORM MATCHES "arm")
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

MESSAGE(STATUS "PLATFORM NAME " ${PLATFORM})

set(CMAKE_CXX_COMPILER /opt/arm-2014.05/bin/arm-none-linux-gnueabi-g++)
set(CMAKE_C_COMPILE /opt/arm-2014.05/bin/arm-none-linux-gnueabi-gcc)

set(GNU_FLAGS "-mfpu=vfp -fPIC -g -W -O2")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_FLAGS}")


else()
set(GNU_FLAGS "-DCOM_X64 -g -W")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_FLAGS}")

include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/x64/freeopcua/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/x64/open62541/include)

link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/x64/freeopcua/lib)
link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/x64/open62541/lib)

endif()

include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/src ALL_SRC)

demo动态库

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
#
# mkdir build
# cd build
# For x64 compile, please use command
# cmake -DCMAKE_BUILD_TYPE=Debug ..
# For arm cross compile, please use command
# cmake -DPLATFORM=arm -DCMAKE_BUILD_TYPE=Release ..
# make -j4
#
cmake_minimum_required(VERSION 3.5) # CMake version check
include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)

if(CMAKE_BUILD_TYPE MATCHES "Debug" OR CMAKE_BUILD_TYPE MATCHES "None")
MESSAGE(STATUS "CMAKE_BUILD_TYPE is Debug")
elseif(CMAKE_BUILD_TYPE MATCHES "Release")
message(STATUS "CMAKE_BUILD_TYPE is Release")
else()
MESSAGE(STATUS "unknown CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE})
endif()

if(PLATFORM MATCHES "arm")
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_CXX_COMPILER /opt/arm-2014.05/bin/arm-none-linux-gnueabi-g++)
set(CMAKE_C_COMPILER /opt/arm-2014.05/bin/arm-none-linux-gnueabi-gcc)

set(GNU_FLAGS "-mfpu=vfp -fPIC -g -W -DBOOST_ASIO_DISABLE_STD_FUTURE")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_FLAGS}")

include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/jsoncpp/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/glog/include)

link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/jsoncpp/lib)
link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/boost/lib)
link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/arm/glog/lib)
else()
set(GNU_FLAGS "-DCOM_X64 -g -W")
set(CMAKE_CXX_FLAGS "${GNU_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_FLAGS}")

include_directories(${CMAKE_CURRENT_LIST_DIR}/lib/x64/boost/include)

link_directories(${CMAKE_CURRENT_LIST_DIR}/lib/x64/boost/lib)
endif()

#include_directories(${CMAKE_CURRENT_LIST_DIR}/libs/x64/jsoncpp/include/)
#link_directories(${CMAKE_CURRENT_LIST_DIR}/libs/x64/jsoncpp/lib)

add_executable(demo demo.cpp)
set_property(TARGET demo PROPERTY CXX_STANDARD 11)
set_property(TARGET demo PROPERTY CXX_STANDARD_REQUIRED ON)
target_link_libraries(demo dl glog jsoncpp pthread rt)

# Other Version
#
# For x64 compile, please use command
# cmake -DCMAKE_BUILD_TYPE=Debug ..
# For arm cross compile, please use command
# cmake -DPLATFORM=arm -DCMAKE_BUILD_TYPE=Release ..
# make -j4 && make install
#

cmake_minimum_required(VERSION 3.5)
include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)

# include_directories(${PROJECT_SOURCE_DIR}/include)
# aux_source_directory(${PROJECT_SOURCE_DIR}/src ALL_SRC)

add_executable(demo demo.cpp ${ALL_SRC})
set_property(TARGET demo PROPERTY CXX_STANDARD 11)
set_property(TARGET demo PROPERTY CXX_STANDARD_REQUIRED ON)
target_link_libraries(demo opcuaclient opcuaprotocol opcuacore glog pthread)

CmakeTool配置文件

  Cmake是支持在CmakeLists.txt外配置编译工具,这样主要是在交叉编译第三方的库时,会不用直接修改原CMakeLists.txt
创建一个arm.cmake文件

arm.cmake
1
2
3
4
5
6
7
8
9
10
11
12
set(CMAKE_SYSTEM_NAME Linux)    #设置交叉编译系统
set(CMAKE_SYSTEM_PROCESSOR arm) #设置交叉编译平台

set(CMAKE_C_COMPILER /opt/arm-2014.05/bin/arm-none-linux-gnueabi-gcc) #设置交叉编译gcc编译链
set(CMAKE_CXX_COMPILER /opt/arm-2014.05/bin/arm-none-linux-gnueabi-g++) #设置交叉编译g++编译链

# 设置交叉编译的参数
set(GNU_CXX_FLAGS "-mfpu=vfp -std=c++11 -fPIC -g -W -O2 -DBOOST_ASIO_DISABLE_STD_FUTURE")
set(GNU_C_FLAGS "-mfpu=vfp -fPIC -g -W -O2 -std=c99")
set(CMAKE_CXX_FLAGS "${GNU_CXX_FLAGS}")
set(CMAKE_C_FLAGS "${GNU_C_FLAGS}")

CMake-官方文档(原文)

这份渐进式的教程涵盖了 CMake 帮助处理的一些常见的构建问题。许多议题已经在《Mastering CMake》中作为独立的话题介绍过,但是了解它们是如何在示例项目中结合在一起的将非常有帮助。你可以在 CMake 源码中的 Tests/Tutorial 文件夹找到这份教程,每一步的内容都放置在各自的子文件夹中。

一个基本的出发点 (Step1)

最简单的项目是从源代码文件中构建一个可执行文件,CMakeLists.txt 文件仅需要两行,这将作为我们教程的起点,内容如下:

1
2
3
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
add_executable(Tutorial tutorial.cxx)

文件中的命令支持大写、小写或者混合使用,这个例子中的命令使用小写。tutorial.cxx 用于计算一个数的平方根,源码的第一版非常简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 计算一个数的平方根
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (int argc, char *argv[])
{
if (argc < 2)
{
fprintf(stdout,"Usage: %s number\n",argv[0]);
return 1;
}
double inputValue = atof(argv[1]);
double outputValue = sqrt(inputValue);
fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
return 0;
}

添加一个版本号并配置头文件

你可以直接在源代码中添加版本号,但在 CMakeLists.txt 文件中提供版本号将会更加灵活,我们将文件修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
# 版本号 1.0
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)

# 配置一个头文件将一些 CMake 设置传入到源代码中
# 以 TutorialConfig.h.in 为模版,替换相关变量
# 以生成 TutorialConfig.h
configure_file (
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_BINARY_DIR}/TutorialConfig.h"
)

# 将构建目录添加到 include 的搜索路径中以便找到
# TutorialConfig.h 文件
include_directories("${PROJECT_BINARY_DIR}")

# 添加可执行文件
add_executable(Tutorial tutorial.cxx)

因为配置文件将会写入到构建目录中,所以我们将这个目录添加到包含文件的搜索路径中。在源代码中添加 TutorialConfig.h.in 文件:

1
2
3
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

当 CMake 生成这个头文件时,@Tutorial_VERSION_MAJOR@ 和 @Tutorial_VERSION_MINOR@ 的值将会由 CMakeLists.txt 中对应的值替换。接下来我们将头文件包含到 tutorial.cxx 中并且使用这个版本号,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"

int main (int argc, char *argv[])
{
if (argc < 2)
{
fprintf(stdout,"%s Version %d.%d\n",
argv[0],
Tutorial_VERSION_MAJOR,
Tutorial_VERSION_MINOR);
fprintf(stdout,"Usage: %s number\n",argv[0]);
return 1;
}
double inputValue = atof(argv[1]);
double outputValue = sqrt(inputValue);
fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
return 0;
}

主要的改变是包含了头文件并且在使用方法信息中打印了版本号。

添加一个库 (Step 2)

现在我们要在项目中添加一个库,这个库将会包含我们自己的计算平方根的实现。可执行文件将可以使用这个库,而不是使用编译器提供的平方根标准方法。本教程中将这个库放到名为 MathFunctions 的子文件夹中,这个子文件夹需要包含一个 CMakeLists.txt 文件,文件中有如下一行:

1
add_library(MathFunctions mysqrt.cxx)

mysqrt.cxx 文件中有一个叫做 mysqrt 的函数,它提供与编译器的 sqrt 函数相同的功能。我们在顶层的 CMakeLists.txt 中添加一个 add_subdirectory 调用以构建这个库。为了找到 MathFunctions/MathFunctions.h 头文件中的函数原型,我们添加另一条包含路径。最后一个改动是将这个库添加到可执行文件中。顶层 CMakeLists.txt 文件中添加的最新几行如下:

1
2
3
4
5
6
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory (MathFunctions)

# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial MathFunctions)

考虑一下将这个库设计为可选的,本教程中这样做也许是不必要的,但是当使用更大的库或者第三方的库时你也许会用到。第一步是在顶层的 CMakeLists.txt 中添加一个选择:

1
2
3
# 是否使用我们自己的函数?
option (USE_MYMATH
"Use tutorial provided math implementation" ON)

CMake GUI 中将会显示一个 ON 的默认值,用户可以按需更改。这个设置将会被缓存,这样在每次对这个项目运行 CMake 时用户不需要再次设置。接下来的更改是将 MathFunctions 库的构建和连接设置为可选的,我们在顶层 CMakeLists.txt 的最后修改如下:

1
2
3
4
5
6
7
8
9
10
# add the MathFunctions library?
if (USE_MYMATH)
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory (MathFunctions)
set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)

# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial ${EXTRA_LIBS})

这将根据 USE_MYMATH 的设置来决定是否编译并使用 MathFunctions 库。注意这里使用了一个 EXTRA_LIBS 变量来收集任何可选的库,以在之后链接到可执行文件中。对有许多可选组件的项目,这是一种保持其整洁的常用方法。相应的源代码更改如下:

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
/ A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
#include "MathFunctions.h"
#endif

int main (int argc, char *argv[])
{
if (argc < 2)
{
fprintf(stdout,"%s Version %d.%d\n", argv[0],
Tutorial_VERSION_MAJOR,
Tutorial_VERSION_MINOR);
fprintf(stdout,"Usage: %s number\n",argv[0]);
return 1;
}

double inputValue = atof(argv[1]);

#ifdef USE_MYMATH
double outputValue = mysqrt(inputValue);
#else
double outputValue = sqrt(inputValue);
#endif

fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
return 0;
}

在源代码中我们同样使用了 USE_MYMATH 变量。通过在 TutorialConfig.h.in 中添加如下配置,Cmake 将这个变量引入到源代码中:

1
#cmakedefine USE_MYMATH

安装与测试 (Step 3)

接下来我们在项目中添加安装规则和测试支持。安装规则非常直接,对于 MathFunctions 库的安装,我们在 MathFunctions 的 CMakeLists.txt 中添加如下几行:

1
2
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

对于应用程序可执行文件和头文件的安装,我们在顶层的 CMakeLists.txt 中添加如下几行:

1
2
3
4
# add the install targets
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
DESTINATION include)

万事俱备,接下来你应该可以构建这个项目,然后键入 make install (或者在 IDE 中构建 INSTALL 目标),它将会安装合适的头文件,库和执行文件。CMake 的 CMAKE_INSTALL_PREFIX 变量用于决定文件安装位置的根。添加测试也是一个同样直接的过程。在顶层 CMakeLists.txt 的结尾,我们可以添加几个基础测试以判别程序是否工作正常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
include(CTest)

# does the application run
add_test (TutorialRuns Tutorial 25)

# does it sqrt of 25
add_test (TutorialComp25 Tutorial 25)
set_tests_properties (TutorialComp25 PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5")

# does it handle negative numbers
add_test (TutorialNegative Tutorial -25)
set_tests_properties (TutorialNegative PROPERTIES PASS_REGULAR_EXPRESSION "-25 is 0")

# does it handle small numbers
add_test (TutorialSmall Tutorial 0.0001)
set_tests_properties (TutorialSmall PROPERTIES PASS_REGULAR_EXPRESSION "0.0001 is 0.01")

# does the usage message work?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")

构建完成后,可以使用命令行工具 ctest 运行测试。第一个测试只是验证程序是否运行,没有段错误或其他的崩溃,并返回零值。这是一个 CTest 测试的基本形式。接下来的几个测试都使用 PASS_REGULAR_EXPRESSION 测试属性来验证测试的输出是否包含某些字符串。这样用来验证预期的计算结果,并且当参数数目不正确时打印使用信息。如果你想添加大量测试来测试不同的输入值,你可能会考虑创建如下所示的宏:

1
2
3
4
5
6
7
8
9
10
#define a macro to simplify adding tests, then use it
macro (do_test arg result)
add_test (TutorialComp${arg} Tutorial ${arg})
set_tests_properties (TutorialComp${arg}
PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)

# do a bunch of result based tests
do_test (25 "25 is 5")
do_test (-25 "-25 is 0")

每调用一次 do_test,根据传递的参数,都会添加一个拥有名字、输入和输出的测试。

添加系统自检 (Step 4)

接下来让我们向项目中添加一些代码,这些代码依赖的功能目标平台可能没有提供。这个例子中,我们添加的代码依赖于目标平台是否提供了对数 log 和指数 exp 函数。当然几乎所有的平台都提供了这样的函数,本教程假定它们是不常见的功能。如果平台提供了 log,那么我们可以在 mysqrt 函数中使用它计算平方根。我们首先使用顶层 CMakeLists.txt 文件中的 CheckFunctionExists.cmake 宏来测试这些功能的可用性,如下所示:

1
2
3
4
# does this system provide the log and exp functions?
include (CheckFunctionExists)
check_function_exists (log HAVE_LOG)
check_function_exists (exp HAVE_EXP)

当 CMake 在平台上发现它们时,我们在 TutorialConfig.h.in 中定义这些值:

1
2
3
// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

log 和 exp 的测试需要放在 configure_file 命令之前,configure_file 命令会立即使用 CMake 中的当前设置生成文件。当系统提供了这两个函数时,我们可以使用以下代码在 mysqrt 函数中提供一个基于 log 和 exp 的替代实现:

1
2
3
4
5
// if we have both log and exp then use them
#if defined (HAVE_LOG) && defined (HAVE_EXP)
result = exp(log(x)*0.5);
#else // otherwise use an iterative approach
. . .

添加生成文件和生成器 (Step 5)

在本节中,我们将展示如何将生成的源文件添加到应用程序的构建过程中。本例中,我们将会在构建过程中创建一个预先计算的平方根表,然后将这张表编译进我们的程序中。我们首先需要一个生成这张表的程序,为此我们在 MathFunctions 的子文件夹中添加一个新的名为 MakeTable.cxx 的源文件:

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
// A simple program that builds a sqrt table
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main (int argc, char *argv[])
{
int i;
double result;

// make sure we have enough arguments
if (argc < 2)
{
return 1;
}

// open the output file
FILE *fout = fopen(argv[1],"w");
if (!fout)
{
return 1;
}

// create a source file with a table of square roots
fprintf(fout,"double sqrtTable[] = {\n");
for (i = 0; i < 10; ++i)
{
result = sqrt(static_cast<double>(i));
fprintf(fout,"%g,\n",result);
}

// close the table with a zero
fprintf(fout,"0};\n");
fclose(fout);
return 0;
}

注意这张表会以有效的 C++ 代码的形式生成,输出文件的名字以参数的形式提供。接下来向 MathFunctions 的 CMakeLists.txt 文件中添加合适的命令以构建 MakeTable 的可执行文件,并运行它作为构建过程的一部分。需要几个命令来完成此操作,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)

# add the command to generate the source code
add_custom_command (
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)

# add the binary tree directory to the search path for
# include files
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )

# add the main library
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h )

首先像添加其他执行文件那样添加 MakeTable 的执行文件。然后我们添加一个自定义命令以使用 MakeTable 生成 Table.h 文件。接下来我们需要将生成的文件添加到 MathFunctions 库的源文件列表中,以让 CMake 知道 mysqrt.cxx 依赖于 Table.h 文件。我们也需要将当前的构建文件夹添加到包含文件列表中,以让 Table.h 文件可以被发现并包含到 mysqrt.cxx 中。当构建这个项目时,它会先构建 MakeTable 的执行文件,然后运行 MakeTable 生成 Table.h 文件,最后它会编译包含有 Table.h 的 mysqrt.cxx 以生成 MathFunctions 库。此时,顶层 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
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
include(CTest)

# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)

# does this system provide the log and exp functions?
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)

check_function_exists (log HAVE_LOG)
check_function_exists (exp HAVE_EXP)

# should we use our own math functions
option(USE_MYMATH
"Use tutorial provided math implementation" ON)

# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_BINARY_DIR}/TutorialConfig.h"
)

# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories ("${PROJECT_BINARY_DIR}")

# add the MathFunctions library?
if (USE_MYMATH)
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory (MathFunctions)
set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)

# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial ${EXTRA_LIBS})

# add the install targets
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
DESTINATION include)

# does the application run
add_test (TutorialRuns Tutorial 25)

# does the usage message work?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage
PROPERTIES
PASS_REGULAR_EXPRESSION "Usage:.*number"
)


#define a macro to simplify adding tests
macro (do_test arg result)
add_test (TutorialComp${arg} Tutorial ${arg})
set_tests_properties (TutorialComp${arg}
PROPERTIES PASS_REGULAR_EXPRESSION ${result}
)
endmacro (do_test)

# do a bunch of result based tests
do_test (4 "4 is 2")
do_test (9 "9 is 3")
do_test (5 "5 is 2.236")
do_test (7 "7 is 2.645")
do_test (25 "25 is 5")
do_test (-25 "-25 is 0")
do_test (0.0001 "0.0001 is 0.01")

TutorialConfig.h.in 如下:

1
2
3
4
5
6
7
8
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH

// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

MathFunctions 的 CMakeLists.txt 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
# add the command to generate the source code
add_custom_command (
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
# add the binary tree directory to the search path
# for include files
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )

# add the main library
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h)

install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

构建安装程序 (Step 6)

接下来假设我们想将我们的项目分发给其他人,以便他们可以使用它。我们希望在各种平台上提供二进制和源代码分发。这与之前的第三步有些不同,在这个例子中,我们将构建安装包以支持二进制安装和包管理功能,比如 cygwin,debian,RPMs 等。我们将会使用 CPack 来创建平台相关的安装程序。具体来说,我们需要在我们的顶层 CMakeLists.txt 文件的底部添加几行:

1
2
3
4
5
6
7
# build a CPack driven installer package
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE
"${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
include (CPack)

我们从包含 InstallRequiredSystemLibraries 开始。该模块包含有这个项目在当前平台所需的任何运行时库。然后我们设置一些 CPack 变量指明此项目许可证和版本信息的位置。版本信息使用了本教程前面设置的变量。最后我们包含了 CPack 模块,它将使用你设置的这些变量和其他系统属性来配置安装程序。

接下来就是按照通常的方法构建项目,然后运行 CPack 命令。要构建一个二进制分发,你可以运行:

1
cpack --config CPackConfig.cmake

要创建一个源码分发,你可以键入:

1
cpack --config CPackSourceConfig.cmake

添加对仪表板的支持 (Step 7)

添加将测试结果提交给仪表板的支持非常简单。在教程之前的步骤中已经定义了一些测试,我们只需运行这些测试并且将它们提交给一个仪表板。要包括对仪表板的支持,我们将 CTest 模块包含在我们的顶层 CMakeLists.txt 文件中:

1
2
# enable dashboard scripting
include (CTest)

我们还创建一个CTestConfig.cmake文件,可以在该文件中为仪表板指定此项目的名称。

1
set (CTEST_PROJECT_NAME "Tutorial")

当运行 CTest 时它会读取这个文件。要创建简单的仪表板,你可以在项目中运行 CMake,然后切换目录到构建目录中运行 ctest –D Experimental. 仪表板的结构将会上传到 Kitware 的公共仪表板中(这里)。

C/C++宏的使用

marco_head.h
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

# 的作用 : 将传入的变量字符串化
// String the variables passed in
#define PRINTCLASS(ClassName) printout(#ClassName)

将传入的ClassName转换成字符串
PRINTCLASS(4);
----->
printout("4");

## 的作用 : 在宏中是连接两个单元(有时候定义一个变量,这个变量的名字要由外面输入,这时候就需要宏的##)
#define DeclareSomething(ArgumentName) int ArgumentName##index

连接index
DeclareSomething(name);
----->
int name##index;

#define DeclareSomething(ArgumentName, i) int ArgumentName##i
DeclareSomething(name, 4);
----->
int name4;

... 的作用 : 是可变参数宏

// varargs
#define Declare_Fun(...) typedef std::function<void(__VA_ARGS__)> iStdFunction

Declare_Fun(int,int,double);
----->
std::function<void(int,int,double)> iStdFunction;

// varargs
#define Declare_Fun (...) typedef std::function<void(int,##__VA_ARGS__)> iStdFunction

Declare_Fun (float,double);
----->
std::function<void(int, float, double)> iStdFunction;

如果在宏里不写任何参数:

Declare_Fun();
----->
std::function<void(int)> iStdFunction;
##的作用,当没有参数传入时,也可以将第一个参数后面的逗号在展开时去掉。