2016-03-04 9 views
6

W CMake na flagi dla kompilatora C++ można wpływać na różne sposoby: ustawiając CMAKE_CXX_FLAGS ręcznie, używając add_definitions(), wymuszając pewien standard C++ i tak dalej.Pobierz pełną linię komend kompilatora C++

Aby skompilować cel w tym samym projekcie z różnymi regułami (prekompilowany nagłówek, w moim przypadku), muszę odtworzyć dokładne polecenie, które jest używane do kompilowania plików dodanych przez polecenie takie jak add_executable() w tym katalogu.

Czytanie CMAKE_CXX_FLAGS zwraca tylko wartość ustawioną do niego jawnie, CMAKE_CXX_FLAGS_DEBUG i tylko lista rodzeństwa zawiera domyślne opcje debugowania/wydawania. Istnieją specjalne funkcje pobierania flag od add_definitions() i add_compiler_options(), ale żadna nie wydaje się być w stanie zwrócić ostateczną linię poleceń.

Jak mogę uzyskać wszystkie flagi przekazane do kompilatora do zmiennej CMake?

Odpowiedz

3

Aby odpowiedzieć na moje własne pytanie: Wydaje się, że jedynym sposobem na uzyskanie wszystkie flagi kompilatora jest odtworzenie ich z różnych źródeł. Kod pracuję ze teraz jest następujący (GCC):

macro (GET_COMPILER_FLAGS TARGET VAR) 
    if (CMAKE_COMPILER_IS_GNUCXX) 
     set(COMPILER_FLAGS "") 

     # Get flags form add_definitions, re-escape quotes 
     get_target_property(TARGET_DEFS ${TARGET} COMPILE_DEFINITIONS) 
     get_directory_property(DIRECTORY_DEFS COMPILE_DEFINITIONS) 
     foreach (DEF ${TARGET_DEFS} ${DIRECTORY_DEFS}) 
      if (DEF) 
       string(REPLACE "\"" "\\\"" DEF "${DEF}") 
       list(APPEND COMPILER_FLAGS "-D${DEF}") 
      endif() 
     endforeach() 

     # Get flags form include_directories() 
     get_target_property(TARGET_INCLUDEDIRS ${TARGET} INCLUDE_DIRECTORIES) 
     foreach (DIR ${TARGET_INCLUDEDIRS}) 
      if (DIR) 
       list(APPEND COMPILER_FLAGS "-I${DIR}") 
      endif() 
     endforeach() 

     # Get build-type specific flags 
     string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE_SUFFIX) 
     separate_arguments(GLOBAL_FLAGS UNIX_COMMAND 
       "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BUILD_TYPE_SUFFIX}}") 
     list(APPEND COMPILER_FLAGS ${GLOBAL_FLAGS}) 

     # Add -std= flag if appropriate 
     get_target_property(STANDARD ${TARGET} CXX_STANDARD) 
     if ((NOT "${STANDARD}" STREQUAL NOTFOUND) AND (NOT "${STANDARD}" STREQUAL "")) 
      list(APPEND COMPILER_FLAGS "-std=gnu++${STANDARD}") 
     endif() 
    endif() 
    set(${VAR} "${COMPILER_FLAGS}") 
endmacro() 

ten może być przedłużony do także wywołane przez add_compiler_options() i więcej opcji.

2

Najprostszym sposobem jest użycie make VERBOSE=1 podczas kompilacji.

cd my-build-dir 
cmake path-to-my-sources 
make VERBOSE=1 

Spowoduje to utworzenie kompilacji jednowątkowej, a make spowoduje wydrukowanie wszystkich poleceń powłoki, które uruchamia tuż przed uruchomieniem. Więc zobaczysz wyjście jak:

[ 0%] Building CXX object Whatever.cpp.o 
<huge scary build command it used to build Whatever.cpp> 
+1

Jest to na pewno przydatne, ale muszę ponownie użyć flag kompilatora w tym samym projekcie, więc w jakiś sposób muszę je pobrać do zmiennej. –

+0

To jest trudniejsze. Uważam, że jedyną opcją jest połączenie wszystkich różnych źródeł flag razem. Prekompilowane nagłówki są źródłem znaczących problemów z CMake. Wiele flag ma także odwrotność, która zastąpi wcześniejszą wersję pozytywną (więc jeśli potrzebujesz tylko wyłączyć kilka rzeczy, możesz je odwrócić za pomocą _adding_ dodatkowych flag). Chyba widziałem to: http://stackoverflow.com/questions/148570/using-pre-compiled-headers-with-cmake –

+0

To wydaje się być jedynym rozwiązaniem, dzięki. –

Powiązane problemy