Jaka jest nowoczesna metoda ustawiania ogólnych flag kompilacji w CMake?

84

CMake oferuje wiele mechanizmów pobierania flag do kompilatora:

Czy jest jedna metoda, która jest preferowana w nowoczesnym zastosowaniu? Jeśli tak, dlaczego? Ponadto, w jaki sposób można używać tej metody w przypadku wielu systemów konfiguracyjnych, takich jak MSVC?

Peter Clark
źródło

Odpowiedzi:

94

W przypadku nowoczesnego CMake (wersje 2.8.12 i nowsze) należy użyć target_compile_options, który wewnętrznie używa właściwości docelowych.

CMAKE_<LANG>_FLAGSjest zmienną globalną i najbardziej podatną na błędy w użyciu. Nie obsługuje również wyrażeń generatora , co może być bardzo przydatne.

add_compile_options opiera się na właściwościach katalogu, co jest dobre w niektórych sytuacjach, ale zwykle nie jest najbardziej naturalnym sposobem określania opcji.

target_compile_optionsdziała na zasadzie docelowej (poprzez ustawienie właściwości COMPILE_OPTIONSi INTERFACE_COMPILE_OPTIONStarget), co zwykle daje najczystszy kod CMake, ponieważ opcje kompilacji dla pliku źródłowego są określane przez to, do którego projektu należy plik (a nie do którego katalogu jest umieszczony na dysku twardym). Ma to dodatkową zaletę, że automatycznie dba o przekazywanie opcji do zależnych celów, jeśli jest to wymagane.

Mimo że są nieco bardziej szczegółowe, polecenia dla każdego celu pozwalają na dość precyzyjną kontrolę nad różnymi opcjami kompilacji i (z mojego osobistego doświadczenia) są najmniej narażone na bóle głowy na dłuższą metę.

Teoretycznie można również ustawić odpowiednie właściwości bezpośrednio za pomocą set_target_properties, ale target_compile_optionszwykle jest to bardziej czytelne.

Na przykład, aby ustawić opcje kompilacji celu foona podstawie konfiguracji przy użyciu wyrażeń generatora, możesz napisać:

target_compile_options(foo PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
target_compile_options(foo PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")
ComicSansMS
źródło
12
Zauważ, że target_compile_options dodaj opcje, abyś mógł zmodyfikować ostatnią linię w ten sposób, aby była bardziej czytelna)
2
@ComicSansMS Świetna odpowiedź i najlepsza (i najbardziej aktualna), jaką udało mi się znaleźć w Internecie. Dzięki!
Ela782
Jeśli chcę mieć ten sam ścisły zestaw flag kompilacji na całym świecie, jaki jest najlepszy nowoczesny sposób na zrobienie tego? Określanie tych samych flag raz po raz dla różnych celów za pomocą target_compile_options wydaje się złym pomysłem
user3667089
1
@ user3667089 Właściwości specyficzne dla celu zwykle są inicjowane przez zmienną lub właściwość katalogu. Strona podręcznika dla odpowiedniej właściwości zawiera dokładne informacje. W przypadku opcji kompilacji COMPILE_OPTIONSrobi to właściwość katalogu. Możesz użyć add_compile_optionspolecenia, aby to ustawić. Opcje, w przypadku których jest to dobre podejście, są zwykle nieliczne.
ComicSansMS
6
@ComicSansMS Jakie jest zastosowanie PUBLICw target_compile_options?
Ramana Reddy