2013-04-12 18 views
17

laufen Ich habe einen benutzerdefinierten BefehlCMake: Wie ein add_custom_command vor alles andere

add_custom_command(
    OUTPUT config.h 
    PRE_BUILD 
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/mk_config_h.py ${CMAKE_CURRENT_BINARY_DIR}/config.h 
) 

Ich versuche, es zu laufen, bevor alles andere und ich Unix-Makefiles generieren.

Allerdings wird PRE_BUILD nur für VS2010 unterstützt, was bedeutet, dass config.h vor dem Verknüpfen erstellt wird.

Wie mache ich einen benutzerdefinierten Befehl, bevor CMake beginnt, Quellen zu kompilieren.

+1

wird die Ausgabedatei von Ihrem benutzerdefinierten Befehl (dh config.h) als Quelldatei in einem anderen CMake Ziel verwendet (dh in der Liste der Quellen über 'add_executable' bestanden haben oder 'add_library')? In diesem Fall sollten Sie sich keine Gedanken über die Ausführungsreihenfolge machen müssen - CMake wird den benutzerdefinierten Befehl bei Bedarf aufrufen. – Fraser

Antwort

28

Sie sollten add_custom_target statt und add_dependencies benutzen, um Ihr normales Ziel davon abhängen machen:

add_custom_target(
    myCustomTarget 
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/mk_config_h.py ${CMAKE_CURRENT_BINARY_DIR}/config.h 
) 
add_dependencies(myTarget myCustomTarget) 

Damit soll sichergestellt werden, dass der Befehl vor dem Kompilieren die Quellen von myTarget ausgeführt wird.

+0

Es hat eine Weile gedauert, dass add_custom_target zum Ausführen einer ausführbaren Datei viel besser ist als add_custom_command. Danke für diese Lösung! – Anonymous

1

Herkömmliche Build-Systeme, die auf Makefiles basieren, müssen Header nicht als Teil eines Ziels angeben. Darüber hinaus wird das Hinzufügen von Headern zum Ziel als Antipattern betrachtet. Aber das Generieren eines Headers ist eine Ausnahme von dieser Regel.

http://voices.canonical.com/jussi.pakkanen/2013/03/26/a-list-of-common-cmake-antipatterns/

Sie sollten Ihre ${CMAKE_CURRENT_BINARY_DIR}/config.h als Teil eines anderen compilled Ziel gesetzt. Zum Beispiel:

set(PROGRAM1_SOURCES main_program1.cpp) 
set(PROGRAM1_HEADERS main_program1.h ${CMAKE_CURRENT_BINARY_DIR}/config.h) 
add_executable(program1 ${PROGRAM1_SOURCES} ${PROGRAM1_HEADERS}) 

Damit wird CMake wissen, welche die erzeugte config.h tatsächlich benötigt Ziel und wird die Erzeugung von Befehlen in einem rechten Erstellungsschritte einfügen können.

Auch finden Sie ein Beispiel an https://cmake.org/cmake-tutorial/#s5

+2

Sie benötigen Header, wenn Sie Code-Analyse von den verschiedenen IDEs arbeiten möchten. – ZeroPhase

+0

@zerophase, stimme ich zu. Projektdateien für IDE benötigen häufig einen Verweis auf alle Dateien des Projekts. Aber cmake ist in der Lage, das Projekt ohne Header-Dateien zu erstellen. – Piroxiljin

+0

Oh sicher. Normalerweise müssen Header hinzugefügt werden, um verschiedene Endbenutzer zu unterstützen. – ZeroPhase

Verwandte Themen