2014-10-06 197 views
3

我想用CMake創建一個簡單的靜態庫Maths,然後鏈接到該庫創建一個簡單的可執行文件AlphaCMake無法找到我的庫文件

這裏是我的目錄結構:

/Maths 
    /build 
     /
    /CMakeLists.txt 
    /maths.cpp 
    /maths.h 
/Alpha 
    /build 
     /
    /CMakeLists.txt 
    /main.cpp 

這裏是這些文件的內容:

*的CMakeLists.txt(用於數學)*

cmake_minimum_required(VERSION 2.6) 
project(Maths) 
add_library(maths STATIC maths.cpp) 

*數學.cpp *

int Double(int x) 
{ 
    int y = x * 2; 
    return y; 
} 

* maths.h *

int Double(int x); 

*的CMakeLists.txt(爲阿爾法)*

cmake_minimum_required(VERSION 2.8) 
project(Alpha) 
add_executable(alpha main.cpp ../Maths/maths.h) 
target_link_libraries(maths ../Maths/build/libmaths.a) 

*的main.cpp *

#include <iostream> 

#include "maths.h" 

using namespace std; 

int main() 
{ 
    int x = 5; 
    int y = Triple(x); 
    cout << "The answer = " << y << endl; 
    return 0; 
} 

因此,我進入目錄/Maths/build,並運行cmake ..。然後,我運行make。這會在目錄/Maths/build中創建庫文件libmaths.a

然後,我進入目錄/Alpha/build,並運行cmake ..。然後,我運行make。但是,這給我錯誤信息:

/usr/bin/ld: cannot find -lmaths 

爲什麼不能找到我剛創建的庫文件?

我也試過copyiing libmaths.amaths.h到目錄/Alpha,以及改變阿爾法的的CMakeLists.txt到:

cmake_minimum_required(VERSION 2.8) 
project(Alpha) 
add_executable(alpha main.cpp maths.h) 
target_link_libraries(maths libmaths.a) 

但是這給了同樣的錯誤。

回答

3

這裏的基本問題是libmaths.a未放置在其中一個默認鏈接器目錄中。 更大的問題是,您首先通過libmaths.atarget_link_libraries

這有幾個原因不好,但最明顯的是它是完全不可移植的。對於靜態庫,不同的編譯器工具鏈可能會使用不同於.a的結尾,因此您將無法在此處進行構建。此外,如果您決定在未來轉換到動態鏈接,這意味着重構您現有的CMake腳本。

正確的解決方案是不傳遞硬編碼文件名到target_link_libraries。有兩條道路可以避免這種情況。

  1. 使用查找腳本。基本上,您可以撥打find_library(MY_MATHLIB maths [...]),然後改爲target_link_libraries(alpha ${MY_MATHLIB})。這將以便攜方式確定文件的絕對路徑並將其傳遞給鏈接器。這種方法最大的缺點是.a文件必須已經存在才能使find調用成功。因此,如果您想在之後構建maths,然後運行CMake爲alpha或將其構建爲alpha的一部分,則此操作將不起作用。

  2. 由於這兩個庫都在您的控制之下,因此請考慮使用CMake's packaging mechanism。這是迄今爲止建設最方便的方法,但不幸的是最難建立。如果您願意花一些時間來挖掘CMake文檔並嘗試構建,我鼓勵您嘗試一下,但如果您只是想要快速運行的某些內容,則可能需要堅持選項1。

+0

我在這裏也有同樣的問題,也纔剛剛開始cmake的。我對C++編程實踐一無所知,剛開始。你能解釋你的第一個推薦嗎?因爲我無法理解提供的鏈接中的一件事。如果你能舉一個例子,我會非常感激。 – Bora 2017-03-09 19:34:32

+0

@Bora find_library命令只是在磁盤上查找庫文件。由於CMake知道不同編譯器的命名約定,因此只需提供原始名稱(示例中爲'maths'),而不用任何文件擴展名,CMake就會自動搜索正確的文件。根據您的系統和文件的位置,您可能還需要提供文件所在位置的其他提示。查看鏈接的聯機幫助頁以查看查找規則的完整說明。但最終它只不過是在磁盤上搜索具有匹配名稱的文件而已。 – ComicSansMS 2017-03-09 20:18:15

2

使用在根目錄中的CMakeLists.txt

/CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 
PROJECT(MyProject) 
ADD_SUBDIRECTORY(Maths) 
ADD_SUBDIRECTORY(Alpha) 

爲Alpha /的CMakeLists.txt

TARGET_LINK_LIBRARIES(alpha maths) 

運行cmake上頂級的CMakeLists.txt,而不是個別子目錄那些