前言
文件夹目录格式
目录 src add add.cpp add.h sum sum.cpp sum.h build example CMakeList.txt test.cpp CMakeList.txt
~/CMakeList.txt 是总配置 整个项目的Cmake配置 包括CMake版本。
~/example/CMakeList.txt 是子项目配置 一般就配置编译文件。
一、构建可执行程序
cmake_minimum_required(VERSION 3.0) project(day1) add_executable(day1 main.cpp add.cpp) # 查找当前目录下的所有源文件 # 并将名称保存到 DIR_SRCS 变量 #aux_source_directory(. DIR_SRCS) #add_executable(day1 ${DIR_SRCS})
二、多文件构建可执行程序
cmake_minimum_required(VERSION 3.0) project(day2) aux_source_directory(. DIR_SRCS) aux_source_directory(./src/add DIR_SRCS) aux_source_directory(./src/sum DIR_SRCS) #message("DIR_SRCS = ${DIR_SRCS}") # 打印 add_executable(day2 ${DIR_SRCS}) # 查找当前目录下的所有源文件 # 并将名称保存到 DIR_SRCS 变量 #aux_source_directory(. DIR_SRCS) # 生成可执行程序 #add_executable(day1 ${DIR_SRCS})
三、生成动态/静态库
cmake_minimum_required(VERSION 3.0) project(day3) aux_source_directory(. DIR_SRCS) aux_source_directory(./src/add DIR_SRCS) aux_source_directory(./src/sum DIR_SRCS) message("DIR_SRCS = ${DIR_SRCS}") #add_executable(day3 ${DIR_SRCS}) #生成libday3.so 动态库 add_library(day3 SHARED ${DIR_SRCS}) #生成libday3.a 静态库 #add_library(day3 STATIC ${DIR_SRCS})
四、测试使用动态/静态库
生成动态库SHARED,静态库STATIC
#add_library(day3 SHARED ${DIR_SRCS})
如何调用生成的动态/静态库 三个命令即可
include_directories(xxx) #添加include路径 link_directories(xxx) #给编译器添加库目录 target_link_libraries(target_name lib_name ...) #给目标添加依赖库
!!!Linux下使用readelf xxx -d 可以看程序的链接库
五、同时生成库和测试
几个新变量
CMAKE_PROJECT_NAME,PROJECT_BINARY_DIR,CMAKE_CURRENT_SOURCE_DIR
# 设置二进制可执行文件输出路径 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) # 设置库文件输出路径 set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
生成myProject_shared动态库文件
add_library(${CMAKE_PROJECT_NAME}_shared SHARED ${DIR_SRCS}) # 链接需要用到的库文件pthread #target_link_libraries(${CMAKE_PROJECT_NAME}_shared pthread) # 修改库文件名称为myProject,系统自动改为libmyProject set_target_properties(${CMAKE_PROJECT_NAME}_shared PROPERTIES OUTPUT_NAME "${CMAKE_PROJECT_NAME}")
生成myProject_static静态库文件
add_library(${CMAKE_PROJECT_NAME}_static STATIC ${DIR_SRCS}) # 链接需要用到的库文件pthread #target_link_libraries(${CMAKE_PROJECT_NAME}_static pthread) # 修改库文件名称为myProject,系统自动改为libmyProject set_target_properties(${CMAKE_PROJECT_NAME}_static PROPERTIES OUTPUT_NAME "${CMAKE_PROJECT_NAME}")
下面这个命令会调用example 文件夹下的CMakeLists.txt 文件
add_subdirectory(example)
example 下面的CMakeLists.txt aux_source_directory(. TEST_SRC_LIST) foreach(TEST_SRC ${TEST_SRC_LIST}) STRING(REGEX REPLACE "^\\./|\\.c[a-zA-Z0-9_]*$" "" TEST_EXE_NAME ${TEST_SRC}) # 字符串处理,去掉前面路径和后缀 message(STATUS "添加测试程序:${TEST_EXE_NAME}") add_executable(${TEST_EXE_NAME} ${TEST_SRC}) target_link_libraries(${TEST_EXE_NAME} ${CMAKE_PROJECT_NAME}_shared ) endforeach(TEST_SRC ${TEST_SRC_LIST})
六、生成win和linux的动态库
6.1 CMakeLists.txt 如何在区别平台
if(WIN32) ... elseif(APPLE) else() ... endif() if(ANDROID) else() endif()
注意win生成动态库需要加入
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
window 的动态库,会带一个.lib 文件,这个文件只是在编译时候需要,运行时候不需要
window 动态库xx.dll,xx.lib(一般会附带不是必须)
window 静态库 xx.lib
linux 动态库 libxx.so
linux 静态库 libxx.a
七、宏变量设置
如果想在写代码时候定义一个宏变量
应用场景,假设设计一套接口,但有两种算法实现,用到了两个不同的第三方库
#ifdef USE_Detect_A
…
#elif USE_Detect_B
…
#endif
CMakeList.txt
cmake_minimum_required(VERSION 3.0 ) project(day1) # 是否使用自己的 Math库 option (USE_Detect_A "Use provided math implementation" ON) option (USE_Detect_B "Use provided math implementation" OFF) # 用于测试替换用的变量 if(USE_Detect_A) message("USE_Detect_A #############") add_definitions(-DUSE_Detect_A) elseif(USE_Detect_B) message("USE_Detect_B #############") add_definitions(-DUSE_Detect_B) else() message("USE_Detect #############") add_definitions(-DUSE_Detect) endif() add_compile_options(-std=c++11) add_executable(day1 main.cpp )
#include <stdio.h> int main() { #ifdef USE_Detect printf(" USE_Detect i = %d add(%f %f) = %f ", i, a, b, c); #elif USE_Detect_A printf(" USE_Detect_A i = %d add(%f %f) = %f ", i, a, b, c); #elif USE_Detect_B printf(" USE_Detect_B i = %d add(%f %f) = %f ", i, a, b, c); #endif } }
编译命令 cmake .. -DUSE_Detect_B=ON
八、cmake 中的install
install 相当于将库和头文件 导出到某个路径
#安装目录 执行cmake生成的时候 指定安装目录 cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local/testInstall
set(INSTALL_PATH_LIB lib) set(INSTALL_PATH_INCLUDE include) install(DIRECTORY src/sum DESTINATION ${INSTALL_PATH_INCLUDE} FILES_MATCHING PATTERN "*.h") install(DIRECTORY src/add DESTINATION ${INSTALL_PATH_INCLUDE} FILES_MATCHING PATTERN "*.h") #lib库的安装 if(WIN32) install(TARGETS ${CMAKE_PROJECT_NAME}_shared RUNTIME DESTINATION ${INSTALL_PATH_LIB}) else() install(TARGETS ${CMAKE_PROJECT_NAME}_shared LIBRARY DESTINATION ${INSTALL_PATH_LIB}) endif() install(TARGETS ${CMAKE_PROJECT_NAME}_static ARCHIVE DESTINATION ${INSTALL_PATH_LIB})
也可以安装多个
INSTALL(TARGETS myrun mylib mystaticlib RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION libstatic )
九、模板
可参考我sdl_learn项目cmake模板
十、常用配置
10.1 移除某文件
list(REMOVE_ITEM WINDOWS_FILE “WXDumpFile.cpp” “WXDumpFile.h” “WXLog.h” “WXLog.cpp”)
10.2 添加筛选器
FILE(GLOB USBMUXD_SRC usbmuxd/.h usbmuxd/.cpp)
source_group(usbmuxd FILES ${USBMUXD_SRC})
10.3 搜索路径和库
10.3.1 find_path
搜索指定头文件路径
FIND_PATH(myCeres NAMES ceress.h PATHS /ceres/include/ceres NO_DEFAULT_PATH)
10.3.2 find_library
查找库所在目录
FIND_LIBRARY(RUNTIME_LIB mylib /usr/lib /usr/local/lib NO_DEFAULT_PATH)
10.3.3 find_package
使用find_package引入外部依赖包
10.4 设置cpp标准
set(CMAKE_CXX_STANDARD 11)