Як додати посилання або компілювати прапор у файл CMake?


220

Я використовую 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")

Він все ще відображає помилку.


зараз у мене однакова проблема, і я намагаюся різні речі. Повісьте трохи, і я опублікую відповідь. Для компіляції прапорів існує нечистий, але простий спосіб: add_definitions ("- truc")
Offirmo

Для більш актуального обговорення цього питання (особливо якщо ви використовуєте CMake 3.x або новіший): Який сучасний метод встановлення загальних прапорів компіляції в CMake? .
ComicSansMS

Якщо прапори посилань, які ви хочете націлити на налаштування rpath , ознайомтеся з конкретними командами CMake rpath gitlab.kitware.com/cmake/community/wikis/doc/cmake/…
Габріель

Відповіді:


243

Припустимо, ви хочете додати ці прапори (краще оголосити їх у постійній):

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.


4
Чому add_definitions () є нечистим?
leinaD_natipaC

14
@leinaD_natipaC: В офіційній документації сказано: Ця команда може використовуватися для додавання будь-яких прапорів, але вона призначена для додавання визначень препроцесора . Я думаю, що саме тому.
Бенуа Бланшон

Хоча це прийнята відповідь, це справді показує дуже старий стиль CMAKE, зверніться до відповіді @vitaut про те, як будь-який новий код CMAKE повинен бути структурований з урахуванням компіляції часових параметрів
Харальд Шеріх,

1
string(APPEND CMAKE_EXE_LINKER_FLAGS "new_value")коротше і чистіше, ніжset(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} new_value")
кривавий

165

У новіших версіях CMake ви можете встановити прапорці компілятора та лінкера для однієї цілі відповідно target_compile_optionsі target_link_librariesвідповідно (так, остання також встановлює параметри сполучника):

target_compile_options(first-test PRIVATE -fexceptions)

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

Як і в CMake 3.13, ви також target_link_optionsможете додати параметри лінкера, що робить ціль більш зрозумілою.


2
Я намагався його використовувати: target_compile_options(main_static PRIVATE --static)але це, здається, не працює, будь-яка ідея чому?
Paweł Szczur

2
-staticце, мабуть, параметр для зв’язку, а не компілятора. Спробуйте передати його target_link_libraries.
vitaut

9
О, target_link_librariesя пропустив ту частину документа: "Вкажіть бібліотеки або прапори, які слід використовувати при посиланні заданої цілі." Дякую.
Paweł Szczur

3
Недавнє доповнення: CMake 3.13 представляє target_link_optionsбільш чіткий спосіб вказувати прапорці. Слід уникати використання target_link_librariesпрапорів-посилателів у майбутньому та використання target_link_optionsнатомість.
ComicSansMS

1
Існує також add_compile_options - см stackoverflow.com/questions/39501481 / ... і зовсім недавно add_link_options
Брюс Адамс

46

Спробуйте встановити змінну CMAKE_CXX_FLAGSзамість CMAKE_C_FLAGS:

set (CMAKE_CXX_FLAGS "-fexceptions")

Змінна CMAKE_C_FLAGSвпливає лише на компілятор C, але ви збираєте код C ++.

Додавання прапора до CMAKE_EXE_LINKER_FLAGSзайвого.


Я спробував це, але це все ще дає помилку. Встановлено (CMAKE_CXX_FLAGS "-fexceptions") єдиний спосіб вказати прапор компілятора.
solti

3
Я вирішив проблему, але не дуже добре її поганий спосіб вирішення .. Я зробив -DCMAKE_CXX_FLAGS = "-fexceptions" в командному рядку. чомусь cmake не читає прапори з файлу .cmake. :( .. дякую сакра за вашу відповідь ..
solti

8
-DCMAKE_CXX_FLAGS = "-fexceptions" НЕ повинно бути пробілу між = і "
evandrix

Щодо того, що ви сказали: "чомусь cmake не читає прапори з файлу .cmake." Обов’язково очистіть наявний кеш. Це можна зробити, видаливши все з каталогу зборки перед тим, як знову cmake.
zaizen

1

Ви також можете додати прапорці посилання на певну ціль, використовуючи LINK_FLAGSвластивість:

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

Якщо ви хочете поширити цю зміну на інші цілі, ви можете створити фіктивну ціль, на яку слід посилатися.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.