Chciałbym użyć globalnego zestawu flag do kompilacji projektu, co oznacza, że w moim pliku CMakeLists.txt najwyższego poziomu określiłem:
ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )
Jednak dla określonego pliku (powiedzmy "foo.cpp") w podkatalogu, chcę przełączyć flagi kompilacji, aby nie stosować -Weffc ++ (dołączona biblioteka komercyjna, której nie mogę zmienić). Aby uprościć sytuację, aby użyć tylko -Wall, próbowałem:
SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
, który nie zadziałał. Ja też próbowałem
SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
i
ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )
, w którym żaden nie działał.
Wreszcie spróbowałem usunąć tę definicję:
REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )
, co również nie zadziałało (co oznacza, że dostaję wiele ostrzeżeń dotyczących stylu komercyjnej biblioteki). (** Uwaga: ostrzeżenia są pomijane, jeśli NIE dołączę ponownie dyrektywy -Weffc ++ po zbudowaniu pliku wykonywalnego).
Próbowałem też tymczasowo usunąć flagi kompilacji: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , ale to nie pomogło.
Czy nie ma na to eleganckiego rozwiązania?
źródło
Odpowiedzi:
Twoje próby powyżej dodają dalsze flagi do twojego pliku / celu, zamiast nadpisywać, jak się wydajesz. Na przykład z dokumentacji dotyczącej właściwości w plikach źródłowych - COMPILE_FLAGS :
Powinieneś być w stanie usunąć
-Weffc++
flagę dla foo.cpp, wykonującPowinno to skutkować dodaniem
-Wno-effc++
po-Weffc++
w poleceniu kompilatora, a to drugie ustawienie wygrywa. Aby zobaczyć pełne polecenie i sprawdzić, czy tak jest, możesz to zrobićNawiasem mówiąc, jeden z opiekunów Biblioteki standardowej GNU C ++ przedstawia
-Weffc++
w tej odpowiedzi dość negatywną opinię .Inną kwestią jest to, że nadużywasz
add_definitions
w tym sensie, że używasz tego do flag kompilatora, a nie do zamierzonych definicji preprocesorów.Byłoby lepiej użyć
add_compile_options
lub dla wersji CMake <3.0, aby zrobić coś więcej jak:
W odpowiedzi na dalsze pytania w komentarzach poniżej uważam, że niemożliwe jest wiarygodne usunięcie flagi z pojedynczego pliku. Powodem jest to, że do dowolnego pliku źródłowego zastosowano cel
COMPILE_OPTIONS
i 1 , ale nie pojawiają się one w żadnej z właściwości tego pliku źródłowego.COMPILE_FLAGS
Możesz spojrzeć na usunięcie flagi problemu z elementu docelowego
COMPILE_OPTIONS
, a następnie zastosowanie go do każdego źródła celu indywidualnie, pomijając go w określonym pliku źródłowym zgodnie z wymaganiami.Jednak, chociaż może to działać w wielu scenariuszach, wiąże się to z kilkoma problemami.
Po pierwsze - właściwości plików źródłowych nie obejmują
COMPILE_OPTIONS
tylkoCOMPILE_FLAGS
. Jest to problem, ponieważCOMPILE_OPTIONS
element docelowy może zawierać wyrażenia generatora , aleCOMPILE_FLAGS
ich nie obsługuje. Więc musiałbyś uwzględniać wyrażenia generatora podczas wyszukiwania swojej flagi, a nawet być może musiałbyś nawet "przeanalizować" wyrażenia generatora, jeśli twoja flaga była zawarta w jednym lub więcej, aby zobaczyć, czy powinna zostać ponownie zastosowana do pozostałych pliki źródłowe.Po drugie - od CMake v3.0 cele mogą określać
INTERFACE_COMPILE_OPTIONS
. Oznacza to, że zależność twojego celu może dodać lub nadpisać twój celCOMPILE_OPTIONS
poprzez jegoINTERFACE_COMPILE_OPTIONS
. Więc dalej musiałbyś rekurencyjnie iterować przez wszystkie zależności twojego celu (nie jest to szczególnie łatwe zadanie, ponieważ listaLINK_LIBRARIES
dla celu może również zawierać wyrażenia generatora), aby znaleźć te, które stosują flagę problemu, i spróbować usunąć je z tych cele ”INTERFACE_COMPILE_OPTIONS
.Na tym etapie złożoności chciałbym przesłać poprawkę do CMake, aby zapewnić funkcję bezwarunkowego usuwania określonej flagi z pliku źródłowego.
1: Zwróć uwagę, że w przeciwieństwie do
COMPILE_FLAGS
właściwości w plikach źródłowychCOMPILE_FLAGS
właściwość obiektów docelowych jest przestarzała.źródło
Po prostu dodam poprawną odpowiedź @ Fraser.
W przypadku, gdy chcesz dodać specjalną flagę do określonych folderów, możesz zrobić:
lub
Zauważ, że nie zaleca się używania GLOB, jak omówiono tutaj
źródło
Korzystając z odpowiedzi @Fraser, utworzyłem poniższy kod, aby obsłużyć dołączenia Qt, ponieważ zmienna zawiera wiele ścieżek oddzielonych średnikami. Oznacza to, że musiałem najpierw dodać
foreach()
pętlę i ręcznie utworzyć flagi dołączania . Ale to pozwala mi mieć jeden wyjątek: foo.cpp (ten jeden plik używa Qt na razie, ale na dłuższą metę chcę usunąć tę zależność i chcę się upewnić, że Qt nie wkradnie się nigdzie indziej).Zauważ również, że używam
-isystem
zamiast tego,-I
aby uniknąć niektórych ostrzeżeń, które w przeciwnym razie generują nagłówki Qt (mam włączonych mnóstwo ostrzeżeń).źródło