如何在 CMake 文件中添加链接器或编译标志?

新手上路,请多包涵

我正在使用 arm-linux-androideabi-g++ 编译器。当我尝试编译一个简单的“Hello, World!”程序编译得很好。当我通过在该代码中添加一个简单的异常处理来测试它时,它也可以工作(在添加 -fexceptions .. 我猜它默认是禁用的)。

这是针对 Android 设备的,我只想使用 CMake,而不是 ndk-build

例如 - first.cpp

 #include <iostream>

using namespace std;

int main()
{
   try
   {
   }
   catch (...)
   {
   }
   return 0;
}

./arm-linux-androideadi-g++ -o first-test first.cpp -fexceptions

它工作没有问题…

问题…我正在尝试使用 CMake 文件编译该文件。

我想添加 -fexceptions 作为标志。我试过了

set (CMAKE_EXE_LINKER_FLAGS -fexceptions ) or set (CMAKE_EXE_LINKER_FLAGS "fexceptions" )

set ( CMAKE_C_FLAGS "fexceptions")

它仍然显示错误。

原文由 solti 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 807
2 个回答

注意:鉴于 CMake 的演变,因为这是 2012 年编写的答案,这里的大多数建议现在已经过时/不推荐使用,并且有更好的选择。


假设您要添加这些标志(最好在常量中声明它们):

 SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
SET(GCC_COVERAGE_LINK_FLAGS    "-lgcov")

有几种方法可以添加它们:

  1. 最简单的一个(不干净,但简单方便,仅适用于编译标志、C 和 C++):
     add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})

  1. 附加到相应的 CMake 变量:
     SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
    SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")

  1. 使用目标属性,参见。 doc CMake 编译标志目标属性,需要知道目标名称。
     get_target_property(TEMP ${THE_TARGET} COMPILE_FLAGS)
    if(TEMP STREQUAL "TEMP-NOTFOUND")
      SET(TEMP "") # Set to empty string
    else()
      SET(TEMP "${TEMP} ") # A space to cleanly separate from existing content
    endif()
    # Append our values
    SET(TEMP "${TEMP}${GCC_COVERAGE_COMPILE_FLAGS}" )
    set_target_properties(${THE_TARGET} PROPERTIES COMPILE_FLAGS ${TEMP} )

现在我使用方法2。

原文由 Offirmo 发布,翻译遵循 CC BY-SA 4.0 许可协议

指定工具链特定选项的首选方法是使用 CMake 的 工具链工具。这确保了以下之间的清晰划分:

  • 关于如何将源文件组织成目标的说明——以 CMakeLists.txt 文件表示,完全与工具链无关;和
  • 应如何配置某些工具链的详细信息 - 分为 CMake 脚本文件,可由项目的未来用户扩展,可扩展。

理想情况下,您的 CMakeLists.txt 文件中不应有编译器/链接器标志——即使在 if / endif 块中也是如此。并且您的程序应该使用默认工具链(例如 GNU/Linux 上的 GCC 或 Windows 上的 MSVC)为本地平台构建,而不需要任何额外的标志。

添加工具链的步骤:

  1. 使用全局工具链设置创建一个文件,例如 arm-linux-androideadi-gcc.cmake
    set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
   set(CMAKE_CXX_FLAGS_INIT "-fexceptions")

(您可以 [在此处](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux) 找到示例 Linux 交叉编译工具链文件。)
  1. 当您想使用此工具链生成构建系统时,请在命令行中指定 CMAKE_TOOLCHAIN_FILE 参数:
    mkdir android-arm-build && cd android-arm-build
   cmake -DCMAKE_TOOLCHAIN_FILE=$(pwd)/../arm-linux-androideadi-gcc.cmake ..

(注意:您不能使用相对路径。)
  1. 正常构建:
    cmake --build .

工具链文件使交叉编译更容易,但它们还有其他用途:

  • 为您的单元测试提供强化诊断。
   set(CMAKE_CXX_FLAGS_INIT "-Werror -Wall -Wextra -Wpedantic")

  • 难以配置的开发工具。
   # toolchain file for use with gcov
  set(CMAKE_CXX_FLAGS_INIT "--coverage -fno-exceptions -g")

  • 加强安全检查。
   # toolchain file for use with gdb
  set(CMAKE_CXX_FLAGS_DEBUG_INIT "-fsanitize=address,undefined -fsanitize-undefined-trap-on-error")
  set(CMAKE_EXE_LINKER_FLAGS_INIT "-fsanitize=address,undefined -static-libasan")

原文由 John McFarlane 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题