Cmake介绍与模板
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows [Visual C++](https://baike.baidu.com/item/Visual C%2B%2B/1811800) 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。
单一目录多个源文件
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo2)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 指定生成目标
add_executable(Demo ${DIR_SRCS})
多个目录多个源文件
根目录
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo3)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 添加 math 子目录
add_subdirectory(math)
# 指定生成目标
add_executable(Demo main.cc)
# 添加链接库
target_link_libraries(Demo MathFunctions)
子目录
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)
# 生成链接库
add_library (MathFunctions ${DIR_LIB_SRCS})
贼好用的 CMake 模板
前言
dll 及 dll 测试工程配置,工程结构:
BaseLibrary
src
xxx.cpp
xxx.h
CMakeLists.txt -----------------------2
config
BaseLibraryConfig.cmake.in
install
cmake
BaseLibraryConfig.cmake
include
xxx.h
lib
libBaseLibrary.so
test
xxx.cpp
CMakeLists.txt -----------------------3
CMakeLists.txt -------------------------------1
没有很复杂,但是也绝对够用了,CMakeLists.txt 文件编号如上
配置代码
1、CMakeLists.txt -----------1
cmake_minimum_required (VERSION 3.8)
set(This BaseLibrary)
project(${This} C CXX)
# 设置语言标准
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(ROOT_DIR ${CMAKE_SOURCE_DIR})
# 配置多线程选项
SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} "-pthread")
# Meta information about the project
set(META_PROJECT_NAME ${This})
set(META_PROJECT_DESCRIPTION "CMake project of my base library")
set(META_AUTHOR_ORGANIZATION "HULUWA")
set(META_AUTHOR_MAINTAINER "huluwa508@outlook.com")
set(META_VERSION_MAJOR "1")
set(META_VERSION_MINOR "0")
set(META_VERSION_PATCH "0")
set(META_VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}")
set(META_NAME_VERSION "${META_PROJECT_NAME} v${META_VERSION}")
# Create version file
file(WRITE "${PROJECT_BINARY_DIR}/VERSION" "${META_NAME_VERSION}")
# 分别设置Debug和Release输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Bin/Debug)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Bin/Release)
add_subdirectory(src)
add_subdirectory(test)
2、CMakeLists.txt -----------2
set(Target ${This})
message("")
message(STATUS "Start building : " ${Target})
# 设置包含路径
include_directories(${ROOT_DIR}/src/include)
# 添加当前文件夹下所有文件为源文件
aux_source_directory(./logger LOGGERT_SRCS)
aux_source_directory(./util UTIL_SRCS)
set(SRCS
${LOGGERT_SRCS}
${UTIL_SRCS}
)
# 生成动态库
add_library(${Target} SHARED ${SRCS})
target_link_libraries(${Target} stdc++fs)
# 定义导出宏
target_compile_definitions(${Target}
PRIVATE
LIBRARY_EXPORT)
# 安装生成的动态库
set(CMAKE_INSTALL_PREFIX ${ROOT_DIR}/install)
install(TARGETS ${Target}
EXPORT ${Target}Tagets
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
)
# 安装头文件
install(DIRECTORY ${ROOT_DIR}/src/include DESTINATION ${CMAKE_INSTALL_PREFIX})
# 将目标文件可导出文件
install(EXPORT ${Target}Tagets DESTINATION ${ROOT_DIR}/cmake)
# 生成 ${Target}Config.cmake
configure_file(${ROOT_DIR}/config/${Target}Config.cmake.in ${ROOT_DIR}/cmake/${Target}Config.cmake)
install(FILES ${ROOT_DIR}/cmake/${Target}Config.cmake DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake)
message(STATUS "Stop building : " ${Target} "\n")
注意
1)如果使用了C++标准库,记得链接stdc++fs
target_link_libraries(${Target} stdc++fs)
2)在Windows下需要导出符号
target_compile_definitions(${Target}
PRIVATE
LIBRARY_EXPORT)
等效于 #define LIBRARY_EXPORT
3)*find_package 功能*
BaseLibraryConfig.cmake.in 文件内填写如下内容
set(${This}_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/include)
set(${This}_LINK_DIRS ${CMAKE_INSTALL_PREFIX}/lib)
set(${This}_LIBRARIES ${This})
当执行
configure_file(${ROOT_DIR}/config/${Target}Config.cmake.in ${ROOT_DIR}/cmake/${Target}Config.cmake)
指令时,会在cmake文件夹下生成 BaseLibraryConfig.cmake,同时将替换
${This}_INCLUDE_DIRS 替换成 BaseLibrary_INCLUDE_DIRS
${This}_LINK_DIRS 替换成 BaseLibrary_LINK_DIRS
${This}_LIBRARIES 替换成 BaseLibrary_LIBRARIES
这样编译后在build目录下执行 make install 命令就会将该文件安装到安装目录,其它工程就可以直接从安装目录查找使用当前库,省去手动配置依赖的麻烦
find_package(${This} REQUIRED HINTS "${ROOT_DIR}/cmake")
include_directories(${${This}_INCLUDE_DIRS})
link_directories(${This}_LINK_DIRS)
target_link_libraries(${Target} ${${This}_LIBRARIES})
3、CMakeLists.txt -----------3
set(Target loggerTest)
project(Target C CXX)
# 设置语言标准
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
message("")
message(STATUS "Start building : " ${Target})
# 设置包含路径
include_directories(${ROOT_DIR}/src/include)
# find_package(${This} REQUIRED HINTS "${ROOT_DIR}/cmake")
# include_directories(${${This}_INCLUDE_DIRS})
# 设置依赖动态库、静态库路径
link_directories(
${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
)
# link_directories(${This}_LINK_DIRS)
aux_source_directory(. SRCS)
add_executable(${Target} ${SRCS})
target_link_libraries(${Target} -lpthread ${This})
# target_link_libraries(${Target} ${${This}_LIBRARIES})
message(STATUS "Stop building : " ${Target} "\n")
注意
1)就算使用了 C++11 的 thread,也要链接 -lpthread