Linux系统下C++库安装使用

细细品味:find_package查找库的规律是如此的巧妙,库的安装也是如此~给我一个库,我如何能够让find_package找到它呢?这就是本文的重点!!!

C++库的安装方式

在linux系统下库的安装方式主要有三种:

  1. 使用包管理器安装:Linux系统通常有自己的软件包管理器,如apt、yum、dnf等。用户可以通过包管理器直接安装预编译的C++库,无需手动下载和编译。例如,使用apt install命令在Ubuntu或Debian系统上安装软件包。
  2. 手动编译和安装:用户可以手动下载库的源代码,然后自行编译和安装。这种方式相对较复杂,但提供了更多的定制选项。
  3. 手动编译不安装;通过手动编译库,设置环境变量,即可使用。
  4. 不编译直接使用:如果一个库只有头文件,例如Eigen库,直接include_directories即可。

使用包管理器安装

sudo install apt libeigen3-dev为例,首先我们解析一下这个语句,sudo表示获取管理员权限

apt是Linux系统的一个包管理工具,install表示安装,lib+库名-dev 是 Ubuntu/Debian 系统中包含开发文件(头文件、静态库、共享库、CMake 模块等)的开发版本软件包的命名规则。其中,lib 是固定前缀,库名 是指具体的库名,-dev 表示这是开发版本的软件包。例如,libeigen3-dev 表示的是 Eigen 库的开发版本软件包,包含了头文件和其他开发所需的文件,方便在 C++ 项目中使用 Eigen 库进行编程。不需要手动编译该软件包,可以通过 sudo apt install libeigen3-dev 命令安装预编译好的开发版本软件包。

既然sudo install apt libeigen3-dev无需手动编译,可以直接在我们的代码中使用;那我们现在有个问题,我们cmake编译时,它是如何找到这个库的呢?这个库的安装路径是啥?谁指定的?安装完之后CMakeLists.txt中find_package是怎么找到这个库的头文件路径(XXX_INCLUDE_DIRS)和链接库(XXX_LIBRARIES)呢?如何找到的?

首先,我们要知道在Ubuntu和Debian等使用apt包管理器的Linux发行版中,apt会将软件包的文件安装到预定的目录结构下。具体安装路径取决于软件包的类型和用途。

通常情况下,预编译的二进制软件包(包括C++库和应用程序)会安装在以下目录:

  • 可执行文件(二进制文件):/usr/bin/usr/local/bin
  • 库文件(动态库和静态库):/usr/lib/usr/local/lib
  • 头文件(C++库的头文件):/usr/include/usr/local/include

例如,对于libeigen3-dev软件包,它是Eigen库的开发版本,头文件会安装在/usr/include/eigen3目录下,配置文件安装在/usr/lib/cmake目录下,该目录包括Eigen3Config.cmake文件;而该配置文件正好是在find_package的搜索范围内,因此通过该方式find_package是能找到库的。

手动编译和安装

如果我们自己去官网下载eigen或者使用git clone 下载,需要自己先编译,再进行安装,安装过程中config.cmake文件就配置好了,合理安装在find_package能找的位置;

在CMakeLists.txt所在的目录下,输入下列指令,即可安装;

1
2
3
4
mkdir build
cd build
cmake ..
sudo make install

手动编译不安装

如果我们发现,某个库我手动编译完之后,我们想要用find_package安装不了咋办呢?

根据find_package的查找规律先找环境变量路径,然后在环境变量路径下找lib或者share下的cmake文件或者包名文件夹下的Config.cmake配置文件。

在linux系统的主目录下,打开.bashrc文件,将该库写入到环境变量中

一般是source ./devel/setup.bash命令,如此将devel文件夹添加到环境变量当中,当find_package找库时,根据上面的查找规律,就会在devel文件夹下的lib或share文件夹下的cmake或该库名文件夹下的Config.cmake文件。

也就是说,当我自己下载一个库之后,编译完库后,设置一下环境变量,find_package就能使用,并找到该库的Config.cmake配置文件了。

不编译,直接使用

最常见就是engen库了,我们在CMakeLists.txt,直接指明头文件路径即可。

#include_directories( "D:\\Eigen" )