2010-10-24 13 views
12

Estoy intentando que un archivo producido por un add_custom_command en un directorio sea una dependencia de un add_custom_command en otro directorio.cmake: luchando con las dependencias de add_custom_command

En el primer directorio (lib/núcleo) Tengo un comando de construcción que tiene este aspecto:

add_custom_command(
    OUTPUT libcore.bc 
    COMMAND tartln -filetype=bc -link-as-library -o libcore.bc ${STDLIB_BC_FILES} 
    DEPENDS ${STDLIB_BC_FILES} tartln 
    COMMENT "Linking libcore.bc") 

En el segundo directorio, tengo un comando que utiliza la salida de ese comando:

add_custom_command(OUTPUT ${OBJ_FILE} 
    COMMAND tartln -disable-fp-elim -filetype=obj -o ${OBJ_FILE} ${BC_FILE} 
     "${PROJECT_BINARY_DIR}/lib/core/libcore.bc" 
    MAIN_DEPENDENCY "${BC_FILE}" 
    DEPENDS "${PROJECT_BINARY_DIR}/lib/core/libcore.bc" 
    COMMENT "Linking Tart bitcode file ${BC_FILE}") 

Sin embargo, cuando trato de instalar, me sale el siguiente error:

make[3]: *** No rule to make target `lib/core/libcore.bc', needed by `test/stdlib/ReflectionTest.o'. Stop. 

Una cosa rara que veo es que la ruta en el mensaje de error es una ruta relativa, no absoluta, a pesar del hecho de que sé que $ {PROJECT_BINARY_DIR} es una ruta correcta y completa. No sé si esto es un problema o simplemente una rareza de la marca.

También he intentado hacer un objetivo de nivel superior de la biblioteca libcore, en el directorio lib/núcleo:

add_custom_target(libcore DEPENDS libcore.bc libcore.deps) 

Y luego usar esa en la cláusula depende. Lo extraño de eso es que funciona la primera vez que haces una compilación limpia, pero da un error en cualquier compilación posterior. En cualquier caso, mi entendimiento es que DEPENDS se supone que solo funciona para las dependencias de archivos, por lo que esta no parece ser la solución correcta. (¿Cómo se tiene un comando personalizado que depende de un objetivo de nivel superior, entonces?)

También he intentado poner caminos absolutos en todas partes, sin efecto.

Respuesta

7

La documentación cmake dice lo siguiente acerca del parámetro depende:

The DEPENDS option specifies files on which the command depends. If any dependency is an OUTPUT of another custom command in the same directory (CMakeLists.txt file) CMake automatically brings the other custom command into the target in which this command is built. If DEPENDS specifies any target (created by an ADD_* command) a target-level dependency is created to make sure the target is built before any target using this custom command.

Por lo tanto creo que tendrá que definir un objetivo y usando add_custom_target depender de esto.

La documentación para add_custom_target dice:

Dependencies listed with the DEPENDS argument may reference files and outputs of custom commands created with add_custom_command() in the same directory (CMakeLists.txt file).

por lo que tendrá que utilizar add_custom_command y add_custom_target de la siguiente manera:

  1. En el primer directorio de generar el archivo bc haces

    add_custom_command(OUTPUT libcore.bc ...) # just as in your question add_custom_target (LibCoreBC DEPENDS libcore.bc)

  2. En el segundo directorio que hacer

    add_custom_command (OUT ${OBJ_FILE} DEPENDS LibCoreBC ....)

+4

Lamentablemente, esta solución no funciona. (Me doy cuenta de que probablemente sea una respuesta inútil después de que haya transcurrido casi un año). Por lo que puedo decir, el parámetro DEPENDS de add_custom_command DEBE ser una dependencia de nivel de archivo, aunque los documentos dicen que hay una dependencia de nivel de destino * en el mismo directorio * funcionará, de hecho, probé muchas permutaciones diferentes en los últimos 11 meses, y ninguna de ellas funciona. Es decir, si defino el destino personalizado "foo" en el mismo directorio, y luego digo DEPENDS "foo", simplemente informará "sin reglas para hacer objetivo 'foo' ..." – Talin

+0

@Talin Así que esto parece ser un error, ¿hay algún problema informado sobre esto en [CMake bugtracker] (http://www.cmake.org/Bug/my_view_page.php)? – lef

0

No creo add_custom_target va a trabajar para lo que quiero. De acuerdo con los documentos de cmake, un objetivo personalizado creado por add_custom_target siempre se considera desactualizado y siempre se genera.

El problema es que estoy tratando de tomar la salida de un add_custom_command, y alimentarlo a la entrada de otro add_custom_command en un directorio diferente.Solo quiero que esto suceda si el archivo fuente original está desactualizado; si utilicé add_custom_target, la salida siempre se reconstruirá aunque el archivo fuente no haya cambiado. Dado que hay cientos de estos archivos fuente, esto haría que la construcción fuera muy lenta.

Esto es lo que estoy tratando de hacer: Tengo un programa que genera un archivo .bc (código de bits LLVM) dado un archivo de origen. Hay muchos de estos archivos fuente, que crean una gran cantidad de archivos .bc.

Un segundo programa transforma todos los archivos .bc en un solo archivo .obj (objeto ELF). Por lo que los pasos de transformación se ven así:

archivos de código
source file -> .bc  (via add_custom_command) 
    .bc   -> .obj (via add_custom_command) 
    .obj  -> .exe (via add_executable) 

la fuente original se encuentran en diferentes directorios, ya que son bibliotecas de clases - Yo no quiero tener que poner todo el código para cada biblioteca de clases de la misma directorio.

3

Esto no es una respuesta sino una aclaración a uno de sus answers arriba.

According to the cmake documents, a custom target created by add_custom_target is always considered out of date and is always built.

OMI, los documentos cmake deben decir en su lugar:

A custom target created by add_custom_target is always considered out of date and is always built, but only when requested.

Eso significa que si todos sus objetivos se marcan como EXCLUDE_FROM_ALL, y usted tiene add_custom_target comandos que crean nuevos objetivos, y que escriba make desde la línea de comandos sin objetivos especificados, los objetivos añadidos con add_custom_target son no construidos. Pero si los deletreas en la línea de comandos make explícitamente, entonces están construidos. Además, existe la palabra clave ALL que puede especificar en add_custom_target para forzar que se creen como parte de la regla all, lo que creo que significa cuando make se ejecuta sin argumentos.

+0

Estoy de acuerdo. Las palabras "siempre se construye" no son literalmente verdaderas. –

Cuestiones relacionadas