cmake链接共享库时出现“没有规则可制定目标”的错误。

13
在Ubuntu操作系统中,我已经下载了一个第三方共享库mylibrary.so并将其放置在/home/karnivaurus/Libraries目录下。同时,我也将相关的头文件myheader.h放在了/home/karnivaurus/Headers目录下。现在,我想在我的C++代码中使用CMake来链接这个库。以下是我的CMakeLists.txt文件:
cmake_minimum_required(VERSION 2.0.0)

project(DemoProject)

include_directories(/home/karnivaurus/Headers)

add_executable(demo demo.cpp)

target_link_libraries(demo /home/karnivaurus/Libraries/mylibrary)

然而,这让我收到了错误信息:

:-1: error: No rule to make target `/home/karnivaurus/Libraries/mylibrary', needed by `demo'.  Stop.

发生了什么?


6
  1. 你真的需要支持 CMake 版本 古老 到 2.0 吗?
  2. 库在磁盘上的名称不应该是 libmylibrary.so 吗?如果不是,你可以尝试在 target_link_libraries() 中添加 .so 扩展名,这可能有助于消除混淆。
- Angew is no longer proud of SO
如果我添加了.so扩展名,它会给我一个错误:无法找到-lmylibrary - Karnivaurus
您能手动链接库吗,即在不使用CMake的项目中?如果可以,那么哪个命令行可以实现这一点?可能可以从中推断出CMake的语法。我仍然相信该库的名称不遵循Linux惯例。 - Angew is no longer proud of SO
你是否缺少了一个add_library调用? - Bill Campbell
4
add_library命令不是从源代码构建新的库吗?我已经有了编译好的mylibrary.so文件... - Karnivaurus
1
可能是CMake链接到外部库的重复问题。 - Donal Lafferty
2个回答

7
虽然这里发布的另一个答案是有效的,但它已经过时了。CMake现在提供更好的解决方案来在您的代码中使用预构建的外部库。事实上,CMake自身甚至在文档中不鼓励使用 link_directories() 命令。 target_link_libraries() 命令以非常具体的语法链接到外部库。更现代的解决方案是为您的外部库创建一个 IMPORTED CMake目标:
add_library(MyExternalLib SHARED IMPORTED)

# Provide the full path to the library, so CMake knows where to find it.
set_target_properties(MyExternalLib PROPERTIES IMPORTED_LOCATION /home/karnivaurus/Libraries/mylibrary.so)

您可以在代码中稍后使用此导入的 CMake 目标,并将其与其他目标进行链接

target_link_libraries(demo PRIVATE MyExternalLib)

如果您希望了解如何在您的CMake代码中使用外部第三方库的其他方法,请参阅此处的回答。


@astronomerdave,“IMPORTED_LOCATION”属性应指向一个单一的目标。我认为,您可以使用“IMPORTED_LOCATION_Debug”和“IMPORTED_LOCATION_Release”为一个目标设置两个版本的库。 - Kevin

0

您可以使用完整路径来链接静态库。如果要链接动态库,最好使用link_directories(),像这样:

cmake_minimum_required(VERSION 2.0.0)

project(DemoProject)

include_directories(/home/karnivaurus/Headers)
link_directories(/home/karnivaurus/Libraries)

add_executable(demo demo.cpp)

target_link_libraries(demo mylibrary)

确保mylibrary在文件名中有前缀lib和后缀.so(即完整名称为/home/karnivaurus/Libraries/libmylibrary.so)。

为了使您的项目更加灵活,最好编写一个查找器模块,避免硬编码路径,如/home/karnivaurus/*


1
请使用find_file和相关函数。 - steveire
@steveire,通常仅有文件路径是不够的。对于更严肃的项目,最好学习查找器以及如何编写它们。 - zaufi
那不是你的建议。 - steveire
1
这个回答已经过时了。目前的CMake文档明确说明应该避免使用link_directories。有关替代方案的更多信息,请参阅文档。 - tjwrona1992
9
我并不认为这是浪费时间,并且我也没有试图侮辱你的回答。当它被写下来时,我并不是说这是一个糟糕的答案,但人们在谷歌上搜索CMake建议时会偶然发现这个帖子。应该让他们知道,尽管过去这可能是一个好的答案,但今天采取这种建议将是错误的,因为有更好的选择。 - tjwrona1992

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接