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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11783932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:32:22  来源:igfitidea点击:

How do I add a linker or compile flag in a CMake file?

c++cmake

提问by solti

I am using the arm-linux-androideabi-g++compiler. When I try to compile a simple "Hello, World!" program it compiles fine. When I test it by adding a simple exception handling in that code it works too (after adding -fexceptions.. I guess it is disabled by default).

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

This is for an Android device, and I only want to use CMake, not ndk-build.

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

For example - first.cpp

例如 - first.cpp

#include <iostream>

using namespace std;

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

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

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

It works with no problem...

它工作没有问题......

The problem... I am trying to compile the file with a CMake file.

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

I want to add the -fexceptionsas a flag. I tried with

我想将其添加-fexceptions为标志。我试过

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

and

set ( CMAKE_C_FLAGS "fexceptions")

It still displays an error.

它仍然显示错误。

回答by Offirmo

Suppose you want to add those flags (better to declare them in a constant):

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

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

There are several ways to add them:

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

  1. The easiest one (not clean, but easy and convenient, and works only for compile flags, C & C++ at once):

    add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
    
  2. Appending to corresponding CMake variables:

    SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
    SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
    
  3. Using target properties, cf. doc CMake compile flag target propertyand need to know the target name.

    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} )
    
  1. 最简单的一个(不干净,但简单方便,并且只对编译标志、C 和 C++ 一次有效):

    add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
    
  2. 附加到相应的 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}")
    
  3. 使用目标属性,参见。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} )
    

Right now I use method 2.

现在我使用方法2。

回答by vitaut

In newer versions of CMake you can set compiler and linker flags for a single target with target_compile_optionsand target_link_librariesrespectively (yes, the latter sets linker options too):

在较新版本的 CMake 中,您可以分别使用target_compile_optionstarget_link_libraries为单个目标设置编译器和链接器标志(是的,后者也设置链接器选项):

target_compile_options(first-test PRIVATE -fexceptions)

The advantage of this method is that you can control propagation of options to other targets that depend on this one via PUBLICand PRIVATE.

这种方法的优点是您可以通过PUBLIC和控制选项传播到依赖于该目标的其他目标PRIVATE

As of CMake 3.13 you can also use target_link_optionsto add linker options which makes the intent more clear.

从 CMake 3.13 开始,您还可以使用target_link_options添加链接器选项,使意图更加清晰。

回答by sakra

Try setting the variable CMAKE_CXX_FLAGSinstead of CMAKE_C_FLAGS:

尝试设置变量CMAKE_CXX_FLAGS而不是CMAKE_C_FLAGS

set (CMAKE_CXX_FLAGS "-fexceptions")

The variable CMAKE_C_FLAGSonly affects the C compiler, but you are compiling C++ code.

该变量CMAKE_C_FLAGS仅影响 C 编译器,但您正在编译 C++ 代码。

Adding the flag to CMAKE_EXE_LINKER_FLAGSis redundant.

将标志添加到CMAKE_EXE_LINKER_FLAGS是多余的。

回答by kaveish

You can also add linker flags to a specific target using the LINK_FLAGSproperty:

您还可以使用以下LINK_FLAGS属性将链接器标志添加到特定目标:

set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${flag}")

If you want to propagate this change to other targets, you can create a dummy target to link to.

如果您想将此更改传播到其他目标,您可以创建一个要链接到的虚拟目标。

回答by onqtam

Checkout the ucm_add_flagsand ucm_add_linker_flagsmacros of ucm(my set of useful CMake macros) - they deal with appending compiler/linker flags.

查看ucmucm_add_flagsucm_add_linker_flags宏(我的一组有用的 CMake 宏)——它们处理附加编译器/链接器标志。