Use la lista como dependencias en add_custom_command
Quiero usar la lista, es decir, set(RESOURCES foo.txt bar.txt foo.bar bar.foo)como dependencias en lugar de escribir manualmente en la add_custom_commandparte DEPENDS.
El caso de uso de la vida real es para una glib-compile-resourcesherramienta de utilidad donde un usuario puede permitirle generar todas las dependencias del archivo xml usando el --generate-dependenciesparámetro. En nuestro caso, la salida se almacena en una variable usando CMake execute_process(). De esa manera, no tengo que actualizar manualmente el script CMake cada vez que se agrega o elimina un nuevo recurso del archivo xml.
cmake_minimum_required(VERSION 3.15)
project(dummy LANGUAGES C)
find_program(GLIB_COMPILE_RESOURCES NAMES glib-compile-resources REQUIRED)
set(GRESOURCE_C dummy.gresource.c)
set(GRESOURCE_XML dummy.gresource.xml)
set(GRESOURCE_XML_IN dummy.gresource.xml.in)
set(GRESOURCE_DEPENDENCIES)
set(OLD ${CMAKE_CURRENT_SOURCE_DIR}/${GRESOURCE_XML_IN})
set(NEW ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_XML})
if(NOT EXISTS ${OLD} OR (${OLD} IS_NEWER_THAN ${NEW})) configure_file(${GRESOURCE_XML_IN} ${GRESOURCE_XML}) execute_process( WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${GLIB_COMPILE_RESOURCES} --generate-dependencies ${GRESOURCE_XML}
OUTPUT_VARIABLE GRESOURCE_DEPENDENCIES
)
endif()
add_custom_command(
OUTPUT ${GRESOURCE_C} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${GLIB_COMPILE_RESOURCES} ARGS --generate-source --target=${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C} {NEW} VERBATIM MAIN_DEPENDENCY ${GRESOURCE_XML}
DEPENDS ${GRESOURCE_DEPENDENCIES} # <-- Here lies the problem ) add_custom_target( dummy-resource DEPENDS ${GRESOURCE_C}
)
add_executable(${PROJECT_NAME} dummy.c) add_dependencies(${PROJECT_NAME} dummy-resource)
dummy.gresource.xml.in
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource>
<!-- touch foo.glade && touch bar.glade -->
<file>foo.glade</file>
<file>bar.glade</file>
</gresource>
</gresources>
El muñeco puede ser hola mundo por ahora.
La lista no está expandida en la parte anterior DEPENDE. Pero si escribo manualmente todas las dependencias, funciona. ¿Hay alguna forma de lograr el comportamiento que quiero?
Respuestas
La fuente de la causa es el valor de salida GRESOURCE_DEPENDENCIESque obtuvimos deexecute_process()
Intente imprimir su longitud real como una lista. ¡Conseguiremos talla 1!
Pero la cadena impresa usando message(${GRESOURCE_DEPENDENCIES})es tan convincente:
foo.glade
bar.glade
¡Pero esa salida es incorrecta! Solo obtenemos ese tipo de salida si foreach()se usa loop junto con message(). Sin bucle, una lista impresa usando solo message(), la salida correcta sale así:
foo.gladebar.glade
El remedio para esto es simple:
- Úselo
string(REPLACE "\n" ";" ...)para convertir nuestro valor de cadena en una lista - Saque el último elemento porque es solo un
\ncarácter de espacio en blanco - Gracias a los comentarios anteriores Establecer
GRESOURCE_DEPENDENCIEScomo variable persistente
Guión corregido
cmake_minimum_required(VERSION 3.15)
project(dummy LANGUAGES C)
find_program(GLIB_COMPILE_RESOURCES NAMES glib-compile-resources REQUIRED)
set(GRESOURCE_C dummy.gresource.c)
set(GRESOURCE_XML dummy.gresource.xml)
set(GRESOURCE_XML_IN dummy.gresource.xml.in)
set(GRESOURCE_DEPENDENCIES CACHE INTERNAL "GResource dependencies for dummy")
set(OLD ${CMAKE_CURRENT_SOURCE_DIR}/${GRESOURCE_XML_IN}) set(NEW ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_XML}) if(NOT EXISTS ${NEW} OR (${OLD} IS_NEWER_THAN ${NEW}))
configure_file(${GRESOURCE_XML_IN} ${GRESOURCE_XML})
execute_process(
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${GLIB_COMPILE_RESOURCES} --generate-dependencies ${GRESOURCE_XML} OUTPUT_VARIABLE GRESOURCE_DEPENDENCIES ) # OUTPUT_VARIABLE is not a list but a single string value with newlines # Convert it to a list and pop out the last newline character string(REPLACE "\n" ";" GRESOURCE_DEPENDENCIES ${GRESOURCE_DEPENDENCIES})
list(POP_BACK GRESOURCE_DEPENDENCIES)
endif()
add_custom_command(
OUTPUT ${GRESOURCE_C} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${GLIB_COMPILE_RESOURCES} ARGS --generate-source --target=${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C} ${NEW}
VERBATIM
MAIN_DEPENDENCY ${GRESOURCE_XML} DEPENDS ${GRESOURCE_DEPENDENCIES}
)
add_custom_target(
dummy-resource
DEPENDS ${GRESOURCE_C} ) add_executable(${PROJECT_NAME} dummy.c)
add_dependencies(${PROJECT_NAME} dummy-resource)