web-dev-qa-db-fra.com

Comment ajouter un éditeur de liens ou un indicateur de compilation dans un fichier CMake?

J'utilise le compilateur arm-linux-androideabi-g++. Quand j'essaye de compiler un simple "Hello, World!" programme il compile bien. Lorsque je le teste en ajoutant une simple gestion des exceptions dans ce code, cela fonctionne également (après avoir ajouté -fexceptions .. Je suppose qu'il est désactivé par défaut).

Ceci est pour un périphérique Android, et je veux seulement utiliser CMake, pas ndk-build.

Par exemple - first.cpp

#include <iostream>

using namespace std;

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

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

Cela fonctionne sans problème ...

Le problème ... J'essaie de compiler le fichier avec un fichier CMake.

Je veux ajouter le -fexceptions comme drapeau. J'ai essayé avec

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

et

set ( CMAKE_C_FLAGS "fexceptions")

Il affiche toujours une erreur.

181
solti

Supposons que vous souhaitiez ajouter ces drapeaux (il est préférable de les déclarer dans une constante):

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

Il y a plusieurs façons de les ajouter:

  1. Le plus simple (pas propre, mais facile et pratique, et ne fonctionne que pour les drapeaux de compilation, C & C++ à la fois):

    add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
    
  2. Ajout aux variables CMake correspondantes:

    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. En utilisant les propriétés de la cible, cf. doc CMake compile flag target property et doit connaître le nom de la cible.

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

En ce moment, j'utilise la méthode 2.

217
Offirmo

Dans les versions plus récentes de CMake, vous pouvez définir les drapeaux du compilateur et de l'éditeur de liens pour une cible unique avec target_compile_options et target_link_libraries (oui, ce dernier définit l'éditeur de liens options aussi):

_target_compile_options(first-test PRIVATE -fexceptions)
_

L'avantage de cette méthode est que vous pouvez contrôler la propagation des options vers d'autres cibles qui dépendent de celle-ci via PUBLIC et PRIVATE.

À partir de CMake 3.13, vous pouvez également utiliser target_link_options pour ajouter des options d’éditeur de liens, ce qui rend l’intention plus claire.

137
vitaut

Essayez de définir la variable CMAKE_CXX_FLAGS au lieu de CMAKE_C_FLAGS:

set (CMAKE_CXX_FLAGS "-fexceptions")

La variable CMAKE_C_FLAGS n'affecte que le compilateur C, mais vous compilez du code C++.

L'ajout de l'indicateur à CMAKE_EXE_LINKER_FLAGS est redondant.

37
sakra

Vous pouvez également ajouter des indicateurs de l'éditeur de liens à une cible spécifique à l'aide de la propriété LINK_FLAGS:

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

Si vous souhaitez propager cette modification vers d'autres cibles, vous pouvez créer une cible factice à associer.

1
kaveish

Vérifiez les cm_add_flags et cm_add_linker_flags les macros de cm (mon ensemble de macros utiles de CMake) - ils traitent de l'ajout de drapeaux de compilation/éditeur de liens.

0
onqtam