cmake
Pasos de compilación personalizados
Buscar..
Introducción
Los pasos de compilación personalizados son útiles para ejecutar objetivos personalizados en la compilación de su proyecto o para copiar fácilmente los archivos para que no tenga que hacerlo manualmente (¿quizás dlls?). Aquí le mostraré dos ejemplos, el primero es para copiar dlls (en particular Qt5 dlls) a su directorio binario de proyectos (ya sea Debug o Release) y el segundo es para ejecutar un objetivo personalizado (Doxygen en este caso) en su solución (Si estás utilizando Visual Studio).
Observaciones
Como puede ver, puede hacer mucho con objetivos de compilación personalizados y pasos en cmake, pero debe tener cuidado al usarlos, especialmente al copiar archivos DLL. Si bien es conveniente hacerlo, a veces puede dar lugar a lo que se llama cariñosamente "infierno dll".
Básicamente, esto significa que puede perderse en qué dlls depende realmente su ejecutable, cuáles se cargan y cuáles necesita ejecutar (tal vez debido a la variable de ruta de su computadora).
¡Aparte de la advertencia anterior, siéntete libre de hacer que los objetivos personalizados hagan lo que quieras! Son potentes y flexibles, y son una herramienta invaluable para cualquier proyecto de creación.
Ejemplo de copia dt Qt5
Entonces, digamos que tiene un proyecto que depende de Qt5 y necesita copiar los archivos DLL relevantes a su directorio de compilación y no quiere hacerlo manualmente; puedes hacer lo siguiente:
cmake_minimum_required(VERSION 3.0)
project(MyQtProj LANGUAGES C CXX)
find_package(Qt5 COMPONENTS Core Gui Widgets)
#...set up your project
# add the executable
add_executable(MyQtProj ${PROJ_SOURCES} ${PROJ_HEADERS})
add_custom_command(TARGET MyQtProj POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:MyQtProj>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:MyQtProj>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:MyQtProj>
)
Entonces, cada vez que construya su proyecto, si las dll de destino han cambiado y desea copiarlas, se copiarán después de que se construya su objetivo (en este caso, el ejecutable principal) (observe el comando copy_if_different
); De lo contrario, no serán copiados.
Además, tenga en cuenta el uso de expresiones de generador aquí. La ventaja con el uso de estos es que no tiene que decir explícitamente dónde copiar los archivos DLL o qué variantes utilizar. Sin embargo, para poder usarlos, el proyecto que está utilizando (Qt5 en este caso) debe tener objetivos importados.
Si está creando una depuración, CMake sabe (según el destino importado) copiar los archivos Qt5Cored.dll, Qt5Guid.dll y Qt5Widgetsd.dll en la carpeta Debug de su carpeta de compilación. Si está creando una versión de lanzamiento, las versiones de lanzamiento de los .dlls se copiarán a la carpeta de la versión.
Ejecutar un objetivo personalizado
También puede crear un destino personalizado para ejecutar cuando desee realizar una tarea en particular. Estos son típicamente ejecutables que ejecutas para hacer cosas diferentes. Algo que puede ser de particular uso es ejecutar Doxygen para generar documentación para su proyecto. Para hacer esto, puede hacer lo siguiente en su CMakeLists.txt
(por simplicidad continuaremos con nuestro ejemplo de proyecto de Qt5):
cmake_minimum_required(VERSION 3.0)
project(MyQtProj LANGUAGES C CXX)
find_package(Qt5 COMPONENTS Core Gui Widgets)
#...set up your project
add_executable(MyQtProj ${PROJ_SOURCES} ${PROJ_HEADERS})
add_custom_command(TARGET MyQtProj POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:MyQtProj>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:MyQtProj>
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:MyQtProj>
)
#Add target to build documents from visual studio.
set(DOXYGEN_INPUT ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile)
#set the output directory of the documentation
set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/docs)
# sanity check...
message("Doxygen Output ${DOXYGEN_OUTPUT_DIR}")
find_package(Doxygen)
if(DOXYGEN_FOUND)
# create the output directory where the documentation will live
file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR})
# configure our Doxygen configuration file. This will be the input to the doxygen
# executable
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in
${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
# now add the custom target. This will create a build target called 'DOCUMENTATION'
# in your project
ADD_CUSTOM_TARGET(DOCUMENTATION
COMMAND ${CMAKE_COMMAND} -E echo_append "Building API Documentation..."
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOXYGEN_OUTPUT_DIR}
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E echo "Done."
WORKING_DIRECTORY ${DOXYGEN_OUTPUT_DIR})
endif(DOXYGEN_FOUND)
Ahora, cuando creamos nuestra solución (nuevamente, suponiendo que está utilizando Visual Studio), tendrá un objetivo de compilación llamado DOCUMENTATION
que puede compilar para regenerar la documentación de su proyecto.