Який сучасний метод встановлення загальних прапорців компіляції в CMake?


84

CMake пропонує безліч механізмів отримання прапорців компілятору:

Чи є один метод, який є кращим перед іншим у сучасному використанні? Якщо так, то чому? Крім того, як цей метод можна використовувати з кількома системами конфігурації, такими як MSVC?


Відповіді:


94

Для сучасного CMake (версії 2.8.12 і новіших) ви повинні використовувати target_compile_options, який використовує цільові властивості внутрішньо.

CMAKE_<LANG>_FLAGSє глобальною змінною і найбільш схильною до використання. Він також не підтримує генераторські вирази , які можуть стати в нагоді.

add_compile_options базується на властивостях каталогу, що в деяких ситуаціях добре, але, як правило, не найприродніший спосіб вказати параметри.

target_compile_optionsпрацює на основі цілі (шляхом встановлення властивостей COMPILE_OPTIONSі INTERFACE_COMPILE_OPTIONStarget), що зазвичай призводить до найчистішого коду CMake, оскільки параметри компіляції вихідного файлу визначаються тим, до якого проекту належить файл (а не до якого каталогу він розміщений) на жорсткому диску). Це має додаткову перевагу в тому, що він автоматично піклується про передачу параметрів залежним цілям, якщо це вимагається.

Незважаючи на те, що вони трохи більш багатослівні, команди per-target дозволяють досить чітко контролювати різні варіанти збірки, і (з мого особистого досвіду) найменш вірогідно спричиняють головний біль у довгостроковій перспективі.

Теоретично ви також можете встановити відповідні властивості безпосередньо, використовуючи це set_target_properties, але, target_compile_optionsяк правило, це читабельніше.

Наприклад, щоб встановити параметри компіляції цілі fooна основі конфігурації, використовуючи вирази генератора, ви можете написати:

target_compile_options(foo PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
target_compile_options(foo PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")

12
Зверніть увагу, що target_compile_options додайте параметри, щоб ви могли змінити останній рядок, як цей, щоб зробити його більш читабельним)

2
@ComicSansMS Чудова відповідь і найкраще (і найсучасніше), яке я міг знайти в Інтернеті. Дякую!
Ela782

Якщо я хочу мати такий самий суворий набір прапорців компіляції у всьому світі, який найкращий сучасний спосіб це зробити? Вказівка ​​одних і тих же прапорів знову і знову для різних цілей з target_compile_options здається поганою ідеєю
user3667089

1
@ user3667089 Цільові властивості зазвичай ініціалізуються змінною або властивістю каталогу. Посібник із відповідною властивістю повідомляє, який саме. У разі варіантів компіляції це COMPILE_OPTIONSробить властивість каталогу. Ви можете використовувати add_compile_optionsкоманду, щоб встановити це. Варіантів, для яких це хороший підхід, зазвичай небагато.
ComicSansMS

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