文章介绍
- 本文章将介绍在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}/other ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${OUT_LIB_PATH}/debug ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${OUT_LIB_PATH}/release # windows dll文件输出 RUNTIME_OUTPUT_DIRECTORY ${OUT_EXE_PATH}/other RUNTIME_OUTPUT_DIRECTORY_DEBUG ${OUT_EXE_PATH}/debug RUNTIME_OUTPUT_DIRECTORY_RELEASE ${OUT_EXE_PATH}/release # linux so 文件输出 LIBRARY_OUTPUT_DIRECTORY ${OUT_LIB_PATH}/other LIBRARY_OUTPUT_DIRECTORY_DEBUG ${OUT_LIB_PATH}/debug LIBRARY_OUTPUT_DIRECTORY_RELEASE ${OUT_LIB_PATH}/release # windows pdb文件 PDB_OUTPUT_DIRECTORY ${OUT_LIB_PATH}/pdb PDB_OUTPUT_DIRECTORY_DEBUG ${OUT_LIB_PATH}/pdb # debug 版本加后缀 DEBUG_POSTFIX "d" ) # 生成可执行程序 add_executable(res ${PROJECT_SOURCE_DIR}/src/main.cpp) # 设置可执行程序的输出 set_target_properties(res PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OUT_EXE_PATH}/other RUNTIME_OUTPUT_DIRECTORY_DEBUG ${OUT_EXE_PATH}/debug RUNTIME_OUTPUT_DIRECTORY_RELEASE ${OUT_EXE_PATH}/release # 设置工作目录 # VS_DEBUGGER_WORKING_DIRECTORY ${OUT_EXE_PATH} # 根据不同编译类型,设置不同工作目录 # $<IF:1,debug,release> 满足条件,返回debug # $<IF:0,debug,release> 不满足条件,返回release VS_DEBUGGER_WORKING_DIRECTORY $<IF:$<CONFIG:Debug>,debug,release> # windows pdb文件 PDB_OUTPUT_DIRECTORY ${OUT_LIB_PATH}/pdb PDB_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=Release make
- 生成Debug版本
-
# Windows 平台在 build_win 下执行 cmake .. cmake --build . --config Debug # Linux 平台在 build_linux 下执行 cmake .. -D CMAKE_BUILD_TYPE=Debug make
- 看下最终生成的库目录结构
-
├── 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 - 只设置Release set_target_properties(res PROPERTIES MSVC_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 PROPERTIES VERSION "1.0.0" SOVERSION "6" NO_SONAME OFF )
- 编译结果