2015-04-30 8 views
9

docs dla CMake 3.2.2 stanie, że możliwe jest użycie wyrażeń generatora do podpisu install(<FILES|PROGRAMS> ...). Starałem się używać wyrażeń generatora innymi podpisami install(), ale najwyraźniej to nie działa. Chciałbym zrobić coś takiego:Generator Expression do zainstalowania() nakazuje

install(TARGETS foo EXPORT fooConfig 
     RUNTIME DESTINATION "Bin/$<CONFIG>" 
     LIBRARY DESTINATION "Lib/$<CONFIG>" 
     ARCHIVE DESTINATION "Lib/$<CONFIG>" 

Próbowałem też dzwoniąc install() wielokrotnie tak:

install(TARGETS foo EXPORT fooConfig 
     RUNTIME DESTINATION "Bin/Debug" CONFIGURATIONS Debug 
     LIBRARY DESTINATION "Lib/Debug" CONFIGURATIONS Debug 
     ARCHIVE DESTINATION "Lib/Debug" CONFIGURATIONS Debug 
install(TARGETS foo EXPORT fooConfig 
     RUNTIME DESTINATION "Bin/Release" CONFIGURATIONS Release 
     LIBRARY DESTINATION "Lib/Release" CONFIGURATIONS Release 
     ARCHIVE DESTINATION "Lib/Release" CONFIGURATIONS Release 
install(TARGETS foo EXPORT fooConfig 
     RUNTIME DESTINATION "Bin/MinSizeRel" CONFIGURATIONS MinSizeRel 
     LIBRARY DESTINATION "Lib/MinSizeRel" CONFIGURATIONS MinSizeRel 
     ARCHIVE DESTINATION "Lib/MinSizeRel" CONFIGURATIONS MinSizeRel 
install(TARGETS foo EXPORT fooConfig 
     RUNTIME DESTINATION "Bin/RelWithDebInfo" CONFIGURATIONS RelWithDebInfo 
     LIBRARY DESTINATION "Lib/RelWithDebInfo" CONFIGURATIONS RelWithDebInfo 
     ARCHIVE DESTINATION "Lib/RelWithDebInfo" CONFIGURATIONS RelWithDebInfo 

Powoduje CMake emitować błąd wzdłuż linii Target „foo” eksportowanych więcej niż raz w „fooConfig”.

Nie mogę korzystać CMAKE_BUILD_TYPE tutaj albo bez aktualizowania pamięci podręcznej CUpewnij i ponowne przeprowadzenie kompilacji. Zamiast tego chcę użyć funkcji batch-build Visual Studio, która buduje dla mnie wiele konfiguracji.

Byłem trochę hack, że próbowałem też. Zauważyłem, że generowane INSTALL CWprowadä projekt jest po prostu powołując skrypt CUpewnij ${CMAKE_BINARY_DIR}/cmake_install.cmake z argumentem -DBUILD_TYPE=$(Configuration). Tak więc próbowałem:

install(TARGETS foo EXPORT fooConfig 
     RUNTIME DESTINATION "Bin/\${BUILD_TYPE}" 
     LIBRARY DESTINATION "Lib/\${BUILD_TYPE}" 
     ARCHIVE DESTINATION "Lib/\${BUILD_TYPE}" 

To faktycznie działało dobrze dla instalacji. Jednak zainstalowany skrypt eksportu, tj. Plik wyjściowy install(EXPORT fooConfig DESTINATION .), teraz próbuje również użyć , który nie jest ustawiony w momencie, w którym użytkownik zawiera ten skrypt ...

Jeśli ktoś zna inny sposób osiągnięcia moich celów, proszę ja wiem.

Odpowiedz

6

Niestety, komenda install obsługuje tylko wyrażenia generatora dla listy plików do zainstalowania, ale nie dla katalogu docelowego.

Polecam na wystające ze swojej małej siekać, ale zamiast używać CMAKE_INSTALL_CONFIG_NAMECMAKE_BUILD_TYPE, tj .:

install(TARGETS foo EXPORT fooConfig 
     RUNTIME DESTINATION "Bin/\${CMAKE_INSTALL_CONFIG_NAME}" 
     LIBRARY DESTINATION "Lib/\${CMAKE_INSTALL_CONFIG_NAME}" 
     ARCHIVE DESTINATION "Lib/\${CMAKE_INSTALL_CONFIG_NAME}" 

CMAKE_INSTALL_CONFIG_NAME jest ustawiony w aktualnej konfiguracji kompilacji używane do instalowania w wygenerowanym cmake_install.cmake skryptu.

Wygenerowane skrypty eksportu (np., fooConfig-debug.cmake) można automatycznie naprawić, dodając skrypt łatki do procesu instalacji. Wygenerować plik patch_export_files.cmake z następujących zawartości w katalogu źródłowym:

file(GLOB_RECURSE _configFiles "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/fooConfig-*.cmake") 
foreach(_configFile ${_configFiles}) 
    file (READ "${_configFile}" _contents) 
    string (REGEX MATCH "configuration \"[A-Za-z]+\"" _configName "${_contents}") 
    if (_configName MATCHES "\"([A-Za-z]+)\"") 
     message(STATUS "Patching: ${_configFile}") 
     string (REPLACE "\${CMAKE_INSTALL_CONFIG_NAME}" "${CMAKE_MATCH_1}" _patchedContents "${_contents}") 
     file (WRITE "${_configFile}" "${_patchedContents}") 
    endif() 
endforeach() 

Skrypt łata musi być prowadzony w czasie instalacji przez dodanie install(SCRIPT ... połączenia po install(EXPORT ...:

install(EXPORT fooConfig DESTINATION .) 
... 
install(SCRIPT patch_export_files.cmake) 

skrypt łata pierwszy analizuje konfigurację, z której wygenerowany skrypt eksportowy jest poprawny, z jego komentarza nagłówka, a następnie zastępuje każde użycie ${CMAKE_INSTALL_CONFIG_NAME} nazwą konfiguracji.

+0

Spodziewałem się, że muszę zrobić coś takiego ... Szkoda, że ​​CMake nie obsługuje czegoś takiego. W ich systemie śledzenia problemów zauważyłem, że ostatnio zaimplementowano wyrażenia generujące dla argumentów DESTINATION wszystkich podpisów install(), ale nie ma jeszcze oficjalnego wydania z tą funkcją. Tak więc dla przyszłych użytkowników: ostatnie wersje CMake (> 3.2.2) prawdopodobnie już obsługują wyrażenia generatora dla innych sygnatur niż instalacyjnych (PLIKI). – Manuzor

2

pracuję nad projektem, który wymaga buduje z różnych konfiguracjach. Sposób, w jaki to osiągnąłem, polega na użyciu "ExternalProject".

Stworzyłem repozytorium próbki, aby pokazać wam pomysł: https://github.com/mpaluru/cmake_multiple_build_configs_example

(Linux jest środowiskiem używam najczęściej i nie mają dostępu do Visual Studio). Jeśli przechodzą na fladze -G w najwyższym poziomie CMakeLists.txt powinieneś być w stanie wygenerować swoje pliki VS. Przetestowałem to na Linuksie i "make -j" działa dobrze. Obie konfiguracje debugowania i wydawania są budowane równolegle.

Podsumowanie: Tworzysz nowy projekt superbuild, który wywołuje twój projekt za pomocą ExternalProject_Add z innym CMAKE_BUILD_TYPE.

I na podstawie typu kompilacji przekazuje się różne definicje lub instaluje się inaczej.

+0

ExternalProject to dobry pomysł, ale wymagałoby to zmiany istniejącego drzewa źródeł, prawda? – Manuzor

+0

NIE i TAK. To zależy od konfiguracji twojego bieżącego projektu. Jeśli już zajmowałeś się robieniem różnych rzeczy na podstawie zmiennej CMAKE_BUILD_TYPE, nie musisz w ogóle modyfikować istniejącego projektu. Wszystko, co musisz zrobić, to stworzyć nowy projekt opakowania, jak wskazałem w przykładowym kodzie. –

+0

Ale ten projekt otoki musiałby żyć poza istniejącym kodem, co najmniej o jeden poziom powyżej oryginalnego źródła. Czy jest jakiś sposób na włączenie tego opakowania bezpośrednio do katalogu głównego? Może poprzez wielokrotne włączenie? – Manuzor