2017-05-30 2 views
0

Ich bin ein benutzerdefiniertes Feature beitragen - sagen, MyFeature - zu einem Projekt, das CMake verwendet und separate Quell- und Build-Verzeichnisse hat. MyFeature besteht aus einer einzelnen Binärdatei. (MyFeature ist in der Tat eine benutzerdefinierte Simulink-Bibliothek, also muss ich MATLAB aufrufen, um es zu erstellen - die wichtige Sache hier ist, dass das Erstellen des Objekts nicht GCC oder die anderen Standard-Build-Tools, die CMake standardmäßig verwendet.) Also Ich habe eine spezielle Regel, um das Objekt zu bauen - sagen wir myRule. Ich will machen myrule nur ausgeführt werden, wenn (a) MyFeature nicht vorhanden ist, oder (b) die eine Quelldatei, auf dem MyFeature abhängt - sagen wir, MySource --is neuer als die derzeit -existing MyFeature. Eine kleine zusätzliche Falte ist, dass ich nur wirklich MyFeature im Quellbaum brauche, wo myRule normalerweise es platziert. Wie kann ich das alles erreichen?Benutzerdefiniertes Objekt mit Abhängigkeiten in CMake

ich auch nicht add_executable oder add_library, soweit ich kann sagen können, weil sie dazu bestimmt sind eng für Objekte, die Sie den GCC bauen (oder sonst bereits konfiguriert) Toolchain. Ich kann add_custom_target nicht verwenden, weil das resultierende Ziel immer veraltet ist. Bisher habe ich einige Fortschritte mit einer Kombination aus add_custom_target und add_custom_command gemacht, wie folgt:

add_custom_target(fakeTarget 
    DEPENDS MyFeature) 

add_custom_command(OUTPUT MyFeature 
    COMMAND myRule && touch ${CMAKE_CURRENT_BINARY_DIR}/MyFeature 
    DEPENDS mySource) 

add_dependencies(targetThatAlwaysRuns fakeTarget) 

Der Befehl eine leere MyFeature Datei im Build-Baum zu schaffen scheint ausreichend zu fälschen make in nicht umbauen, wenn die echte MyFeature existiert (im Quellbaum), die eines meiner Ziele erreicht. Sobald diese gefälschte Datei jedoch existiert, selbst wenn ich MySource in der Quellstruktur aktualisiere, wird make nicht wiederhergestellt MyFeature. Hier stecke ich fest. Es scheint besonders rätselhaft, weil ich in der CMakeFiles Innereien sehen kann, dass es ein Ziel für MyFeature gibt, die tatsächlich MySource (mit dem richtigen Pfad - im Quellbaum!) Als Abhängigkeit auflistet. Wenn ich versuchen würde, diese Situation mit einem viel einfacheren (Spielzeug-) Makefile in einem einzigen Verzeichnis zu replizieren, würde ich, wenn ich eine der Quelldateien, von denen das Ziel abhängt, aktualisieren, selbst wenn die Zielausgabedatei bereits existiert, machen machen das Richtige - es wird das Objekt aus der aktualisierten Quelle neu erstellen und dann das Gesamtziel neu erstellen. Warum ist das Build-Verhalten in dieser Situation anders? Und was kann ich tun, um das Ziel (b) zusammen mit dem Ziel (a) zu erreichen? Vielen Dank!

+0

Unter der Annahme 'add_custom_rule' meinen Sie 'add_custom_command', dies sollte funktionieren. Versuchen Sie, absolute Pfade in den Optionen * DEPENDS * und * OUTPUT * zu verwenden. "Eine kleine zusätzliche Falte ist, dass ich MyFeature nur im Quellbaum brauche" - nichts hindert Sie daran, eine Datei im Quellbaum zu erstellen. – Tsyvarev

+0

Hoppla! Ja, ich meinte add_custom_command - habe bearbeitet um das zu beheben. Es stimmt, nichts hindert mich daran, eine Datei im Quellbaum zu erstellen. Ich habe den Grund für meinen Hack erklärt, eine leere Datei in den Build-Baum zu legen. CMake _does_ hindert mich daran, ein Ziel im Quellbaum zu definieren, daher kann die Ausgabedatei in add_custom_command auch nicht im Quellbaum enthalten sein. –

+0

Das Hinzufügen des absoluten Pfades zur Option * DEPENDS * in add_custom_command funktioniert! Vielen Dank! –

Antwort

0

Wie Tsyvarev in seinem Kommentar vorgeschlagen, alles, was ich tun musste, war die HäNGT Abhängigkeit mit einem absoluten Pfad angeben:

add_custom_target(fakeTarget 
    DEPENDS MyFeature) 

add_custom_command(OUTPUT MyFeature 
    COMMAND myRule && touch ${CMAKE_CURRENT_BINARY_DIR}/MyFeature 
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/mySource) 

add_dependencies(targetThatAlwaysRuns fakeTarget) 

jedoch nun ein Benutzer annehmen, den realen MyFeature aus der löscht Source-Baum und läuft dann Make wieder. Make wird nicht regeneriert MyFeature, weil die gefälschte MyFeature ist immer noch in der Build-Struktur vorhanden. Wie kann ich dieses Problem überwinden?

Verwandte Themen