Zdefiniować makro preprocesora poprzez CMake?


Odpowiedzi:


382

Przez długi czas CMake miał add_definitionsdo tego polecenie. Jednak ostatnio polecenie to zostało zastąpione bardziej szczegółowym podejściem (osobne polecenia dla definicji kompilacji, obejmują katalogi i opcje kompilatora).

Przykład użycia nowych definicji add_compile_definitions :

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION})
add_compile_definitions(WITH_OPENCV2)

Lub:

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION} WITH_OPENCV2)

Zaletą tego jest to, że omija odrapane sztuczki, dla których przygotował CMake add_definitions. CMake to taki obskurny system, ale w końcu zaczynają szukać zdrowia psychicznego.

Znajdź więcej wyjaśnień na temat poleceń używanych w flagach kompilatora tutaj: https://cmake.org/cmake/help/latest/command/add_definitions.html

Podobnie możesz zrobić to dla każdego celu, jak wyjaśniono w odpowiedzi Jima Hunzikera.


4
Z połączonej strony: „Uwaga To polecenie zostało zastąpione przez alternatywy: użyj add_compile_definitions (), aby dodać definicje preprocesora”. Może ta odpowiedź wymaga edycji?
M.Herzkamp

9
W cmake 3.10.2, add_compile_definitionsrzuty CMake Error at CMakeLists.txt:6 (add_compile_definitions): Unknown CMake command "add_compile_definitions".. add_compile_options(-D <your-def>)Zamiast tego musiałem użyć .
code_dredd

2
@mannyglover Nie wydaje mi się, ale możesz ustawić flagi kompilatora za pomocą -D, coś w stylu cmake -D CMAKE_CXXFLAGS='-DDEBUG_CHESSBOARD'(nie testowane)
ypnos

1
Jest naprawdę nowy ... w rzeczywistości jest w bardziej nowoczesnym CMake (> 3.11). Ból, który tak trudno jest poznać, kiedy wprowadzono polecenie.
Sandburg,

1
@ Sandburg Możesz otworzyć link do ostatniej dokumentacji: https://cmake.org/cmake/help/v3.17/command/add_compile_definitions.html#command:add_compile_definitionsi zacznij zmieniać numer wersji, aż strona zniknie. To byłaby wersja, w której jeszcze nie istnieje. W następnym ruchu możesz przejść do Whats newsekcji, aby znaleźć nowe polecenie lub funkcję. Więc to nie takie trudne.
Andry

245

Aby to zrobić dla określonego celu, możesz wykonać następujące czynności:

target_compile_definitions(my_target PRIVATE FOO=1 BAR=1)

Powinieneś to zrobić, jeśli budujesz więcej niż jeden cel i nie chcesz, aby wszystkie używały tych samych flag. Zobacz także oficjalną dokumentację na temat definicji_pliku_docelowego .


1
@JimHunziker Czym się target_compile_definitions(my_target PRIVATE FOO=1)różni set_source_files_properties(foo.cpp PROPERTIES COMPILE_DEFINITIONS -DFOO=1)?
John Strood,

1
@JohnStrood Różnica jest na poziomie zakresu. target_compile_definitionsustawia wartość dla CAŁEGO pliku wykonywalnego / biblioteki, gdzie jako „set_source_files_properties” ustawia wartość tylko dla określonego pliku. Polecenie Później pozwala na kompilację plików w innym języku; tj set_source_files_properties(compile_me_as_objc.c PROPERTIES -x objective-c. : Pamiętaj, że -x objective-ctutaj jest flaga specyficzna dla GCC / Clang.
Julian Kirsch

20

Inne rozwiązania proponowane na tej stronie są przydatne w niektórych wersjach Cmake <3.3.2 . Tutaj rozwiązanie dla wersji, której używam (tj 3.3.2.). Sprawdź wersję swojego Cmake za pomocą $ cmake --versioni wybierz rozwiązanie, które odpowiada Twoim potrzebom. Dokumentację cmake można znaleźć na oficjalnej stronie.

Z CMake w wersji 3.3.2, w celu utworzenia

#define foo

Musiałem użyć:

add_definitions(-Dfoo)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)

i, aby mieć definicję makra preprocesora, taką jak ta inna:

#define foo=5

linia jest tak zmodyfikowana:

add_definitions(-Dfoo=5)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)

4
Według dokumentacji to rozwiązanie jest w rzeczywistości starszym, bardziej przestarzałym podejściem. Pozostałe odpowiedzi oferują bardziej nowoczesne rozwiązania.
squareskittles,

2
Kiedy napisałem odpowiedź, wypróbowałem inne rozwiązanie, ale żadne z nich nie działało.
Leos313,

@squareskittles, jakiś pomysł, dlaczego rozwiązanie drugiej odpowiedzi nie działało poprawnie? CMake daj błędy, jeśli spróbuję
Leos313

1
Jeśli korzystasz z CMake 3.3.2, jak wskazałeś w odpowiedzi, musisz użyć add_definitions()lub target_compile_definitions(). Bardziej nowoczesne polecenie add_compile_definitions()zostało dodane dopiero w CMake 3.12. @ Leos313
squareskittles

1
@squareskittles, aktualizuję odpowiedź, ponownie pisząc to, co napisałem kilka miesięcy temu. Dziękujemy za zwrócenie na to uwagi
Leos313
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.