Подтвердить что ты не робот

Как добавить компоновщик или флаг компиляции в файл CMake?

Я использую компилятор arm-linux-androideabi-g++. Когда я пытаюсь скомпилировать простое "Привет, мир!" Программа компилируется нормально. Когда я тестирую его, добавляя простую обработку исключений в этот код, он тоже работает (после добавления -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")

По-прежнему отображается ошибка.

4b9b3361

Ответ 1

Предположим, вы хотите добавить эти флаги (лучше объявить их в константе):

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

Есть несколько способов добавить их:

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

Прямо сейчас я использую метод 2.

Ответ 2

В более новых версиях CMake вы можете установить флаги компилятора и компоновщика для одной цели с помощью target_compile_options и target_link_libraries соответственно (да, последний также устанавливает параметры компоновщика):

target_compile_options(first-test PRIVATE -fexceptions)

Преимущество этого метода заключается в том, что вы можете контролировать распространение опций на другие цели, которые зависят от этого, с помощью PUBLIC и PRIVATE.

Начиная с CMake 3.13, вы также можете использовать target_link_options для добавления опций компоновщика, что делает намерение более ясным.

Ответ 3

Попробуйте установить переменную CMAKE_CXX_FLAGS вместо CMAKE_C_FLAGS:

set (CMAKE_CXX_FLAGS "-fexceptions")

Переменная CMAKE_C_FLAGS влияет только на компилятор C, но вы компилируете код на С++.

Добавление флага в CMAKE_EXE_LINKER_FLAGS является избыточным.

Ответ 4

Вы также можете добавить флаги компоновщика к определенной цели, используя свойство LINK_FLAGS:

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

Если вы хотите распространить это изменение на другие цели, вы можете создать фиктивную цель для ссылки.

Ответ 5

Изучите макросы ucm_add_flags и ucm_add_linker_flags для ucm (мой набор полезных макросов CMake) - они имеют дело с добавлением флагов компилятора/компоновщика.