2015-07-21 88 views
1

可以說我有一個項目與兩個獨立的子項目。如果我正確理解了cmake,那麼這個想法應該是讓一個根CMakeLists.txt定義一個project(...),然後使用add_subdirectory(...)來包含子項目。每個子項目都有自己的CMakeLists.txt定義自己的項目。這樣,項目可以一起構建(使用root cmake文件)或單獨構建(使用子項目cmake文件)。在哪裏設置CMAKE_CONFIGURATION_TYPES項目與子項目

我現在想更改CMAKE_CONFIGURATION_TYPES。我是否應該在根CMakeLists.txt或每個子項目中或兩者中執行此操作?

在根中更改它意味着單獨構建子項目會提供錯誤的配置類型;其他選項將複製cmake代碼。我想我在這裏錯過了一些東西。

+0

爲什麼您需要更改CMAKE_CONFIGURATION_TYPES,您想如何修改它? –

+0

而不是釋放,調試和RelWithDebugInfo,我想有釋放,調試和配置文件。 – Flogo

+1

我現在這樣做: '設置(CMAKE_CONFIGURATION_TYPES 「調試;釋放;簡介」) 集(CMAKE_CONFIGURATION_TYPES 「$ {CMAKE_CONFIGURATION_TYPES}」 CACHE STRING 「支持的配置清單。」) mark_as_advanced(CMAKE_CONFIGURATION_TYPES) 如果(NOT CMAKE_BUILD_TYPE) 消息( 「違約釋放構建」) 集(CMAKE_BUILD_TYPE發佈 CACHE STRING 「選擇構建的類型,選項有:$ {CMAKE_CONFIGURATION_TYPES}」 FORCE) ENDIF()' – Flogo

回答

3

將因式分解設置依賴於配置的設置的代碼。在CMakeLists.txt的年初

if(NOT SET_UP_CONFIGURATIONS_DONE) 
    set(SET_UP_CONFIGURATIONS_DONE 1) 

    # No reason to set CMAKE_CONFIGURATION_TYPES if it's not a multiconfig generator 
    # Also no reason mess with CMAKE_BUILD_TYPE if it's a multiconfig generator. 
    if(CMAKE_CONFIGURATION_TYPES) # multiconfig generator? 
     set(CMAKE_CONFIGURATION_TYPES "Debug;Release;Profile" CACHE STRING "" FORCE) 
    else() 
     if(NOT CMAKE_BUILD_TYPE) 
      message("Defaulting to release build.") 
      set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE) 
     endif() 
     set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build") 
     # set the valid options for cmake-gui drop-down list 
     set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;Profile") 
    endif() 
    # now set up the Profile configuration 
    set(CMAKE_C_FLAGS_PROFILE "...") 
    set(CMAKE_CXX_FLAGS_PROFILE "...") 
    set(CMAKE_EXE_LINKER_FLAGS_PROFILE "...") 
endif() 

然後include(..)這個文件:與此內容創建一個文件,說,SetUpConfigurations.cmake

你在哪裏放SetUpConfigurations.cmake兩個選擇,這取決於你如何組織你的項目庫:

  1. 的quick'n'dirty方法:複製並提交此腳本到需要每個項目它。其位置將固定,相對於該項目的CMakeLists.txt。所以你可以包括它,例如,與include(${CMAKE_CURRENT_SOURCE_DIR}/<...>/SetUpConfigurations.cmake)

  2. 守規矩的方式:維護與您的自定義CMake腳本庫,就像這一個。每次生成的cmake命令一個項目的時候,你傳遞的路徑,這個倉庫在CMAKE_MODULE_PATH變量:

    cmake -DCMAKE_MODULE_PATH=<dir-of-cmake-script-repo> ... 
    

在這種情況下,包括與include(SetUpConfigurations)(無.cmake擴展名)的腳本。

約multiconfig發生器是一個多麼注:

XcodeVisual Studio被multiconfig發電機。他們尊重CMAKE_CONFIGURATION_TYPES的值,但CMAKE_BUILD_TYPE沒有效果,因爲在處理CMakeLists.txt時沒有定義具體配置。稍後將在IDE的用戶界面上選擇它。

另一方面,makefile樣式的生成器對CMAKE_CONFIGURATION_TYPES不感興趣。CMAKE_BUILD_TYPE定義了配置。這是當CMakeLists.txt文件處理,但仍然是一個具體的值:從不根據對所CMAKE_BUILD_TYPE價值的任何決定:按預期在multiconfig發電機

if(CMAKE_BUILD_TYPE STREQUAL "Release") # WRONG! 
    .... 
endif() 

你的項目將無法正常工作。

+0

我有另一個後續問題。你說在每個'CMakeLists.txt'的開頭都包含(..)'文件。這是否意味着我必須使用相對包含像'$ {CMAKE_CURRENT_SOURCE_DIR} /../ SetUpConfigurations.cmake'?這意味着我不能僅僅複製我的子目錄並在副本上調用cmake。它不是一個真正的問題,我想除了複製每個子目錄中的文件外,沒有辦法避免它,但只是爲了確定,我想問。 – Flogo

+0

@Flogo,我在這個 –

+0

上擴展了答案,謝謝,我可以補充一點,在Visual Studio中,我使用此代碼重新定義CMAKE_CXX_FLAGS_ 以包含/ MP編譯時間開關,以加強編譯到所有可用的CPU核心 – Lothar

1

當在子項目dir中使用add_subdirectory時,幾乎將所有變量傳播到該子項目中,這與「子項目獨立性」相矛盾。

相反,最好使用execute_process()內部的嵌套cmake調用來構建和安裝子項目。如果要爲頂級項目製作一些子項目的定義,則在安裝子項目時需要「導出」此定義。 This問題/回答帖子介紹,如何做到這一點。

+0

這對我來說似乎是一種解決方法。你有一個鏈接到一個項目的地方嗎?也許我的問題中的措詞也是誤導性的。子項目是獨立的,因爲它們不共享代碼並且不相互鏈接。但編譯和使用它們仍然是常見的情況。我也不介意在層次結構中傳播內容,事實上,我希望向下傳播'CMAKE_CONFIGURATION_TYPES'。最好不需要指定兩次。 – Flogo

+0

@Tsyvarev:嵌套的cmake調用是好東西。但是有一些很常見的情況,add_subdirectory是一個獨立的項目。示例:設想一個由許多內部庫和應用程序庫組成的應用程序套件。每個回購都是在其獨立項目中開發的。然後,這些項目作爲子目錄放入應用程序套件超級項目中,以便能夠在一個IDE解決方案中編輯和構建其源文件。 –

+0

@Flogo:例如,看到cmake文件:https://github.com/euspectre/kedr/blob/master/sources/CMakeLists.txt。在else(KEDR_GEN)下的分支安裝子項目'kedr_gen'。如果你想讓子項目共享一些代碼,把這些代碼放在共享的'.cmake'文件中,並將它包含在子項目中。 @ tamas.kenez:是的,有些情況下,合併子項目更重要,而不是獨立。 – Tsyvarev

相關問題