Cmake add_custom_target Config depending Output directory
Hin und wieder muss ich bei Software Projekten ein Target erstellen welches einfach nur einen Job erledigt und das Resultat in den Output kopiert.
In einigen IDEs, wie Visual Studio, ist der Output abhängig von der Config, wie Release oder Debug. Um das custom target in das richtige Verzeichnis kopieren zu lassen verwende ich einen kleinen Trick mit generator expressions um das zu bewerkstelligen.
Hier seht ihr meine default config um für debug und release unterschiedliche Augabeverzeichnisse zu verwenden:
# Set runtime output dir to root/output if no other location was defined
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../../Output/default/bin")
endif()
# Set library output dir to root/output if no other location was defined
if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../../Output/default/lib")
endif()
# Set archive output dir to root/output if no other location was defined
if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../../Output/default/lib/static")
endif()
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG_UPPER )
# Set runtime output dir to root/output if no other location was defined
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG_UPPER})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG_UPPER} "${CMAKE_CURRENT_LIST_DIR}/../../Output/${OUTPUTCONFIG}/bin")
endif()
# Set library output dir to root/output if no other location was defined
if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG_UPPER})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG_UPPER} "${CMAKE_CURRENT_LIST_DIR}/../../Output/${OUTPUTCONFIG}/lib")
endif()
# Set archive output dir to root/output if no other location was defined
if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG_UPPER})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG_UPPER} "${CMAKE_CURRENT_LIST_DIR}/../../Output/${OUTPUTCONFIG}/static")
endif()
set(CONFIG_DEPENDING_OUTPUT_DIR "${CONFIG_DEPENDING_OUTPUT_DIR}$<$<CONFIG:${OUTPUTCONFIG}>:${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG_UPPER}}>")
endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )
In der letzten Zeile seht ihr die Variable CONFIG_DEPENDING_OUTPUT_DIR. Diese wird um jede benutzte Config erweitert.
Die CONFIG_DEPENDING_OUTPUT_DIR enthält für jede Config einen anderen Output Pfad bereit.
Dieser Pfad lässt sich nun in einem add_custom_target wiederverwenden:
set(COPY_FILE_IN "${CMAKE_CURRENT_LIST_DIR}/FileToCopy.txt")
add_custom_target(CopyConfiguredFile ALL)
add_custom_command(TARGET CopyConfiguredFile POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${COPY_FILE_IN} ${CONFIG_DEPENDING_OUTPUT_DIR}/custom/FileToCopy.txt
)
In diesem Beispiel wird eine Text-Datei in den Output der jeweiligen Konfiguration kopiert.