2012-05-20 10 views
65

Używamy CMake do generowania plików Visual Studio naszych źródeł w naszym SVN. Teraz moje narzędzie wymaga, aby niektóre pliki DLL znajdowały się w tym samym folderze, co plik wykonywalny. Pliki DLL znajdują się w folderze obok źródła.Jak skopiować pliki DLL do tego samego folderu, co plik wykonywalny za pomocą CMake?

Jak mogę zmienić swój CMakeLists.txt w taki sposób, że wygenerowany projekt Visual Studio będzie miał już określone pliki DLL w folderach wydania/debugowania lub skopiuje je po kompilacji?

Odpowiedz

79

Aby to osiągnąć, użyłbym add_custom_command wraz z cmake -E copy_if_different.... Dla pełnej informacji działać

cmake --help-command add_custom_command 
cmake -E 


Więc w twoim przypadku, jeśli mają następującą strukturę katalogów:

/CMakeLists.txt 
/src 
/libs/test.dll 

i swój cel CUpewnij do którego komenda dotyczy to MyTest, wtedy może dodać następujące elementy do pliku CMakeLists.txt:

add_custom_command(TARGET MyTest POST_BUILD  # Adds a post-build event to MyTest 
    COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..." 
     "${PROJECT_SOURCE_DIR}/libs/test.dll"  # <--this is in-file 
     $<TARGET_FILE_DIR:MyTest>)     # <--this is out-file path 


Jeśli chcesz tylko całą zawartość katalogu /libs/ skopiowane, użyj cmake -E copy_directory:

add_custom_command(TARGET MyTest POST_BUILD 
    COMMAND ${CMAKE_COMMAND} -E copy_directory 
     "${PROJECT_SOURCE_DIR}/libs" 
     $<TARGET_FILE_DIR:MyTest>) 


Jeśli trzeba skopiować różnych bibliotek DLL w zależności od konfiguracji (Release, Debug, np.) możesz mieć te w podkatalogach o odpowiedniej konfiguracji: /libs/Release i /libs/Debug. Następnie należy wstrzyknąć typ konfiguracji do ścieżki do biblioteki dll w zaproszeniu add_custom_command, tak:

add_custom_command(TARGET MyTest POST_BUILD 
    COMMAND ${CMAKE_COMMAND} -E copy_directory 
     "${PROJECT_SOURCE_DIR}/libs/$<CONFIGURATION>" 
     $<TARGET_FILE_DIR:MyTest>) 
+1

Szybka uwaga dla tego, co działało w moim przypadku na wypadek, gdyby pomógł komuś innemu w przyszłości: Mam projekt biblioteki statycznej, do której główny plik wykonywalny opcjonalnie się łączy, a biblioteka ta wymaga skopiowania biblioteki DLL, jeśli zostanie dodana. W pliku CMakeLists.txt tej biblioteki użyłem '$ {CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$ ' dla miejsca docelowego. W przeciwnym razie skopiowałby go do ścieżki budowania biblioteki, która była bezużyteczna. – AberrantWolf

1

Prawdopodobnie musisz add custom target i uzależnić od jednego z twoich wykonywalnych celów. Aby skopiować plik za pomocą powyższej funkcji, użyj:

COMMAND ${CMAKE_PROGRAM} -E copy_if_different ${CMAKE_BINARY_DIR}/path/to/file.dll ${CMAKE_BINARY_DIR}/where/to/put/file.dll.

5

Uzupełnienie do przyjętej odpowiedź dodana jako oddzielny odpowiedź więc dostać formatowania kodu:

Jeśli budujesz biblioteki DLL w tym samym projekcie, zazwyczaj będą to katalogi Release, Debug, itp. Będziesz musiał użyć zmiennych środowiskowych Visual Studio, aby poprawnie je skopiować. np .:

"${PROJECT_BINARY_DIR}/your_library/\$\(Configuration\)/your_library.dll" 

dla źródła i

"${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/your_library.dll" 

do miejsca przeznaczenia. Zwróć uwagę na ucieczkę!

Nie można używać CMake CMAKE_BUILD_TYPE dla konfiguracji, ponieważ została rozwiązana w czasie generowania projektu VS i będzie zawsze taka, jaka jest domyślna.

+5

Ostatnia część zaakceptowanej odpowiedzi odnosi się do tego w czystszy sposób CMake przy użyciu '$ ' –

1

Jest to przydatne dla jednego z nich

SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY 
    ${PROJECT_SOURCE_DIR}/lib CACHE 
    PATH "Directory where all the .lib files are dumped." FORCE) 
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY 
    ${PROJECT_SOURCE_DIR}/bin CACHE 
    PATH "Directory where .exe and .dll files are dumped." FORCE) 
9

umieścić te linie w moim pliku CMakeLists.txt najwyższego poziomu. Wszystkie biblioteki i pliki wykonywalne zostaną umieszczone na najwyższym poziomie katalogu budowania, tak aby pliki wykonywalne mogły znajdować biblioteki i łatwo można je uruchomić.

set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) 
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) 
0

Można również użyć find_library polecenia:

find_library(<some_var> NAMES <name_of_lib> PATHS "<path/to/lib>") 

z określonym EXECUTABLE_PATH, na przykład:

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 

można przesunąć pliki .dll, że plik wykonywalny potrzeba, z

file(COPY ${<some_var>} 
    DESTINATION ${EXECUTABLE_OUTPUT_PATH}) 
Powiązane problemy