2012-11-20 7 views
8

Ich habe eine Frage zu CMake, die hier häufig gestellt wird, aber keine der Antworten scheint mein Problem zu lösen.cmake, add_custom_command mit Abhängigkeiten aus einem anderen Verzeichnis

Im details Unterverzeichnis gibt es ein CMakeLists.txt, die enthält:

add_custom_command(OUTPUT part.out 
        COMMAND foo --input=part.src --output=part.out 
        DEPENDS part.src) 

add_custom_target(part_out 
        DEPENDS part.out) 

Im Hauptverzeichnis ein CMakeLists.txt dort die part.out zur Erzeugung eines andere Datei verwendet wird:

add_custom_command(OUTPUT full.out 
        COMMAND bar --input=./details/part.out --output=full.out) 

add_custom_target(full_out 
        DEPENDS full.out) 

Das Problem ist, dass Ich möchte 3 Dinge hier passieren:

  1. wenn part.out nicht vorhanden es
  2. wenn part.out veralten erzeugt werden muss, ist (part.src neuer ist als part.out) Ich will es
  3. wenn full.out regeneriert werden veraltet ist (part.out neuer ist als full.out, oder full.out desn't existieren) ich habe es (wieder) erzeugt

So sein wollen, wenn ich hinzufügen DEPENDS ./details/part.out zu add_custom_command(OUTPUT full.out) werde ich Punkte erreichen 2 und 3, jedoch nicht mehr als 1 Punkt, denn wenn ich part.out löschen und dann habe ich Rufen SieanIch erhalte eine Fehlermeldung, dass es keine Regel zu machen gibt ./details/part.out (wie es eine Regel aus einem anderen Verzeichnis ist).

Wenn ich DEPENDS full_out-add_custom_command(OUTPUT full.out) hinzuzufügen oder zu add_custom_target(full_out) werde ich erreichen Punkte 1 und 2, aber nicht mehr als 3, denn selbst wenn part.out regeneriert wurde, wird ein full.out nicht regeneriert werden, da es nicht auf der part.out Datei abhängt selbst.

Also, wie kann ich beide Szenarien verbinden? Ich habe darüber nachgedacht, beide DEPENDS hinzuzufügen, aber woher weiß ich, ob das immer funktioniert? Ich meine, in einem solchen Fall spielt die Reihenfolge der Builds eine Rolle.

Antwort

22

CMake docs for add_custom_target:

standardmäßig nichts hängt von der benutzerdefinierten Ziel. Verwenden Sie ADD_DEPENDENCIES , um Abhängigkeiten zu oder von anderen Zielen hinzuzufügen.

Deshalb schlage ich zu "connect" die Ziele mit

ADD_DEPENDENCIES(full_out part_out) 

EDIT: Beispiel Arbeiten

Wie sich herausstellte, um die Quelldatei Eigenschaften für part.out festlegen müssen

Hier ist mein Arbeitsbeispiel (versucht unter Windows mit VS2008):

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8) 
project(full) 

add_subdirectory(details) 

add_custom_command(OUTPUT full.out 
       COMMAND ${CMAKE_COMMAND} -E copy ./details/part.out full.out 
       DEPENDS details/part.out 
       ) 


add_custom_target(full_out 
       DEPENDS full.out details/part.out details/part.src 
      ) 


set_source_files_properties(details/part.out PROPERTIES GENERATED TRUE) 


add_dependencies(full_out part_out) 

details/CMakeLists.txt:

cmake_minimum_required(VERSION 2.8) 
project(part) 

add_custom_command(OUTPUT part.out 
       COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/part.src part.out 
       DEPENDS part.src) 

add_custom_target(part_out 
       DEPENDS part.out) 

Dieses Beispiel arbeitete für alle Ihre 3 genannten Fällen.

+1

ok, ich weiß, wie man Ziele verbindet. Problem ist, wie die Ausgabe eines custom_command wiederhergestellt wird, wenn sich eine Datei (die ein Ergebnis eines anderen benutzerdefinierten Befehls ** aus einem anderen Verzeichnis ist **) ändert –

+1

@ MichałWalenciak Hm, ich sehe. Siehe meine erweiterte Antwort für eine Lösung. –

+0

thx, jetzt ist es in Ordnung :) –

Verwandte Themen