【问题标题】:How to link library using cmake如何使用 cmake 链接库
【发布时间】:2019-12-22 05:21:06
【问题描述】:

我需要在我的程序中使用外部库。 (https://github.com/davidmoreno/onion) 我是 CMake 新手(以及这种编译程序的方式)。

该库包含CMakeLists.txt 文件,所以我想我应该可以使用它。 但是当我尝试编译时,例如hello world 程序示例 (/onion/examples/hello/)。我收到 CMake 无法链接(甚至找不到)使用的库(如 onion.h)的错误。

为了编译,我创建了一个子目录“build”,我从该子目录中执行命令cmake ..,然后是cmake --build .

这里是hello world程序的源文件。 (https://github.com/davidmoreno/onion/tree/master/examples/hello)

CMakeLists.txt:

include_directories (${PROJECT_SOURCE_DIR}/src/) 

add_executable(hello hello.c)
target_link_libraries(hello onion)

hello.c(仅标头):

#include <onion/onion.h>
#include <onion/log.h>
#include <onion/version.h>
#include <signal.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>

这是构建输出:

open# cd build/

open# cmake ..
CMake Warning (dev) in CMakeLists.txt:
  No cmake_minimum_required command is present.  A line of code such as

    cmake_minimum_required(VERSION 3.10)

  should be added at the top of the file.  The version specified may be lower
  if you wish to support older CMake versions for this project.  For more
  information run "cmake --help-policy CMP0000".
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
-- Generating done
-- Build files have been written to: /home/user1/onion/examples/hello/build

open# cmake --build .
Scanning dependencies of target hello
[ 50%] Building C object CMakeFiles/hello.dir/hello.o
/home/user1/onion/examples/hello/hello.c:18:10: fatal error: 'onion/onion.h'
      file not found
#include <onion/onion.h>
         ^~~~~~~~~~~~~~~
1 error generated.
*** Error 1 in . (CMakeFiles/hello.dir/build.make:63 'CMakeFiles/hello.dir/hello.o': /usr/bin/cc  -I/home/user1/onion/examples/hello/src   -...)
*** Error 1 in . (CMakeFiles/Makefile2:68 'CMakeFiles/hello.dir/all')
*** Error 1 in /home/user1/onion/examples/hello/build (Makefile:84 'all')

我尝试了很多解决方案,但没有一个对我有用。

感谢您的帮助。

【问题讨论】:

  • 请在您的问题中提供所有相关代码。避免指向外部网站的链接,因为它们将来可能会更改或被删除。
  • 是的,你是对的。我已经添加了两个源文件。
  • 哪种语言,C C++,因为它们是两种不同的语言? C++ 允许函数和运算符的重载。编译器在处理库时可能会使用 name mangling
  • 嗨,Thomas,这个例子是用 C 语言编写的,但是有一个 C++ 例子,我遇到了同样的问题。
  • No cmake_minimum_required command is present. A line of code such as cmake_minimum_required(VERSION 3.10) should be added at the top of the file 来自自述文件if you want to use the examples on your instalation, compile and __install__ libonion for the current system first. 您是否先为当前系统安装了 libonion?

标签: c++ c unix cmake compilation


【解决方案1】:

基于此存储库设置,您应该使用存储库中的* CMakeLists.txt 文件编译此示例,不是通过在文件上运行 CMake在/onion/examples/hello/ 目录中。通过从顶层运行,您可以选择包含所有示例(默认情况下启用)。

通过从/onion/examples/hello/ 目录运行CMake,include_directories() 命令将relative 解析为当前目录。此处编译流中的“包含”行证明了这一点:

-I/home/user1/onion/examples/hello/src

hello 示例指向&lt;onion/onion.h&gt;,但您包含的目录中不存在头文件。而是他们在这里:

/home/user1/onion/src/onion/onion.h

因此,解决此问题的最简单方法是通过从存储库的 root 运行 cmake 命令来编译您的示例。

【讨论】:

  • 嗨,我这样做了(来自根目录的 cmake + cmake --build)但现在我在尝试运行程序后又遇到了另一个错误。 open# ./examples/hello/hello assertion "("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE)" failed: file "ev.c", line 3570, function "ev_run" Abort trap (core dumped)
  • @Chody123 听起来你已经准备好了一切。这个新问题听起来完全是一个单独的问题,您应该为此发布一个新问题。在 * 上,我们的目标是有针对性、有针对性的问答环境;如果您将新问题作为单独的问题发布,它将获得更多可见性,并且更有可能有人提供帮助。另外,如果您认为我的回答有帮助,您应该将其标记为已接受。