2016-09-15 63 views
-1

以下是我的方案。我有一個頂級CMakeList.txt和另外兩個內部CMakeList.txt。在頂級cmake我有3個自定義目標是copy,build,copyandbuild。如名稱指定make copy將源目錄(即dir1,dir2)複製到$ {CMAKE_SOURCE_DIR}。 make build創建庫和可執行文件。 make copyandbuild(copy + build)。如何重新加載cmake目標

從build目錄運行cmake ..成功完成。

如果我運行make copyandbuild它複製到$ {CMAKE_SOURCE_DIR},但在構建時它顯示錯誤

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

它正在工作,如果我在下面的順序執行命令。

  • cmake的..
  • 化妝copyandbuild
  • cmake的..
  • 使建立

我的要求是它應該再次出來工作運行cmake並作出構建爲copyandbuild做同樣的工作。

頂級的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的是:

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的是:

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

你能分享一下CmakeLists.txt的內容嗎? – Hayt

+2

請清理你的代碼片段:使變量保持一致(例如,設置變量RE_BUILD_COMMAND,但使用RE_BUILD),刪除片段中未使用的變量的定義。就我所瞭解的代碼而言,你期待[add_custom_target]的DEPENDS選項(https://cmake.org/cmake/help/v3.6/command/add_custom_target.html)添加來自其他*目標*的依賴關係。但它實際上增加了**文件**的依賴關係。要添加目標之間的依賴關係,請使用命令[add_dependencies](https://cmake.org/cmake/help/v3.6/command/add_dependencies.html#command:add_dependencies)。 – Tsyvarev

回答

2

您正在以防止其正確的方式使用的CMake功能。通過在許多地方明確地調用shell命令,當你可以使用CMake內置的特性時,你就會剝奪它可用於構建程序的任何上下文的CMake。另外,在CMake中使用通配符*.cpp被認爲是不好的做法。並且您有許多重複的語句 - 您不需要cmake_minimum_required()或設置編譯器標誌而不是在頂層。

總之,你CMakeLists.txt在頂層應該看起來更像是這樣的:

cmake_minimum_required(VERSION 2.6) 

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

add_subdirectory(dir1 EXCLUDE_FROM_ALL) 

你不應該需要各地複製源文件 - 從他們在哪裏只是建立它們,例如您的dir1/CMakeLists.txt威力成爲:

add_library(mylib 
    SHARED 
    sourceCode1/mylib.cpp 
) 

保持簡單。讓它工作。然後問你是否需要添加缺失的功能。

+0

謝謝!對於你的建議,實際上我在這裏只使用複製只是爲了簡單理解目的,實時dir1和dir2將從一些外部應用程序生成。一旦完成,我的copyandbuild命令應該能夠編譯生成的代碼。 – venkat2010

+0

@ venkat2010:那麼你應該把你的問題改寫成一個完全正常工作但最小的例子。由於我們沒有你的代碼生成器,你可以使用一個簡單的'bash'腳本來編寫一個.cpp文件或其他任何東西。 –