Chciałbym add_custom_command
to osiągnąć razem z cmake -E copy_if_different...
. Aby uzyskać pełne informacje uruchom
cmake --help-command add_custom_command
cmake -E
Więc w twoim przypadku, jeśli masz następującą strukturę katalogów:
/CMakeLists.txt
/src
/libs/test.dll
a cel CMake, do którego odnosi się polecenie MyTest
, to możesz dodać do pliku CMakeLists.txt następujące polecenie:
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 /libs/
skopiować całą zawartość katalogu, 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 chcesz skopiować różne biblioteki DLL w zależności od konfiguracji (np. Release, Debug), możesz mieć je w podkatalogach o nazwach z odpowiednią konfiguracją: /libs/Release
i /libs/Debug
. Następnie musisz wstrzyknąć typ konfiguracji do ścieżki do biblioteki dll w add_custom_command
wywołaniu, na przykład:
add_custom_command(TARGET MyTest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/libs/$<CONFIGURATION>"
$<TARGET_FILE_DIR:MyTest>)
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>
jako miejsca docelowego. W przeciwnym razie skopiowałby go do ścieżki budowania biblioteki, co było bezużyteczne.install()
dyrektyw cmake składanie plików binarnych? A możeLIBRARY
rzeczy cmake ? Naprawdę nie znam łańcucha narzędzi.$<TARGET_FILE_DIR:MyTest>
- co to jest? Jak wydrukować informacje, co dokładnie oznaczaIMPORTED_LIBRARIES
. Narzeka, że nie jest w stanie uruchomić polecenia po kompilacji, gdy nic nie zostało zbudowane.IMPORTED
bibliotek i chcesz przenieść biblioteki DLL, musisz użyć polecenia wariantu. Jeśli dodałeś swojąIMPORTED
bibliotekę tak,MyImportedLib
jakbyś używałCOMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:MyImportedLib> $<TARGET_FILE_DIR:MyTest>
Zauważ, że aby uruchomić wiele poleceń po kompilacji, potrzebujesz ich wszystkich powiązanych w jednym niestandardowym poleceniu, np.add_custom_command(TARGET MyTest POST_BUILD COMMAND #your first command# COMMAND #Your second command#)
Umieściłem te wiersze w moim pliku CMakeLists.txt najwyższego poziomu. Wszystkie biblioteki i pliki wykonywalne skompilowane przez CMake zostaną umieszczone na najwyższym poziomie katalogu kompilacji, aby pliki wykonywalne mogły znaleźć biblioteki i łatwo było je uruchomić.
Zauważ, że nie rozwiązuje to problemu OP, jakim jest kopiowanie prekompilowanych plików binarnych z katalogu źródłowego projektu.
źródło
Miałem ten problem dzisiaj, kiedy próbowałem stworzyć wersję mojego programu dla systemu Windows. Skończyło się na tym, że sam przeprowadziłem badania, ponieważ wszystkie te odpowiedzi mnie nie satysfakcjonowały. Były trzy główne problemy:
Chciałem, aby kompilacje debugowania były powiązane z wersjami debugowania bibliotek, a kompilacje wydań były odpowiednio powiązane z kompilacjami wydań bibliotek.
Oprócz tego chciałem, aby prawidłowe wersje plików DLL (Debug / Release) były kopiowane do katalogów wyjściowych.
Chciałem to wszystko osiągnąć bez pisania skomplikowanych i delikatnych skryptów.
Po przejrzeniu kilku podręczników CMake i kilku wieloplatformowych projektów na github znalazłem takie rozwiązanie:
Zadeklaruj swoją bibliotekę jako docelową za pomocą atrybutu „IMPORTOWANE”, odnieś się do jej debugowania i zwolnij pliki .lib i .dll.
Jak zwykle połącz ten cel ze swoim projektem
Wykonaj niestandardowy krok kompilacji, aby skopiować plik dll do miejsca docelowego, jeśli został w jakiś sposób zmieniony od czasu poprzedniej kompilacji
źródło
Aneks do zaakceptowanej odpowiedzi, dodany jako osobna odpowiedź, dzięki czemu otrzymuję formatowanie kodu:
Jeśli budujesz swoje biblioteki DLL w tym samym projekcie, zwykle będą one znajdować się w katalogach Release, Debug itp. Będziesz musiał użyć zmiennych środowiskowych programu Visual Studio, aby poprawnie je skopiować. na przykład:
dla źródła i
do miejsca docelowego. Zwróć uwagę na ucieczkę!
Nie można użyć zmiennej CMake CMAKE_BUILD_TYPE do konfiguracji, ponieważ jest ona rozwiązana w czasie generowania projektu VS i zawsze będzie taka, jaka jest domyślna.
źródło
$<CONFIGURATION>
Możesz także użyć polecenia find_library:
Na przykład ze zdefiniowaną ścieżką EXECUTABLE_PATH:
możesz przenieść pliki .dll, których potrzebujesz, za pomocą
źródło
Przydaje się to jednemu z nich
źródło
Prawdopodobnie musisz dodać cel niestandardowy i uzależnić go od jednego z plików wykonywalnych.
Aby skopiować plik za pomocą powyższej funkcji użyj:
źródło
Jestem początkującym użytkownikiem CMake, ale nadal chciałem podzielić się swoim doświadczeniem. W moim przypadku potrzebowałem kopii poinstalacyjnej, aby wszystkie moje pliki binarne były w formacie. W przypadku pliku binarnego innej firmy, który można zaimportować w CMake, działa dla mnie następujące rozwiązanie:
Oczywiście IMPORTED_LOCATION_RELEASE może mieć warianty w zależności od tego, jak została zbudowana / zainstalowana biblioteka współdzielona. Może być IMPORTED_LOCATION_DEBUG.
Może jest lepszy sposób na uzyskanie nazwy tej nieruchomości, nie wiem.
źródło
Przenoszenie plików podczas kompilacji przy użyciu
install
Miałem ten problem, próbując postępować zgodnie z oficjalnym samouczkiem CMake w kroku 9 . To była lokalizacja pliku, który chciałem przenieść:
To była lokalizacja, w której chciałem, aby znajdował się plik:
Od tego DLL została wygenerowana w udostępnionej biblioteki, wszystko, co nie było włączenie tej linii w
CMakeLists.txt
w podkatalogu , który zawierał kod źródłowy bibliotekisrc/Mathfunctions/CMakeLists.txt
Dzięki Twoim odpowiedziom mogłem pomyśleć o tym. To tylko jedna linia, więc myślę, że jest w porządku.
$<CONFIG>
Może mieć dwie wartości Debug lub Release W zależności od tego, jak projekt jest zbudowany zgodnie z wymogami oryginalne pytanie.źródło