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 的报错时,你就知道该往哪个方向排查了。

posted @ 2025-12-20 11:39  jack-chen666  阅读(0)  评论(0)    收藏  举报