2010-10-24 3 views
12

Sto cercando di ottenere un file prodotto da un add_custom_command in una directory per essere una dipendenza di un add_custom_command in un'altra directory.cmake: alle dipendenze add_custom_command

Nella prima directory (lib/core) Ho un comando build che assomiglia a questo:

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") 

Nel secondo elenco, ho un comando che utilizza l'output di questo 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}") 

Tuttavia, quando provo ad installare, ottengo il seguente errore:

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

una cosa strana quello che vedo è che il percorso nel messaggio di errore è un percorso relativo, non assoluto, nonostante io sappia che $ {PROJECT_BINARY_DIR} è un percorso completo e corretto. Non so se questo è un problema o solo una stranezza del fare.

Inoltre ho provato a fare un target di alto livello per la libreria libcore, nella directory lib/core:

add_custom_target(libcore DEPENDS libcore.bc libcore.deps) 

E poi usando che nella clausola DEPENDS. La cosa strana è che funziona la prima volta che fai una build pulita, ma dà un errore in ogni build successiva. In ogni caso, la mia comprensione è che DEPENDS dovrebbe funzionare solo per le dipendenze dei file, quindi questa non sembra la soluzione corretta. (Come si dispone di un comando personalizzato che dipende da un obiettivo di livello superiore, quindi?)

Ho anche provato a mettere percorsi assoluti in tutto il mondo, nessun effetto.

risposta

7

La documentazione CMake dice il seguente sul parametro Dipende:

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.

Perciò penso che si dovrà definire un obiettivo utilizzando add_custom_target e dipendono da questo.

La documentazione per 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).

Quindi si dovrà utilizzare add_custom_command e add_custom_target come segue:

  1. Nella prima directory che genera il file bc si fa

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

  2. Nella seconda directory che fai

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

+4

Sfortunatamente, questa soluzione non funziona. (Mi rendo conto che è probabilmente una risposta disperata dopo quasi un anno.) Per quanto posso dire, il parametro DEPENDS di add_custom_command DEVE essere una dipendenza a livello di file - anche se i documenti dicono che una dipendenza a livello di destinazione * nello stesso directory * funzionerà, infatti ho provato diverse permutazioni negli ultimi 11 mesi e nessuna di esse funziona. Cioè, se definisco il target personalizzato "foo" nella stessa directory, e poi dico DEPENDS "foo", verrà semplicemente segnalato "nessuna regola per rendere target 'foo' ..." – Talin

+0

@Talin Quindi questo sembra essere un bug, c'è un problema segnalato per questo in [CMake bugtracker] (http://www.cmake.org/Bug/my_view_page.php)? – lef

0

Non credo add_custom_target funzionerà per quello che voglio. Secondo i documenti cmake, una destinazione personalizzata creata da add_custom_target è sempre considerata obsoleta ed è sempre costruita.

Il problema è che sto cercando di prelevare l'output da uno add_custom_command e inserirlo nell'input di un altro add_custom_command in una directory diversa.Voglio solo che ciò accada se il file sorgente originale non è aggiornato: se avessi usato add_custom_target, l'output sarebbe sempre stato ricostruito anche se il file sorgente non fosse stato modificato. Dato che ci sono centinaia di questi file sorgente, questo renderebbe la costruzione molto lenta.

Ecco cosa sto cercando di fare: Ho un programma che genera un file .bc (codice LLVM) dato un file sorgente. Ci sono molti di questi file sorgenti, che creano molti file .bc.

Un secondo programma trasforma tutti i file .bc in un singolo file .obj (oggetto ELF). Quindi le fasi di trasformazione simile a questa:

file di codice
source file -> .bc  (via add_custom_command) 
    .bc   -> .obj (via add_custom_command) 
    .obj  -> .exe (via add_executable) 

la fonte originale sono in directory differenti, perché sono le librerie di classi - io non voglio avere a mettere tutto il codice per ogni libreria di classi nella stessa directory.

3

Questa è una mancata risposta, ma un chiarimento a uno dei tuoi answers sopra.

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

IMO, i documenti cmake dovrebbero dire invece:

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

Ciò significa che se tutti i vostri obiettivi sono contrassegnati come EXCLUDE_FROM_ALL, e si dispone di add_custom_target comandi che creano nuovi obiettivi, e si digita make dalla riga di comando senza target specificati, gli obiettivi aggiunti con add_custom_target sono non creati. Ma se li si scrive esplicitamente sulla riga di comando make, allora vengono creati. Inoltre, c'è la parola chiave ALL che è possibile specificare per il add_custom_target per forzare quelli da costruire come parte della regola all, che credo significhi quando make viene eseguito senza argomenti.

+0

Sono d'accordo. Le parole "è sempre costruito" non è letteralmente vero. –