2016-09-15 10 views
-1

Das folgende ist das mein Szenario. Ich habe eine Top-Level CMakeList.txt und weitere 2 interne CMakeList.txt. In CMake auf oberster Ebene habe ich 3 benutzerdefinierte Ziele, die copy, build, copyandbuild sind. Wie der Name angibt, kopiert make copy die Quellverzeichnisse (d. H. Dir1, dir2) nach $ {CMAKE_SOURCE_DIR}. make build erstellt libs und ausführbare Dateien. make copyandbuild (kopieren + bauen).Wie man cmake Ziele neu lädt

Die Ausführung von cmake .. vom Build-Verzeichnis wird erfolgreich abgeschlossen.

Wenn ich laufen make copyandbuild es ist das Kopieren auf $ {CMAKE_SOURCE_DIR} aber zum Zeitpunkt der Build ist es Fehler zeigt, dass

No rule to make target `dir1/libmylib.so', needed by `CMaketargetdbuild'. Stop 
  • MyProject
    • dir1
      • CMakeLists. txt
    • dir2
      • CMakeLists.txt
    • CMakeLists.txt

Es funktioniert, wenn ich Befehle in der unten angegebenen Reihenfolge auszuführen.

  • cmake ..
  • make copyandbuild
  • cmake ..

Meine Forderung ist es sollte Cmake läuft mit heraus bauen funktioniert und wieder machen zu bauen als copyandbuild tun die gleiche Arbeit.

Top Level CMakeLists.txt:

cmake_minimum_required(VERSION 2.6) 

    cmake_minimum_required(VERSION 2.6) 
    set(RE_BUILD make rebuild_cache) 
    set(OUTPUT_DIR ${CMAKE_SOURCE_DIR}/../) 


    if(EXISTS ${CMAKE_SOURCE_DIR}/dir1) 
    message(WARNING "Found dir1 dir") 
    add_subdirectory(dir1 EXCLUDE_FROM_ALL) 
    else() 
    message(WARNING "Couldn't find dir1 directory ") 
    endif() 


    if(EXISTS ${CMAKE_SOURCE_DIR}/dir2) 
    add_subdirectory(dir2 EXCLUDE_FROM_ALL) 
    else() 
    message(WARNING "Couldn't find dir2 directory") 
    endif() 

    set(MOVE_LIB_COMMAND mv src/myapp . && mv dir1/mylib .) 
    set(COPY_COMMAND cp -r ../sourceCode1 ../dir1 && cp -r ../sourceCode2 ../dir2) 

    set(CLEAN_DIR1_COMMAND cmake -E remove_directory ${CMAKE_SOURCE_DIR}/dir1) 
    set(CLEAN_DIR2_COMMAND cmake -E remove_directory ${CMAKE_SOURCE_DIR}/dir2) 

    set(SET_SLEEP sync) 

    #Copy command 
    add_custom_target(
    copy ${COPY_COMMAND} 
    COMMAND ${RE_BUILD} 
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 
) 
    #Compilation 
    add_custom_target(
    build 
    COMMAND ${MOVE_LIB_COMMAND} 
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 
    DEPENDS mylib myapp 
) 

    #copy and compile 
    add_custom_target(
    copyandbuild 
    COMMAND ${MOVE_LIB_COMMAND} 
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 
    DEPENDS copy mylib myapp 
) 

    add_custom_command(TARGET copy POST_BUILD 
       COMMAND ${SET_SLEEP} 
) 
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11") 

dir1 CMake ist:

cmake_minimum_required(VERSION 2.6) 

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11") 


include_directories(
${MY_APP_INCLUDE_DIRS} 
) 

link_directories(
${MY_APP_LIBDIR} 
) 

add_library(mylib 
SHARED 
com/*.cpp 
) 
target_link_libraries(mylib myapp_lib) 

dir2 CMake ist:

cmake_minimum_required(VERSION 2.6) 

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11") 
include_directories(
${MY_APP_INCLUDE_DIRS} 
) 
link_directories(
${MY_APP_LIBDIR} 
) 
+3

können Sie den Inhalt der CmakeLists.txt in einer abgespeckten Art und Weise teilen? – Hayt

+2

Bitte säubern Sie Ihr Code-Snippet: machen Sie Variablen konsistent (z. B. setzen Sie die Variable 'RE_BUILD_COMMAND', verwenden Sie aber' RE_BUILD'), entfernen Sie Definitionen von Variablen, die nicht im Snippet verwendet werden. So weit ich aus dem Code verstehe, erwarten Sie die Option DEPENDS des [add_custom_target] (https://cmake.org/cmake/help/v3.6/command/add_custom_target.html), um Abhängigkeiten von anderen * Zielen * hinzuzufügen. Aber es fügt tatsächlich ** Abhängigkeiten von Dateien ** hinzu. Um Abhängigkeiten zwischen Zielen hinzuzufügen, verwenden Sie den Befehl [add_dependencies] (https://cmake.org/cmake/help/v3.6/command/add_dependencies.html#command:add_dependencies). – Tsyvarev

Antwort

2

Sie verwenden CMake in einer Weise, dass seine richtige verhindert Funktion. Durch den expliziten Aufruf von Shell-Befehlen an vielen Stellen können Sie, wenn Sie CMake-integrierte Funktionen verwenden können, CMake jeglichen Kontext rauben, den es zum Erstellen Ihrer Programme verwenden könnte. Auch die Verwendung von Platzhaltern wie *.cpp in CMake gilt als schlechte Übung. Und Sie haben eine Reihe von doppelten Anweisungen - Sie brauchen nicht cmake_minimum_required() oder setzen Compiler-Flags anders als auf der obersten Ebene.

Kurz gesagt, Ihre CMakeLists.txt auf der obersten Ebene sollte wie folgt aussehen:

cmake_minimum_required(VERSION 2.6) 

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11") 

add_subdirectory(dir1 EXCLUDE_FROM_ALL) 

Sie sollten nicht Quelldateien kopieren um müssen - nur um sie aus bauen, wo sie sind, zum Beispiel Ihre dir1/CMakeLists.txt Macht be:

add_library(mylib 
    SHARED 
    sourceCode1/mylib.cpp 
) 

Halten Sie es einfach. Lass es funktionieren. Stellen Sie dann Fragen, wenn Sie fehlende Funktionen hinzufügen müssen.

+0

Danke! für Sie Vorschläge, eigentlich habe ich das Kopieren nur für den einfachen Verständnis Zweck verwendet, in Echtzeit werden dir1 und dir2 aus einigen externen Anwendungen generiert werden.Nach der Generierung ist mein Copyandbuild-Befehl in der Lage, den generierten Code zu kompilieren. – venkat2010

+0

@ venkat2010: Dann sollten Sie Ihre Frage in ein voll funktionierendes, aber minimales Beispiel umformulieren. Da wir Ihren Code-Generator nicht haben, könnten Sie ein einfaches 'bash'-Skript verwenden, um eine .cpp-Datei oder was auch immer zu schreiben. –

Verwandte Themen