【问题标题】:"No rule to make target" error in cmake when linking to shared library链接到共享库时,cmake 中出现“无规则制作目标”错误
【发布时间】:2015-01-04 14:29:46
【问题描述】:

在 Ubuntu 中,我下载了一个第三方共享库,mylibrary.so,我将它放在了目录/home/karnivaurus/Libraries 中。我还将相关的头文件myheader.h 放在目录/home/karnivaurus/Headers 中。我现在想使用 CMake 在我的 C++ 代码中链接到这个库。这是我的 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.

发生了什么事?

【问题讨论】:

  • 1.你真的需要像 2.0 一样支持 CMake ancient 吗? 2. 磁盘上的库名不应该是libmylibrary.so吗?如果不是,您可以尝试将.so 扩展名添加到target_link_libraries(),这可能有助于消除混淆。
  • 如果我添加 .so 扩展名,它会给我错误:cannot find -lmylibrary
  • 您可以手动链接到库吗,即在不使用 CMake 的项目中?如果是这样,什么命令行可以实现这一点?可能可以从中推断出 CMake 语法。不过,我仍然认为该库的名称不符合 Linux 约定。
  • add_library 不是从源代码构建新库吗?我已经得到了编译好的mylibrary.so文件...

标签: c++ cmake shared-libraries libraries


【解决方案1】:

虽然此处发布的其他答案有效,但已过时。 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 代码中使用外部第三方库的其他方法,请参阅回复 here

【讨论】:

  • @astronomerdave IMPORTED_LOCATION 属性应指向单个目标。我相信您可以为一个目标设置一个库的两个版本,例如使用IMPORTED_LOCATION_DebugIMPORTED_LOCATION_Release
【解决方案2】:

您可以使用静态库的完整路径。要链接 w/ 动态链接,最好像这样使用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)。

为了让你的项目更灵活,你最好写一个finder module,避免像/home/karnivaurus/*这样的硬编码路径

【讨论】:

  • 改用 find_file 和朋友。
  • @steveire 通常只有一些文件路径是不够的。对于更严肃的项目,最好学习查找器以及如何编写它们。
  • 这不是你的建议。
  • 这个答案已经过时了。当前的 CMake 文档明确指出应避免使用 link_directories。有关替代方案的更多信息,请参阅文档。
  • 我不认为这是浪费时间,我也不想侮辱您的回答。我并不是说它在编写时是一个糟糕的答案,但是人们会在谷歌上偶然发现这个线程来寻找 CMake 建议。应该让他们意识到,虽然过去这可能是一个很好的答案,但今天接受这个建议会很糟糕,因为有更好的选择。
猜你喜欢
  • 2016-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多