使用pybind11搭配Eigen为何无需调用target_link_libraries?
关于Eigen在pybind11项目中无需链接的疑问及非头文件库处理方法
问题背景
我尝试编译pybind11教程项目中的example.cpp文件,代码如下:
#include <pybind11/pybind11.h> #include <pybind11/eigen.h> #include <Eigen/LU> #include <iostream> // ---------------- // regular C++ code // ---------------- Eigen::MatrixXd mul(const Eigen::MatrixXd &xs, double fac) { std::cout << "Double" << std::endl; return fac*xs; } Eigen::MatrixXi mul(const Eigen::MatrixXi &xs, int fac) { std::cout << "Int" << std::endl; return fac*xs; } // ---------------- // Python interface // ---------------- namespace py = pybind11; PYBIND11_MODULE(example,m) { m.doc() = "pybind11 example plugin"; // N.B. the order here is crucial, in the reversed order every "int" is converted to a "double" m.def("mul", py::overload_cast<const Eigen::MatrixXi &,int >(&mul) ); m.def("mul", py::overload_cast<const Eigen::MatrixXd &,double>(&mul) ); }
对应的CMakeLists.txt内容:
cmake_minimum_required(VERSION 2.8.12) project(example) set (CMAKE_CXX_STANDARD 14) find_package( PkgConfig ) pkg_check_modules( EIGEN3 REQUIRED eigen3 ) include_directories( ${EIGEN3_INCLUDE_DIRS} ) add_subdirectory(pybind11) pybind11_add_module(example example.cpp)
我的疑问:为何无需将Eigen与example目标进行链接?是否因为Eigen是仅头文件库,仅通过include_directories配置头文件路径即可?另外,对于非仅头文件库,我该如何处理?
解答
Eigen无需链接的原因
没错,Eigen是典型的仅头文件(header-only)库——它的所有实现代码都直接写在头文件中,没有预编译好的静态库(.a/.lib)或动态库(.so/.dll)文件。编译时,只要通过include_directories让编译器能找到Eigen的头文件目录,编译器就会在编译example.cpp时直接把Eigen的代码嵌入到目标模块里,因此不需要额外执行链接操作。非仅头文件库的处理方法
对于带有预编译库文件的非仅头文件库,需要在CMake中完成三个核心步骤:
- 定位库文件:使用
find_package(CMake官方推荐,适用于提供了CMake配置文件的库,比如Boost、OpenCV)或pkg_check_modules(适用于通过pkg-config管理的库),获取库的头文件路径和库文件路径。 - 添加头文件路径:推荐使用
target_include_directories替代全局的include_directories,为目标模块单独设置头文件搜索路径,避免污染全局编译环境。例如:target_include_directories(example PRIVATE ${BOOST_INCLUDE_DIRS}) - 链接库文件:使用
target_link_libraries将目标模块与对应的预编译库关联,例如:target_link_libraries(example PRIVATE Boost::system)
内容的提问来源于stack exchange,提问作者QualsPassed
相关产品推荐
相关产品推荐

