学习CMake的课程
CMake学习专栏
CMake Github学习
cmake 进阶
Visual Studio对安卓CMake 工程的支持
文章目录
前言
文件夹目录格式
目录
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模板
SDL地址
十、常用配置
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)
十一、cmake 添加告警报错规范
if(MSVC)
add_compile_options(/W4) # warning level
add_compile_options(/wd4819)
add_compile_options(/wd4003)
add_compile_options(/wd4002)
add_compile_options(/wd4996)
add_compile_options(/wd4456)
add_compile_options(/wd4457)
add_compile_options(/wd4458)
add_compile_options(/wd4459)
add_compile_options(/wd4477)
add_compile_options(/wd4311)
add_compile_options(/wd4302)
add_compile_options(/wd4840)
add_compile_options(/wd4244)
add_compile_options(/wd4510)
add_compile_options(/wd4610)
add_compile_options(/wd4512)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_compile_options(/wd4189)
add_compile_options(/wd4101)
endif()
常见问题
一直构建出错
cmake缓存清理一下,例如CMakeCache.txt文件和CMakeFiles文件夹等