Cmake命令之a(chǎn)dd_subdirectory介紹

  • 命令格式

    add_subdirectory (source_dir [binary_dir] [EXCLUDE_FROM_ALL])
    添加一個(gè)子目錄并構(gòu)建該子目錄。

  • 命令解析

    • source_dir
      必選參數(shù)。該參數(shù)指定一個(gè)子目錄,子目錄下應(yīng)該包含CMakeLists.txt文件和代碼文件。子目錄可以是相對路徑也可以是絕對路徑,如果是相對路徑,則是相對當(dāng)前目錄的一個(gè)相對路徑。
    • binary_dir
      可選參數(shù)。該參數(shù)指定一個(gè)目錄,用于存放輸出文件。可以是相對路徑也可以是絕對路徑,如果是相對路徑,則是相對當(dāng)前輸出目錄的一個(gè)相對路徑。如果該參數(shù)沒有指定,則默認(rèn)的輸出目錄使用source_dir
    • EXCLUDE_FROM_ALL
      可選參數(shù)。當(dāng)指定了該參數(shù),則子目錄下的目標(biāo)不會被父目錄下的目標(biāo)文件包含進(jìn)去,父目錄的CMakeLists.txt不會構(gòu)建子目錄的目標(biāo)文件,必須在子目錄下顯式去構(gòu)建。例外情況:當(dāng)父目錄的目標(biāo)依賴于子目錄的目標(biāo),則子目錄的目標(biāo)仍然會被構(gòu)建出來以滿足依賴關(guān)系(例如使用了target_link_libraries)

??此外需要注意的是,因?yàn)閍dd_subdirectory增加的構(gòu)建子目錄,CMake構(gòu)建工程會自動將該子目錄添加到編譯和鏈接的搜索目錄中,以保證整個(gè)構(gòu)建工程能滿足依賴,這也是為什么使用add_subdirectory后不需要將子文件夾加入到頭文件或庫文件搜索目錄也能搜索到子目錄的頭文件或庫文件。

  • 舉例說明

    目錄結(jié)構(gòu)及說明如下:

    ├── CMakeLists.txt????#父目錄的CMakeList.txt
    ├── main.cpp????#源文件,包含main函數(shù)
    ├── sub????#子目錄
    ?└── CMakeLists.txt????#子目錄的CMakeLists.txt
    ?└── test.h????#子目錄頭文件
    ?└── test.cpp????#子目錄源文件
    ?

    子目錄sub 下的test.cpp定義了一個(gè)函數(shù)test(),將輸入?yún)?shù)打印出來,相應(yīng)的頭文件test.h則對test()進(jìn)行聲明,CMakelists.txt則將sub下的源文件編譯成庫文件。

    //  sub/test.cpp  
    #include "test.h"
    #include <iostream>
    
    void test(std::string str)
    {
        std::cout << str << std::endl;
    }
    
    //  sub/test.h
    #include <string>
    
    void test(std::string str);
    
    # sub/CMakeLists.txt
    cmake_minimum_required(VERSION 3.10.2)
    project(sub)
    add_library(sub test.cpp)
    
    • 場景1:父目錄CMakeLists.txtadd_subdirectory 只指定了source_dir
    # 父目錄下的CMakeLists.txt
    cmake_minimum_required(VERSION 3.10.2)
    project(test)
    
    add_subdirectory(sub) 
    

    在父目錄下調(diào)用cmake .構(gòu)建之后,在sub目錄下會出現(xiàn)libsub.a庫,說明當(dāng)不指定binary_dir,輸出目標(biāo)文件就會放到source_dir目錄下。

    • 場景2:父目錄CMakeLists.txtadd_subdirectory 指定了source_dirbinary_dir
    # 父目錄下的CMakeLists.txt
    cmake_minimum_required(VERSION 3.10.2)
    project(test)
    
    add_subdirectory(sub output) 
    

    在父目錄下調(diào)用cmake .構(gòu)建之后,在output目錄下會出現(xiàn)libsub.a庫,sub目錄下則沒有libsub.a。說明當(dāng)指定binary_dir,輸出目標(biāo)文件就會放到binary_dir目錄下。

    • 場景3:父目錄CMakeLists.txtadd_subdirectory 指定了EXCLUDE_FROM_ALL選項(xiàng)。
    # 父目錄下的CMakeLists.txt
    cmake_minimum_required(VERSION 3.10.2)
    project(test)
    
    add_subdirectory(sub output EXCLUDE_FROM_ALL) 
    add_executable(test main.cpp)
    

    在父目錄下調(diào)用cmake .構(gòu)建之后,在output目錄或sub目錄下不會出現(xiàn)libsub.a庫,說明當(dāng)指定EXCLUDE_FROM_ALL選項(xiàng),子目錄的目標(biāo)文件不會生成。

    • 場景4:父目錄CMakeLists.txtadd_subdirectory 指定了EXCLUDE_FROM_ALL選項(xiàng),且父目錄的目標(biāo)文件依賴子目錄的目標(biāo)文件。
    # 父目錄下的CMakeLists.txt
    cmake_minimum_required(VERSION 3.10.2)
    project(test)
    
    add_subdirectory(sub output EXCLUDE_FROM_ALL) 
    add_executable(test main.cpp)
    target_link_libraries(test sub)
    

    在父目錄下調(diào)用cmake .構(gòu)建之后,在output目錄出現(xiàn)libsub.a庫,說明即使指定EXCLUDE_FROM_ALL選項(xiàng),當(dāng)父目錄目標(biāo)文件對子目錄目標(biāo)文件存在依賴關(guān)系時(shí),子目錄的目標(biāo)文件仍然會生成以滿足依賴關(guān)系。

?
?最后,以一個(gè)完整的例子來結(jié)束本文(sub目錄下的CMakeList.txttest.htest.cpp等文件內(nèi)容如上文所示,沒有變化),父目錄下的main.cppCMakeList.txt如下:

# 父目錄下的CMakeLists.txt
cmake_minimum_required(VERSION 3.10.2)
project(test)

include_directories(sub)
add_subdirectory(sub output) 

add_executable(test main.cpp)
target_link_libraries(test sub)
# 父目錄下的main.cpp
#include "test.h"
#include <iostream>

int main(int argc, char** argv)
{
    std::cout << "In main..." << std::endl;
    test("hello, world!");
    return 0;
}
# 輸出
> cmake --build .
Scanning dependencies of target sub
[ 25%] Building CXX object output/CMakeFiles/sub.dir/test.cpp.o
[ 50%] Linking CXX static library libsub.a
[ 50%] Built target sub
Scanning dependencies of target test
[ 75%] Building CXX object CMakeFiles/test.dir/main.cpp.o
[100%] Linking CXX executable test
[100%] Built target test
>./test
In main...
hello, world!

附錄:參考資料

  1. https://cmake.org/cmake/help/latest/command/add_subdirectory.html
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。