文章介绍
- 本文章将介绍在Windows和Linux平台,生成可执行程序时,如何设置Debug和Release的一些属性。
- 主要介绍如何设置目标程序的生成路径,以及运行时库的设置和目标程序版本号的设置。
Debug和Release模式
- -O,-O1: 这两个命令的效果是一样的,目的都是在不影响编译速度的前提下,尽量采用一些优化算法降低代码大小和可执行代码的运行速度。
- -O2:该优化选项会牺牲部分编译速度,除了执行-O1所执行的所有优化之外,还会采用几乎所有的目标配置支持的优化算法,用以提高目标代码的运行速度。
- -O3: 该选项除了执行-O2所有的优化选项之外,一般都是采取很多向量化算法,提高代码的并行执行程度。
- -Os: -O3的目标是宁愿增加目标代码的大小,也要拼命的提高运行速度,但是这个选项是在-O2的基础之上,尽量的降低目标代码的大小,这对于存储容量很小的设备来说非常重要。
config对应的优化
- Debug: -g
- Release: -O3
- RelWithDebInfo: -O2 -g
- MinSizeRel: -Os
Linux配置
- 在CMake中设置
-
set(CMAKE_BUILD_TYPE Debug)
- 构建时配置
-
cmake .. -D CMAKE_BUILD_TYPE=Release
Windows配置
- Windows需要在编译时配置生成的类型,默认生成Debug
- 编译时配置命令。加-v可以看到调试信息。
-
cmake --build . --config Release -v
Debug和Release不同输出路径
- 执行程序和dll输出
-
RUNTIME_OUTPUT_DIRECTORY_<CONFIG>
- lib和a库输出
-
ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
- so动态库输出
-
LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
- pdb文件输出
-
PDB_OUTPUT_DIRECTORY_<CONFIG>
debug库名加后缀
-
set_target_properties(${target} PROPERTIES DEBUG_POSTFIX "d")
运行时库设置
- MSVC_RUNTIME_LIBRARY
- MultiThreaded(MT): 运行时库静态链接到目标文件。
- MultiThreadedDLL(MD): 运行时库动态链接到目标文件。
- MultiThreadedDebug(MTd): 运行时库静态链接到目标文件,加调试信息。
- MultiThreadedDebugDLL(MDd): 运行时库动态链接到目标文件,加调试信息。
- 默认运行时库是MD
动态库设置版本号
- NO_SONAME: NO-不产生动态库的符号链接,OFF - 产生动态库的符号链接
- VERSION: 整体版本号
- SOVERSION: 某个库的版本,对可执行程序无效。
示例
示例一:设置编译目标的路径
- 目录结构
-
├── build_linux├── build_win├── CMakeLists.txt├── include│ ├── dlib.h│ └── jlib.h└── src├── dlib.cpp├── jlib.cpp└── main.cpp
- CMakeLists.txt 文件内容
-
# 指定CMake最低版本cmake_minimum_required(VERSION 3.16)# 构建项目的名称project(cmake_demo)# 包含头文件include_directories(${PROJECT_SOURCE_DIR}/include)# 打印编译类型message("CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE})# 生成静态库add_library(jlib STATIC ${PROJECT_SOURCE_DIR}/src/jlib.cpp)set(OUT_LIB_PATH ${PROJECT_SOURCE_DIR}/lib)set(OUT_EXE_PATH ${PROJECT_SOURCE_DIR}/exe)# 设置静态库的输出set_target_properties(jlib PROPERTIES# 除了debug和release其他类型库的输出ARCHIVE_OUTPUT_DIRECTORY ${OUT_LIB_PATH}/other# debug库的输出ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${OUT_LIB_PATH}/debug# release库的输出ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${OUT_LIB_PATH}/release)# 生成动态库add_library(dlib SHARED ${PROJECT_SOURCE_DIR}/src/dlib.cpp)# 设置动态库的输出set_target_properties(dlib PROPERTIES# windows lib文件输出ARCHIVE_OUTPUT_DIRECTORY ${OUT_LIB_PATH}/otherARCHIVE_OUTPUT_DIRECTORY_DEBUG ${OUT_LIB_PATH}/debugARCHIVE_OUTPUT_DIRECTORY_RELEASE ${OUT_LIB_PATH}/release# windows dll文件输出RUNTIME_OUTPUT_DIRECTORY ${OUT_EXE_PATH}/other RUNTIME_OUTPUT_DIRECTORY_DEBUG ${OUT_EXE_PATH}/debugRUNTIME_OUTPUT_DIRECTORY_RELEASE ${OUT_EXE_PATH}/release# linux so 文件输出LIBRARY_OUTPUT_DIRECTORY ${OUT_LIB_PATH}/otherLIBRARY_OUTPUT_DIRECTORY_DEBUG ${OUT_LIB_PATH}/debugLIBRARY_OUTPUT_DIRECTORY_RELEASE ${OUT_LIB_PATH}/release# windows pdb文件PDB_OUTPUT_DIRECTORY ${OUT_LIB_PATH}/pdbPDB_OUTPUT_DIRECTORY_DEBUG ${OUT_LIB_PATH}/pdb# debug 版本加后缀DEBUG_POSTFIX "d")# 生成可执行程序add_executable(res ${PROJECT_SOURCE_DIR}/src/main.cpp)# 设置可执行程序的输出set_target_properties(res PROPERTIESRUNTIME_OUTPUT_DIRECTORY ${OUT_EXE_PATH}/other RUNTIME_OUTPUT_DIRECTORY_DEBUG ${OUT_EXE_PATH}/debugRUNTIME_OUTPUT_DIRECTORY_RELEASE ${OUT_EXE_PATH}/release# 设置工作目录# VS_DEBUGGER_WORKING_DIRECTORY ${OUT_EXE_PATH}# 根据不同编译类型,设置不同工作目录# $<IF:1,debug,release> 满足条件,返回debug# $<IF:0,debug,release> 不满足条件,返回releaseVS_DEBUGGER_WORKING_DIRECTORY $<IF:$<CONFIG:Debug>,debug,release># windows pdb文件PDB_OUTPUT_DIaRECTORY ${OUT_LIB_PATH}/pdbPDB_OUTPUT_DIRECTORY_DEBUG ${OUT_LIB_PATH}/pdb# debug 版本加后缀DEBUG_POSTFIX "d")
- 生成Release版本
-
# Windows 平台在 build_win 下执行cmake ..cmake --build . --config Release# Linux 平台在 build_linux 下执行cmake .. -D CMAKE_BUILD_TYPE=Releasemake
- 生成Debug版本
-
# Windows 平台在 build_win 下执行cmake ..cmake --build . --config Debug# Linux 平台在 build_linux 下执行cmake .. -D CMAKE_BUILD_TYPE=Debugmake
- 看下最终生成的库目录结构
-
├── exe│ ├── debug│ │ ├── dlibd.dll│ │ ├── resd│ │ ├── resd.exe│ └── release│ ├── dlib.dll│ ├── res│ └── res.exe├── lib├── debug│ ├── dlibd.lib│ ├── jlib.lib│ ├── jlib.pdb│ ├── libdlibd.so│ └── libjlib.a├── pdb│ ├── dlibd.pdb│ ├── Release│ └── resd.pdb└── release├── dlib.lib├── jlib.lib├── libdlib.so└── libjlib.a
示例一:运行时库设置
- 这里以Release为例。运行时库默认是动态链接,即 MD
- cmake中可以设置为静态链接,即 MT
-
# 指定CMake最低版本cmake_minimum_required(VERSION 3.16)# 构建项目的名称project(cmake_demo)# 包含头文件include_directories(${PROJECT_SOURCE_DIR}/include)# 生成可执行程序add_executable(res ${PROJECT_SOURCE_DIR}/src/main.cpp)# 设置运行时库静态链接MT - 只设置Releaseset_target_properties(res PROPERTIESMSVC_RUNTIME_LIBRARY "MultiThreaded")# 根据编译类型设置# set_target_properties(res PROPERTIES# MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"# )
- 编译命令
-
cmake ..cmake --build . --config Release -v
- 先不设置,看下效果
- 输出信息是 MD
- 生成的可执行程序要依赖运行时库,且可执行比较小,为9kb
- 设置为MT,再看下效果
- 输出信息是MT
- 没有依赖运行时库,且大小变为 95kb
示例三:动态库设置版本号
- cmake文件内容
-
# 指定CMake最低版本cmake_minimum_required(VERSION 3.16)# 构建项目的名称project(cmake_demo)# 包含头文件include_directories(${PROJECT_SOURCE_DIR}/include)# 生成动态库add_library(dlib SHARED ${PROJECT_SOURCE_DIR}/src/dlib.cpp)# 设置目标程序版本号set_target_properties(dlib PROPERTIESVERSION "1.0.0"SOVERSION "6"NO_SONAME OFF)
- 编译结果