web-dev-qa-db-fra.com

Copiez le fichier cible vers un autre emplacement dans une étape de post-construction dans CMake

J'ai une bibliothèque dynamique qui obtient un nom différent en fonction de la configuration, spécifié dans les scripts CMake par:

set_target_properties(${name} PROPERTIES OUTPUT_NAME ${outputName}64)
set_target_properties(${name} PROPERTIES DEBUG_OUTPUT_NAME ${outputName}64_d)

Le résultat final est que j'obtiens un nom différent lors des versions et des versions de débogage. Je voudrais copier la bibliothèque résultante dans un répertoire différent comme étape de post-construction, mais le cadeau (?) De CMake-Fu n'a pas vraiment souri.

J'ai essayé de faire ceci:

GET_TARGET_PROPERTY(origfile mylibrary LOCATION)
STRING(REGEX REPLACE "/" "\\\\" origfile ${origfile})

set(targetfile my_target_path\\${CMAKE_CFG_INTDIR}\\)
STRING(REGEX REPLACE "/" "\\\\" targetfile ${targetfile})

add_custom_command(TARGET mylibrary POST_BUILD
    COMMAND copy ${origfile} ${targetfile}
)

Cela fonctionne très bien pour les versions, mais pour le débogage, la source n'inclut pas le _d auquel je m'attendais. Comment puis-je obtenir le chemin de sortie pour la cible afin de pouvoir copier le fichier?

Remarque: Comme le montre l'extrait ci-dessus, c'est actuellement pour Windows/Visual Studio, mais j'aimerais que cela fonctionne également sur OS X/Xcode/make.

Remarque: J'ai besoin que la bibliothèque soit placée dans un répertoire supplémentaire qui sert de répertoire de sortie pour plusieurs autres projets qui dépendent de cette bibliothèque, afin que ces projets puissent charger la bibliothèque au moment de l'exécution. Une autre solution qui serait acceptable serait de pouvoir créer une cible personnalisée qui effectue la copie, de sorte que les autres projets puissent dépendre de ce projet, qui à son tour dépend de la bibliothèque.

26
villintehaspam

Plutôt que d'utiliser la propriété obsolète LOCATION, préférez utiliser des expressions de générateur:

add_custom_command(TARGET mylibrary POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:mylibrary> ${targetfile}
)

Vous pouvez également générer directement l'exe dans le répertoire cible directement en définissant la propriété cible RUNTIME_OUTPUT_DIRECTORY au lieu de le copier. Cela a des options par configuration (par exemple RUNTIME_OUTPUT_DIRECTORY_DEBUG).

set_target_properties(mylibrary PROPERTIES
                      RUNTIME_OUTPUT_DIRECTORY_DEBUG <debug path>
                      RUNTIME_OUTPUT_DIRECTORY_RELEASE <release path>
)

Pour plus de détails, exécutez:

cmake --help-property "RUNTIME_OUTPUT_DIRECTORY"
cmake --help-property "RUNTIME_OUTPUT_DIRECTORY_<CONFIG>"

De plus, vous devriez pouvoir utiliser des barres obliques tout au long des séparateurs de chemin, même sous Windows.

41
Fraser

Utilisez expressions de générateur dans le POST_BUILD au lieu de calculer manuellement le chemin de sortie. Ceux-ci sont sensibles à la configuration. Exemple:

add_custom_command(TARGET mylibrary POST_BUILD 
  COMMAND "${CMAKE_COMMAND}" -E copy 
     "$<TARGET_FILE:mylibrary>"
     "my_target_path/$<CONFIGURATION>/$<TARGET_FILE_NAME:mylibrary>" 
  COMMENT "Copying to output directory")
11
sakra

Les autres réponses n'étaient pas 100% claires pour moi ...

Supposons que vous construisez un exécutable test_base.exe, ce qui suit va construire l'exécutable puis copier le .exe dans le répertoire de base 'build':

add_executable(test_base "")
target_sources(test_base
    PRIVATE
        catch_main.cpp
        catch_tests.cpp
        sc_main.cpp
)
target_link_libraries(test_base PRIVATE Catch2 systemc)

add_custom_command(TARGET test_base POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:test_base> ${PROJECT_BINARY_DIR}/test_base.exe
    COMMENT "Created ${PROJECT_BINARY_DIR}/test_base.exe"
)

Ainsi, après cette exécution, votre projet aura:

<project dir>/build/test_base.exe

0
driedler