2014-10-06 201 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,而不是个别子目录那些