CMake工程实践(二)

  本文记录使用 CMake 构建 C++ 项目时的一些常用设置, 以供后面查阅。

一、 编译特性设置(Debug / Release)

 不同编译特性设置对应的优化参数如下:

Debug       	-> -g
Release     	-> -O3 -DNDEBUG
RelWithDebInfo	-> -O2 -g -DNDEBUG
MinSizeRel 		-> -Os -DNDEBUG

非Debug模式下都会传递一个 NDEBUG 的宏, 假如有需要可以在代码中把这个宏利用起来。Linux 和 Mac平台在构建项目的直接指定, 因为这两个平台只会构建一个编译版本,如下指定参数:

cmake -S . -B build -D CMAKE_BUILD_TYPE=Release 

//或者直接在 CMakeLists.txt 中指定
if(NOT CMAKE_BUILD_TYPE) 
   set(CMAKE_BUILD_TYPE Release ) 
endif()

但是windows构建的时候会直接构建出四个版本,所以需要在编译的时候指定需要编译的版本:

cmake --build ./build --config Release

二、 配置输出路径

2.1 静态库

 静态库的输出路径指定,windows 平台默认情况下会给每种编译模式都创建一个同名的文件夹,有时候需要在 CMakeLists.txt 中指定, 最好是将编译版本信息一起带上,这样就可以直接在目标文件夹内查询到编译结果,不然 windows 下还会多生成一层编译版本的目录:

set(LIB_PATH ${CMAKE_SOURCE_DIR}/lib)

set_target_properties(project PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${LIB_PATH}
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIB_PATH }/debug
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIB_PATH }/release
)

除了 debug 和 release 都默认输出到 LIB_PATH 路径下。

2.2 动态库

 动态库的输出目录和可执行程序的输出目录配置方法相同。

set(DLL_PATH ${CMAKE_SOURCE_DIR}/lib)
set_target_properties(project PROPERTIES
# windows 平台下动态库的符号文件 .lib 的输出目录 
ARCHIVE_OUTPUT_DIRECTORY ${LIB_PATH }
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIB_PATH }/debug
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIB_PATH }/release

# windos .dll 或者 .exe 文件输出路径
RUNTIME_OUTPUT_DIRECTORY ${DLL_PATH }
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${DLL_PATH }/debug
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PE_PATH }/release

#linux .so 和mac
LIBRARY_OUTPUT_DIRECTORY ${LIB_PATH }
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${LIB_PATH }/debug
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${LIB_PATH }/release

#windows .pdb符号调试文件目录
PDB_OUTPUT_DIRECTORY ${LIB_PATH }/pdb
PDB_OUTPUT_DIRECTORY_DEBUG ${LIB_PATH }/pdb
)

  给 debug 版本的生成个文件添加一个后缀名:

if(MSVC)
set_target_properties(project PROPERTIES
DEBUG_POSTFIX "d"
)
endif()

三、 VS调试目录

 设置 VS 的调试目录,主要是用 VS IDE调试时经常会使用一些资源文件,通过这种方式来指定调试路径,避免资源文件加载失败的情况。根据编译版本来区分 debug 和 release。

VS_DEBUGGER_WORKING_DIRECTORY $<IF:$<CONFIG:Debug>,${DLL_PATH }/debug,${DLL_PATH }/release>

四、 windows 平台设置运行时库

set_target_properties(project PROPERTIES
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
)

MultiThreaded
	Compile with -MT or equivalent flag(s) to use a multi-threaded statically-linked runtime library.
MultiThreadedDLL
	Compile with -MD or equivalent flag(s) to use a multi-threaded dynamically-linked runtime library.
MultiThreadedDebug
	Compile with -MTd or equivalent flag(s) to use a multi-threaded statically-linked runtime library.
MultiThreadedDebugDLL
	Compile with -MDd or equivalent flag(s) to use a multi-threaded dynamically-linked runtime library.

五、 设置 Visual Studio 的文件分类

 Visual Studio 不像 VSCode 那样可以通过文件目录来分组源码,当源码文件个数太多的时候不分组的话就不方便预览调试了。假设有类实现在 a.cpp 中,声明在 a.h 。那么分组可以设置为:

source_group(src FILES a.cpp b.cpp)
source_group(include FILES a.h b.h)

假如要在 include 分组中再内嵌一个分组可以设置为:

source_group(TREE . PREFIX include/inc FILES b.h)

六、 install 安装指定目录

  编译完成后需要对编译结果进行一个统一的部署,比如一个动态库工程需要将头文件(.h),符号文件(.lib) , 动态库(.dll)三者进行安装部署,避免手动挨个进行文件拷贝。 CMakeLists.txt 中代码实例如下:

install(TARGETS ${PROJECT_NAME}

RUNTIME DESTINATION ${CMAKE_SOURCE_DIR}/install  # 执行程序和dll文件输出
ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/install	 # 静态库和windows动态库导出符号 .lib
LIBRARY DESTINATION ${CMAKE_SOURCE_DIR}/install  # linux和mac的动态库 .so .dylib

PUBLIC_HEADER DESTINATION ${CMAKE_SOURCE_DIR}/install    #公开头文件,比如接口类文件
PRIVATE_HEADER DESTINATION ${CMAKE_SOURCE_DIR}/install   #内部头文件
)

  windows平台下假如需要进行调试的话,也需要把 PDB 文件一起部署给库的使用者:

install(FILES $<TARGET_PDB_FILE:${PROJECT_NAME}> DESTINATION ${CMAKE_SOURCE_DIR}/install OPTIONAL)

 安装时可以通过 cmake 命令进行安装,也可以直接在 CMakeLists.txt 中直接配置。

cmake --install ./build --config Release   #部署 Release
cmake --install ./build --config Debug	   #部署 Debug

 导出多个头文件示例:

set(LIST_PUBLIC_HEADER
${CMAKE_SOURCE_DIR}/src/readerbase.h
${CMAKE_SOURCE_DIR}/src/factory.h 
)
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER  "${LIST_PUBLIC_HEADER}")
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值