如何正确地满足以下pybind11项目中的所有链接器依赖项
How to properly satisfy all linker dependencies in following pybind11 project?
我正在为python接口将一个大型库移植到pybind11。然而,我一直在链接器阶段获取multiple declaration error
,或者在python导入过程中获取symbol not found
错误。简化的项目结构如下所示
CMake文件
cmake_minimum_required(VERSION 3.5)
# set the project name
project(tmp VERSION 1.0)
find_package(EnvModules REQUIRED)
env_module(load python39)
find_package(PythonInterp REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
include_directories(pybind11/include)
add_subdirectory(pybind11)
pybind11_add_module(TMP py_modules.cpp
SubConfiguration.cpp)
# pybind11_add_module(TMP py_modules.cpp)
源文件:py_modules.cpp
#include "pybind11/pybind11.h"
#include "calculateStress.h"
namespace py = pybind11;
PYBIND11_MODULE(TMP, m){
py::class_<Stencil>(m, "Stencil")
.def(py::init<double &>());
py::class_<SubConfiguration>(m, "SubConfiguration")
.def(py::init<Stencil &>());
}
calculateStress.h
#ifndef CALCULATESTRESS_H_
#define CALCULATESTRESS_H_
#include "SubConfiguration.h"
#endif /* CALCULATESTRESS_H_ */
SubConfiguration.h
#ifndef SRC_SUBCONFIGURATION_H_
#define SRC_SUBCONFIGURATION_H_
#include "Stencil.h"
class SubConfiguration
{
public:
double& parent;
SubConfiguration(Stencil& stencil);
};
#endif /* SRC_SUBCONFIGURATION_H_ */
SubConfiguration.cpp
#include "SubConfiguration.h"
SubConfiguration::SubConfiguration(Stencil& stencil) :
parent(stencil.parent)
{}
Stencil.h
#ifndef SRC_STENCIL_H_
#define SRC_STENCIL_H_
class Stencil {
public:
double parent;
Stencil(double&);
};
Stencil::Stencil(double& parent) : parent(parent) { }
#endif /* SRC_STENCIL_H_ */
我认为所有的进口保护措施都设置得当。
现在,当我给pybind11_add_module(TMP py_modules.cpp)
编译选项时,我得到了TMP模块,但在导入时,我收到了错误undefined symbol: _ZN16SubConfigurationC1ER7Stencil
而使用pybind11_add_module(TMP py_modules.cpp SubConfiguration.cpp)
,我得到以下错误
/usr/bin/ld: CMakeFiles/TMP.dir/SubConfiguration.cpp.o (symbol from plugin): in function `Stencil::Stencil(double&)':
(.text+0x0): multiple definition of `Stencil::Stencil(double&)'; CMakeFiles/TMP.dir/py_modules.cpp.o (symbol from plugin):(.text+0x0): first defined here
/usr/bin/ld: CMakeFiles/TMP.dir/SubConfiguration.cpp.o (symbol from plugin): in function `Stencil::Stencil(double&)':
(.text+0x0): multiple definition of `Stencil::Stencil(double&)'; CMakeFiles/TMP.dir/py_modules.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/TMP.dir/build.make:99: TMP.cpython-39-x86_64-linux-gnu.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:96: CMakeFiles/TMP.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
如何正确设置?
问题是Stencil.h同时包含在py_modules.cpp和SubConfiguration.cpp中。include保护只能防止来自单个编译单元(cpp文件(的双重包含。
从Stencil.h
中删除Stencil构造函数的实现,并将其作为移动到新文件Stencil.cpp
中
#include "Stencil.h"
Stencil::Stencil(double& parent) : parent(parent) { }
然后将新文件添加到您的模块
...
add_subdirectory(pybind11)
pybind11_add_module(TMP py_modules.cpp SubConfiguration.cpp Stencil.cpp )
更新(反映意见(
如果您有一个模板化的类,则不一定需要在头中包含实现。您可以使用显式模板实例化,如下例所示:
在标题doit.h
中
template< typename T >
T addsome( T t );
体内doit.cpp
#include "doit.h"
// Add explicit template instantiations for the types you care
// #include <doit.h>
template<>
int addsome<int>( int t ) {
return t+1;
}
template<>
double addsome<double>( double t ) {
return t+2;
}
在main.cpp或您使用它的地方
int main() {
int res = addsome<int>( 1 ); // This will link against the compiled body doit.cpp
}
相关文章:
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- 使用Bazel构建具有不同编译器/链接器选项的C/C++依赖关系
- 在链接可执行文件之前查找静态库未解析的依赖项
- aarch64动态链接器rpath使用辅助依赖链接
- 链接二进制库或共享库时,为什么必须传入我依赖的共享库?
- 单独库中的类成员函数定义和链接依赖项
- 可视C++ - 从链接器>输入>其他依赖项中排除文件
- 链接共享库依赖项未在 ldd 中列出
- 您如何将所有链接依赖项都包装到一个Linux静态库中
- 模板或链接接缝依赖注入有哪些替代方案来测试非虚拟方法?
- 使用C 中的链接seam break static变量依赖关系
- GHC 不链接依赖项
- C++ 生成文件不编译依赖项/链接错误?
- 模型依赖关系目标,在运行时链接
- 视觉如何引用部署与2015 C 链接库依赖关系
- 将库与NuGet包链接为Visual Studio中的依赖项
- Cmake不会将共享库的链接依赖关系传播到我的可执行文件
- 如何在VS 2010中自动链接依赖项的依赖项
- 指定当一个静态库依赖于另一个静态库时所需的链接依赖关系