c++的库 有哪几种来源? 1. 同一个 项目里 自己开发编译的函数 2. c++语言自带的库 3. 安装的开源库 如果还有其他的 请帮我补充并 详细的介绍-11
这是一个非常专业且切中要害的问题。在 C++(特别是像 ROS 这样复杂的系统)开发中,搞清楚“这个库从哪来的”决定了你在 CMakeLists.txt 中如何去查找和链接它。
你的归纳已经非常准确了,但这三类还可以进一步细分,并且还有一类在工业界(特别是机器人领域)非常重要的商业/闭源 SDK。
我们可以将 C++ 库的来源归纳为 5 大类。我将结合 CMake 的写法为你详细介绍:
1. C++ 标准库 (C++ Standard Library)
这是你提到的“语言自带的库”。
-
来源:它并不是操作系统提供的,而是编译器 (Compiler) 提供的。当你安装 GCC、Clang 或 MSVC 时,标准库就已经在你的电脑里了。
-
包含内容:
std::vector,std::string,std::iostream,std::thread,std::filesystem等。 -
特点:
-
不需要下载。
-
不需要在 CMake 中显式
find_package。 -
不需要显式
target_link_libraries(大部分情况下编译器自动链接)。 -
CMake 写法:
只需要指定 C++ 标准版本即可:
set(CMAKE_CXX_STANDARD 14) # 告诉编译器使用 C++14 标准库
2. 操作系统系统级库 (System/OS Libraries)
这一类常被新手忽略,或者误认为是标准库。它们是操作系统提供的接口,通常是 C 语言写成的,但 C++ 可以直接调用。
-
来源:随操作系统安装(Linux 内核或 Windows 系统层)。
-
包含内容:
-
Linux:
pthread(多线程底层),dl(动态加载),socket(网络),OpenGL(显卡驱动接口)。 -
Windows:
windows.h(Win32 API)。 -
特点:它们存在于系统中,但需要显式链接。
-
CMake 写法:
通常使用find_library或特定的查找模块:
# 查找多线程库 (Linux下通常是 pthread)
find_package(Threads REQUIRED)
target_link_libraries(my_node Threads::Threads)
3. 第三方开源库 (Third-party Open Source Libraries)
这是你提到的“安装的开源库”,也是 ROS 开发中最庞大的一类。根据安装方式的不同,它们在 CMake 中的处理方式截然不同,可以细分为两种:
3.1 系统级安装 (System Installed)
- 来源:通过
apt-get install,pacman,brew或者vcpkg安装到系统的默认路径(如/usr/lib和/usr/include)。 - 例子:
Eigen3,PCL,OpenCV,Boost。 - 特点:库已经编译好了(通常是二进制
.so或.a文件),头文件也在标准位置。 - CMake 写法:
使用标准且强大的find_package:
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(my_node ${OpenCV_LIBS})
3.2 源码级集成 (Source Integration / In-tree build)
- 来源:你直接去 GitHub
git clone下来,把整个源码文件夹放在你的项目目录里(比如放在3rdparty/文件夹下)。 - 例子:一些轻量级的库,或者你需要修改源码的库。
- 特点:它会随着你的项目一起编译,你可以完全控制编译选项。
- CMake 写法:
使用add_subdirectory:
# 比如你把 g2o 图优化库的源码放在了项目里
add_subdirectory(3rdparty/g2o)
target_link_libraries(my_node g2o) # 直接链接生成的 Target
4. 商业/闭源 SDK (Proprietary/Commercial SDKs) —— 补充重点
在机器人和自动驾驶开发中,这一类非常常见,且最容易出构建问题。
-
来源:硬件厂商提供。你买了一个昂贵的工业相机、机械臂或激光雷达,厂商会给你一个 SDK 包。
-
包含内容:
-
include/:头文件(给你看的接口)。 -
lib/或bin/:二进制文件(.so,.dll,.lib)。厂商不给你源码,只给你编译好的黑盒子。 -
例子:
-
NVIDIA TensorRT / CUDA(虽然部分开源,但核心是闭源二进制)。
-
大恒/海康相机 SDK。
-
UR 机械臂的旧版驱动库。
-
特点:无法用
apt-get安装,也没有源码。你必须手动告诉 CMake 这个文件存在哪。 -
CMake 写法:
需要“显式指定路径”进行链接:
# 1. 找到头文件
include_directories(${PROJECT_SOURCE_DIR}/lib/camera_sdk/include)
# 2. 找到二进制库文件 (.so 或 .lib)
find_library(CAMERA_LIB my_camera_sdk PATHS ${PROJECT_SOURCE_DIR}/lib/camera_sdk/lib)
# 3. 链接
target_link_libraries(my_node ${CAMERA_LIB})
5. 纯头文件库 (Header-only Libraries) —— 补充重点
这是一种特殊的开源库形式,近年来非常流行。
-
来源:GitHub 下载。
-
特点:没有
.cpp文件,只有.hpp或.h文件。所有的实现代码都写在头文件里。 -
优势:不需要编译成
.so或.a,不需要链接(Link),只需要 Include 就能用。 -
例子:
-
Eigen(是的,Eigen 大部分是纯头文件库!)。 -
nlohmann/json(现代 C++ 最流行的 JSON 库)。 -
Sophus(李代数库,SLAM 常用)。 -
CMake 写法:
只需要包含路径即可,不需要target_link_libraries(除非它是 Interface 库):
# 只要让编译器能找到头文件在哪就行
include_directories(/path/to/json/include)
总结一张表
| 来源分类 | 典型代表 | 特征 | CMake 关键指令 |
|---|---|---|---|
| 1. C++ 标准库 | std::vector, std::string |
编译器自带,随叫随到 | set(CMAKE_CXX_STANDARD 14) |
| 2. 系统级库 | pthread, socket |
操作系统提供,通常是 C 接口 | find_package, find_library |
| 3. 开源库 (系统安装) | PCL, OpenCV (apt安装) |
已编译好,在系统默认路径 | find_package |
| 4. 开源库 (源码集成) | 自己 clone 的 github 项目 | 随项目一起从零编译 | add_subdirectory |
| 5. 闭源 SDK | 相机驱动, NVIDIA SDK | 只有头文件和二进制包,无源码 | include_directories + target_link_libraries(绝对路径) |
| 6. 纯头文件库 | Eigen, nlohmann/json |
只有 .hpp,无需编译链接 |
include_directories |
回到你的 ROS 项目 (FAST_LIO):
roscpp,pcl_ros,tf: 属于 第 3 类 (开源库-系统安装)。Eigen: 属于 第 6 类 (纯头文件库) (虽然用 find_package 找,但本质只需要 include)。- 如果你买了一个大疆的 Livox 雷达,它的驱动
livox_ros_driver如果是源码形式放在src下,那就是 第 4 类 (开源库-源码集成)。
理解了这个分类,当你遇到 undefined reference to xxx 或者 cannot find -lxxx 的报错时,你就知道该往哪个方向排查了。

浙公网安备 33010602011771号