it-swarm-es.com

¿Cómo agrego un enlazador o compilar un indicador en un archivo CMake?

Estoy usando el compilador arm-linux-androideabi-g++. Cuando intento compilar un simple "¡Hola mundo!" programa que compila bien. Cuando lo pruebo agregando un simple manejo de excepciones en ese código, también funciona (después de agregar -fexceptions .. Supongo que está deshabilitado por defecto).

Esto es para un dispositivo Android, y solo quiero usar CMake, no ndk-build.

Por ejemplo - first.cpp

#include <iostream>

using namespace std;

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

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

Funciona sin problema ...

El problema ... Estoy tratando de compilar el archivo con un archivo CMake.

Quiero agregar el -fexceptions como una bandera. Lo intenté con

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

y

set ( CMAKE_C_FLAGS "fexceptions")

Todavía muestra un error.

174
solti

Supongamos que desea agregar esas banderas (mejor declararlas en una constante):

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

Hay varias maneras de agregarlos:

  1. La más fácil (no es limpia, pero es fácil y conveniente, y funciona solo para compilar banderas, C y C++ a la vez):

    add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
    
  2. Anexando a las variables CMake correspondientes:

    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. Usando propiedades de destino, cf. doc CMake compilar propiedad de destino de marca y necesita saber el nombre de destino.

    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} )
    

Ahora mismo uso el método 2.

205
Offirmo

En las versiones más recientes de CMake, puede establecer indicadores de compilador y vinculador para un solo objetivo con target_compile_options y target_link_libraries respectivamente (sí, este último también configura opciones de vinculador):

target_compile_options(first-test PRIVATE -fexceptions)

La ventaja de este método es que puede controlar la propagación de opciones a otros objetivos que dependen de este a través de PUBLIC y PRIVATE.

A partir de CMake 3.13 también puede usar target_link_options para agregar opciones de vinculador, lo que hace que la intención sea más clara.

125
vitaut

Intente establecer la variable CMAKE_CXX_FLAGS en lugar de CMAKE_C_FLAGS:

set (CMAKE_CXX_FLAGS "-fexceptions")

La variable CMAKE_C_FLAGS solo afecta al compilador de C, pero está compilando el código de C++.

Agregar la bandera a CMAKE_EXE_LINKER_FLAGS es redundante.

35
sakra

También puede agregar indicadores de vinculador a un destino específico utilizando la propiedad LINK_FLAGS:

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

Si desea propagar este cambio a otros objetivos, puede crear un objetivo ficticio para vincularlo.

1
kaveish

Compruebe los ucm_add_flags y ucm_add_linker_flags macros de ucm (mi conjunto de macros CMake útiles) - se ocupan de añadir banderas de compilador/vinculador.

0
onqtam