2015-07-21 192 views
8

您有一個CMake啓用的庫項目。您需要在另一個庫或可執行文件中使用它。如何使用CMake查找並鏈接到圖書館?你可以具有以下優選:如何使用CMake查找並使用install-export和find_package鏈接到庫?

  • 寫的鍋爐板代碼儘可能少
  • 解耦鏈接庫的內部細節從消費目標

理想情況下,該使用圖書館應該是這樣的:

add_executable(myexe ...) 
target_link_libraries(myexe mylib) 
+0

[CMake的鏈接到外部庫(可能的重複http://stackoverflow.com/questions/8774593/cmake-link-to-external-圖書館) – usr1234567

回答

18

讓我演示一下在一個具體的例子一個可能的解決方案:

myapp項目

我們有一個可執行的目標myapp。我們將它與mylib鏈接起來,它是在它自己的構建樹中構建的。在myappCMakeLists.txt我們發現並指定mylib作爲myexe依賴:

find_package(mylib REQUIRED) 
... 
add_executable(myexe ...) 
target_link_libraries(myexe mylib) 

讓我們來看看如何設置mylibmyexe構建,使這項工作。

mylib項目

mylib的目錄佈局:

mylib 
- CMakeLists.txt 
- mylib.c 
+ include 
    - mylib.h # single public header 

mylibCMakeLists.txt我們需要創建目標,並指定其源文件:

add_library(mylib mylib.c include/mylib.h) 

公衆標題mylib.h將包含爲#include "mylib.h"既通過mylibmylib客戶:

  • mylib本身建於mylib的CMake的項目(如測試)等目標需要找到include/mylib.hmylib源代碼樹的mylib
  • 客戶建立他們的自己的項目(如myexe)需要在的安裝位置找到include/mylib.h

CMake的允許我們指定既包括mylib路徑:

target_include_directories(mylib PUBLIC 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> 
    $<INSTALL_INTERFACE:include>) 

我們在這裏使用PUBLIC選擇,因爲需要的mylib公共接口上這個頭。使用PRIVATE作爲mylib內部的包含路徑。

INSTALL_INTERFACE指定相對於安裝根目錄的路徑,即CMAKE_INSTALL_PREFIX。要實際安裝公用標頭:

install(FILES include/mylib.h DESTINATION include) 

我們還需要安裝庫本身和所謂的配置模塊及相關文件。配置模塊是消耗項目將使用的文件,例如myapp來查找mylib並獲取與其鏈接所需的所有參數。它類似於pkg-config.pc文件。

我們需要兩個相關的install命令。第一招:覆蓋所有標準安裝靜態庫,dll的和so的位置所需要的目的地

install(TARGETS mylib 
    EXPORT mylib-targets 
    ARCHIVE DESTINATION lib 
    LIBRARY DESTINATION lib 
    RUNTIME DESTINATION bin) 

列表。如果你確定你的庫只能作爲一個靜態庫被構建,那麼一個DESTINATION lib就可以做到。

有趣的部分是EXPORT選項。它將目標列表(目前只有mylib)分配給標識mylib-targets。該標識將在未來命令用來生成和消費項目中安裝一些特殊的文件,這使find_package(mylib)工作:

install(EXPORT mylib-targets 
    FILE mylib-config.cmake 
    DESTINATION lib/cmake/mylib) 

此命令生成多個文件:

  • 一個文件,每個構建配置(Debug,Release等),它描述了庫文件和依賴於配置的參數
  • 一個描述配置無關參數的文件,也包括所有依賴於配置的文件。由於這個文件也可以被用來作爲自己的一個配置模塊,我們只需將其重命名爲mylib-config.cmake

文件將被安裝到${CMAKE_INSTALL_PREFIX}/lib/cmake/mylib這是許多標準位置find_package(mylib)命令將爲mylib-config.cmake搜索之一。

建設mylib

我們需要指定一個可變CMAKE_INSTALL_PREFIX安裝位置:

mkdir build 
cd build 
cmake -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib 

,並建立和安裝庫:

cmake --build . --target install 

大廈myexe

myexe需要知道在哪裏尋找mylib。變量CMAKE_PREFIX_PATH可以是路徑列表。我們需要指定前面的安裝位置:構建多種配置

通常我們需要建立多種配置(DebugRelease

mkdir build 
cd build 
cmake -DCMAKE_PREFIX_PATH=$PWD/../out ../mylib 
cmake --build . 

的注意事項。一個關鍵問題是指定配置相關的文件名或安裝位置。例如,您可以爲庫項目設置DEBUG_POSTFIX屬性的默認值:

set(CMAKE_DEBUG_POSTFIX d) 

mylib庫文件的調試版本將被命名爲(在Windows或mylibd.liblibmylibd.lib。生成的EXPORT文件將包含修改後的文件名。

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib 
cmake --build . --target install 

您可能需要單獨的編譯目錄的每個配置,也可以重複使用相同的:

如果你使用的makefile風格CMake的發電機,你可以通過設置變量CMAKE_BUILD_TYPE控制構建配置建立目錄。在這種情況下,爲了安全起見,最好明確地乾淨的構建之前:

cmake --build . --target install --clean-first 

如果您使用的是multiconfig IDE發電機,像XcodeVisual Studio,你需要指定編譯時間配置:

cmake -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib 
cmake --build . --target install --config Release 

參考

您可以克隆和構建this repository其中包含mylibmyexe項目(在Windows和Linux測試)。

查看CMake documentation。最重要的相關命令有:

和兩個DETA ILED的文章: