cmake使用笔记
cmake使用笔记
记录cmake学习及使用中的一些技巧与方法
cmake命令参见:https://www.cnblogs.com/hgwang/p/9086691.html
1 消息输出message
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)
可以用下述可选的关键字指定消息的类型:
(无) = 重要消息;
STATUS = 非重要消息;
WARNING = CMake 警告, 会继续执行;
AUTHOR_WARNING = CMake 警告 (dev), 会继续执行;
SEND_ERROR = CMake 错误, 继续执行,但是会跳过生成的步骤;
FATAL_ERROR = CMake 错误, 终止所有处理过程;
CMake的命令行工具会在stdout上显示STATUS消息,在stderr上显示其他所有消息。CMake的GUI会在它的log区域显示所有消息。交互式的对话框(ccmake和CMakeSetup)将会在状态行上一次显示一条STATUS消息,而其他格式的消息会出现在交互式的弹出式对话框中。
CMake警告和错误消息的文本显示使用的是一种简单的标记语言。文本没有缩进,超过长度的行会回卷,段落之间以新行做为分隔符。
CMAKE可以输出cmake变量的取值,如message(status "binary dir" ${PROJECT_BINARY_DIR})
2 外部构建,cmake编译与源文件分离
创建如下所示文件目录结构:
图1
源文件路径下CMakeLists.txt内容:
1 CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 PROJECT(HELLOLIB CXX) 3 4 ADD_SUBDIRECTORY(src)
利用ADD_SUBDIRECTORY指定子目录下的CMakeLists.txt
src路径下CMakeLists.txt内容:
1 SET (SRC_PATH "${PROJECT_SOURCE_DIR}/src") 2 3 FILE(GLOB SRC_HEADER_LIST ${SRC_PATH}/*.h) 4 FILE(GLOB SRC_SOURCE_LIST ${SRC_PATH}/*.cpp) 5 SOURCE_GROUP("ABC HEAD" FILES ${SRC_HEADER_LIST} ) 6 SOURCE_GROUP("ABC SRC" FILES ${SRC_SOURCE_LIST}) 7 #SOURCE_GROUP("ABC HEAD" FILES ${SRC_HEADER_LIST} ${SRC_SOURCE_LIST}) 8 9 SET(SRC_LIST ${SRC_HEADER_LIST} ${SRC_SOURCE_LIST}) 10 11 MESSAGE(STATUS "all list " ${SRC_LIST}) 12 13 MESSAGE(STATUS "This is binary dir " ${HELLOLIB_BINARY_DIR}) 14 MESSAGE(STATUS "This is source dir " ${HELLOLIB_SOURCE_DIR}) 15 16 ADD_LIBRARY(HELLO SHARED ${SRC_LIST} )
在build下执行 命令“cmake ..”,将编译路径指定到build上层路径,在build下生产cache及项目文件。
3 IDE构建目录树
SET/FILE/SOURCE_GROUP指令相结合,生成IDE目录结构。如图1,如需将src下h和cpp文件各自构建一个目录,使用下面方法:
1 SET (SRC_PATH "${PROJECT_SOURCE_DIR}/src") 2 3 FILE(GLOB SRC_HEADER_LIST ${SRC_PATH}/*.h) 4 FILE(GLOB SRC_SOURCE_LIST ${SRC_PATH}/*.cpp) 5 SOURCE_GROUP("ABC HEAD" FILES ${SRC_HEADER_LIST} ) 6 SOURCE_GROUP("ABC SRC" FILES ${SRC_SOURCE_LIST}) 7 8 SET(SRC_LIST ${SRC_HEADER_LIST} ${SRC_SOURCE_LIST}) 9 10 ADD_LIBRARY(HELLO SHARED ${SRC_LIST} )
第一行:定义src路径 --> 变量SRC_PATH
第三行:定义src路径下所有h文件 --> 变量SRC_HEADER_LIST
第四行:定义src路径下所有cpp文件 --> 变量SRC_SOURCE_LIST
第五行:定义IDE目录树,src路径下所有h文件(变量SRC_HEADER_LIST) --> 目录名称"ABC HEAD"
第六行:定义IDE目录树,src路径下所有cpp文件(变量SRC_SOURCE_LIST) --> 目录名称"ABC SRC"
第8行:h文件和cpp文件赋值给变量SRC_LIST
第9行:利用h文件和cpp文件(SRC_LIST)创建工程
4 与VS工程设置相关的命令
: 对应工程设置 C/C++ --> 常规 --> 附件包含目录 include_directories
: 对应工程设置 链接器 -->常规 --> 附加库目录link_directories
target_link_libraries: 对应工程设置 链接器 --> 常规 --> 附加依赖项
5 定义预编译宏
add_definitions(-DFOO -DBAR ...),由-D加上宏名称组成,在cmake中定义,在源文件中使用。如
#ifdef F00
代码块生效
#endif
但是F00在源代码中无法被查找,无法显示#define F00之类的定义语句。
6 使用find_library替代link_directories
cmake官方文档推荐使用find_library代替使用link_directories,见 https://cmake.org/cmake/help/v3.2/command/find_library.html。
曾因使用link_directories造成附加库路径丢失,后查找到stackoverflow找到问题原因,见下图。
stackoverflow地址:https://stackoverflow.com/questions/31438916/cmake-cannot-find-library-using-link-directories
问题cmake编写如下:
1 FUNCTION(INSERT_COMMEON_PROPERTY pro_name) 2 SET(TEST 0) 3 IF(TEST) 4 5 #MESSAGE(STATUS " TEST : " ${TEST}) 6 LINK_DIRECTORIES( ${BOOST_LIB_DIR}) 7 TARGET_LINK_LIBRARIES(${pro_name} 8 libboost_thread-vc90-mt-gd-x32-1_67.lib 9 libboost_date_time-vc90-mt-gd-x32-1_67.lib 10 libboost_serialization-vc90-mt-gd-x32-1_67.lib 11 libboost_regex-vc90-mt-gd-x32-1_67.lib) 12 ELSE(TEST) 13 #cmake推荐使用FIND_LIBRARY替代LINK_DIRECTORIES,FIND_LIBRARY会生成绝对路径 14 FIND_LIBRARY(BOOST_THREAD_LIB libboost_thread-vc90-mt-gd-x32-1_67 ${BOOST_LIB_DIR}) 15 FIND_LIBRARY(BOOST_DATETIME_LIB libboost_date_time-vc90-mt-gd-x32-1_67 ${BOOST_LIB_DIR}) 16 FIND_LIBRARY(BOOST_SERIALIZATION_LIB libboost_serialization-vc90-mt-gd-x32-1_67 ${BOOST_LIB_DIR}) 17 FIND_LIBRARY(BOOST_REGEX_LIB libboost_regex-vc90-mt-gd-x32-1_67.lib ${BOOST_LIB_DIR}) 18 19 #MESSAGE(STATUS " FIND_LIBRARY : BOOST_THREAD_LIB : " ${BOOST_THREAD_LIB}) 20 21 TARGET_LINK_LIBRARIES(${pro_name} 22 ${BOOST_THREAD_LIB} 23 ${BOOST_DATETIME_LIB} 24 ${BOOST_SERIALIZATION_LIB} 25 ${BOOST_REGEX_LIB}) 26 ENDIF(TEST) 27 28 ENDFUNCTION(INSERT_COMMEON_PROPERTY)
7 error:NO CMAKE_cxx_COMPILER could be found.
错误行号:
PROJECT(BSTT cxx)
一直以为cmake不区分大小写,于是在PROJECT中用了cxx小写。cmake运行至此则必定报错。修改cxx为大写CXX后重新cmake成功。
同理,c代码小写也是错误的,都要改成大写。
测试cmake版本:cmake-3.11.3-win32-x86
8 others
生成debug版本 cmake -DCMAKE_BUILD_TYPE=Debug ..
生成Release版本 cmake -DCMAKE_BUILD_TYPE=Release ..