王锐
发布于 2024-09-18 / 44 阅读
0
0

cmake基本使用手册

  • 配置生成compile_commands.json文件

这里不介绍这个文件是干什么的,配置生成方式-DCMAKE_EXPORT_COMPILE_COMMANDS=ON如下

cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..

临时将某路径添加到查找路径中

cmake -DCMAKE_CXX_FLAGS="-I/path/to/your/include" ..
  • 版本类型配置

cmake -DCMAKE_BUILD_TYPE=Release ..
cmake -DCMAKE_BUILD_TYPE=Debug ..

编译优化篇

对源码进行编译时,如果出现内存不足问题导致编译失败,一般有以下几种方案解决这个问题

  1. 增加机器的内存/设置更大的虚拟内存

  2. 编译选项对编译时的程序进行控制

一般推荐第二种方案,cmake配置以下方式进行编译

cmake -DCMAKE_CXX_FLAGS="-O2" -DCMAKE_C_FLAGS="-O2" ..

常见的优化级别

  1. -O0:禁用所有优化,适用于调试。

  2. -O1:较低级别的优化。

  3. -O2:常用的优化级别,适用于大部分场景。

  4. -O3:更激进的优化,可能增加编译时间和内存占用。

  5. -Os:优化以减小生成的代码大小。

  6. -Wall:启用编译警告,用于帮助开发者发现潜在的代码问题。

版本发布阶段对程序大小优化

在 CMake 中,您可以通过多种方式来减少生成的可执行文件的大小。以下是一些常见的方法和配置选项,可以帮助您生成尽可能小的可执行文件。

  1. 确保编译链接的库都为动态库

  2. 使用-Os编译选项(通常发布版本使用-O2编译选项)

  3. 针对CPU架构,使用-march=native选项

  4. 通过编译和链接时移除未使用的代码和符号,您可以显著减少可执行文件的大小。

  5. 禁用 RTTI 和异常处理

  6. 使用 strip 移除符号表

  7. 启用链接时优化(LTO)

  8. 使用 -fmerge-all-constants告诉编译器将所有相同的常量合并,进一步减少可执行文件的大小。

  9. MinSizeRel 构建类型

完整的示例如下:

if(CMAKE_BUILD_TYPE STREQUAL "Release")
    # 1. 使用 -O2 优化选项
    set(CMAKE_CXX_FLAGS "-O2")
    set(CMAKE_C_FLAGS "-O2")

    # 使用 -march=native 选项
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native")

    # 去除未使用的代码和符号
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")

    # 禁用RTTI和异常处理
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")

    # 启用链接时优化(LTO)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto")
    
    # 使用 -fmerge-all-constants,进行常量合并
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmerge-all-constants")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmerge-all-constants")
endif()

上述例子针对CMAKE_BUILD_TYPE为Release版本进行优化,或者使用CMAKE_BUILD_TYPE=MinSizeRel让编译器自动对编译生成的可执行程序进行优化以使得生成目标文件最小,执行成功后,还需要使用strip命令进行裁剪更进一步降低可执行文件的大小。


评论