我想使用CMake创建一个简单的静态库Maths
,然后链接到该库以创建一个简单的可执行文件Alpha
。
这是我的目录结构:
/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)
* maths.cpp *
int Double(int x)
{
int y = x * 2;
return y;
}
* maths.h *
int Double(int x);
* CMakeLists.txt(适用于Alpha)*
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
。这将在目录libmaths.a
中创建库文件/Maths/build
。
然后,我进入目录/Alpha/build
,然后运行cmake ..
。然后,我运行make
。但是,这给了我错误消息:
/usr/bin/ld: cannot find -lmaths
为什么找不到我刚刚创建的库文件?
我还尝试将libmaths.a
和maths.h
复制到目录/Alpha
中,并将Alpha的CMakeLists.txt更改为:
cmake_minimum_required(VERSION 2.8)
project(Alpha)
add_executable(alpha main.cpp maths.h)
target_link_libraries(maths libmaths.a)
但这也给出了同样的错误。
答案 0 :(得分:3)
这里的基本问题是libmaths.a
未放置在其中一个默认链接器目录中。
更大的问题是您首先将libmaths.a
传递给target_link_libraries
。
这有几个原因很糟糕,但最明显的是它完全不可移植。对于静态库,不同的编译器工具链可能使用与.a
不同的结尾,因此您将无法在那里构建。此外,如果您决定将来切换到动态链接,则意味着重构现有的CMake脚本。
正确的解决方案是不将硬编码的文件名传递给target_link_libraries
。你可以采取两条道路来避免这种情况。
使用查找脚本。从本质上讲,您拨打find_library(MY_MATHLIB maths [...])
,然后改为target_link_libraries(alpha ${MY_MATHLIB})
。这将以可移植的方式确定.a
文件的绝对路径,并将其传递给链接器。这种方法的最大缺点是.a
文件必须已存在才能使查找调用成功。因此,如果您希望在运行maths
的CMake之后构建alpha
,或者将其作为alpha
的一部分构建,则无法使用。
由于两个库都在您的控制之下,请考虑使用CMake's packaging mechanism。这是迄今为止最方便的建筑方法,但不幸的是也是最难建立的方法。如果您愿意花一些时间挖掘CMake文档并尝试构建,我鼓励您尝试一下,但如果您只是想要快速运行的东西,您可能希望坚持使用选项1。
答案 1 :(得分: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 )
在顶级CMakeLists.txt上运行CMake而不是单独的子目录