尽管已在CMake中指定了库,但仍存在未定义的参考错误与libtorch链接的问题C ++ 11 ABI?

如何解决尽管已在CMake中指定了库,但仍存在未定义的参考错误与libtorch链接的问题C ++ 11 ABI?

我试图从我创建的库中创建测试可执行文件。让我们将它们命名为lib1和lib2。 lib1随它的测试一起构建。 lib2的构建也没有任何问题。但是,每当我尝试将lib2与它的测试可执行文件(即使用lib2的示例程序)链接时,都会出现以下错误:

usr/bin/ld: CMakeFiles/Lib2_Test.dir/Lib2_Test.cpp.o: in function `main':
Lib2_Test.cpp:(.text+0xf3): undefined reference to `Lib2::Lib2(std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::__cxx11::basic_string<char,int,int)'
/usr/bin/ld: Lib2_Test.cpp:(.text+0x3f5): undefined reference to `Lib2::Evaluate(bool&,std::allocator<char> >&,float&,cv::Mat&,bool)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Lib2_Test.dir/build.make:130: Lib2_Test] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/Lib2_Test.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

我尝试使用readelf -dldd命令查看标头,两个库似乎都具有所有必要的引用。但是lib1没有任何问题,而lib2链接到使用它的可执行文件时会生成未引用的相关错误。

下面是我为它们创建的cmakeList,后来我还包含了readelf的输出。

lib1的CMakelist.txt:

cmake_minimum_required(VERSION 3.11)
project(Lib1)

set(CMAKE_CXX_STANDARD 17)

find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)

add_definitions(-D_LIB1_BUILD_DLL) 

set( CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -fPIC" )

set(CMAKE_INSTALL_PREFIX /home/me/Desktop/LibtorchPort/built_stuff)

include_directories( /home/me/Desktop/LibtorchPort/Dependencies/include ${TORCH_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS})
LINK_DIRECTORIES(/home/me/libtorch-cxx11-abi-shared-with-deps-1.6.0+cpu/libtorch/lib)

# http://dlib.net/examples/CMakeLists.txt.html
add_subdirectory(/home/me/dlib-19.21 /home/me/dlib-19.21/build)     

set(Lib1_SRC ./lib1.cpp)

add_library(lib1 SHARED  ${Lib1_SRC})

# Link
target_link_libraries(lib1 ${TORCH_LIBRARIES})
target_link_libraries(lib1 ${OpenCV_LIBS})
target_link_libraries(lib1 dlib::dlib)

install(TARGETS lib1 LIBRARY DESTINATION lib)

这是lib1_test的CMakeList.txt:

cmake_minimum_required(VERSION 3.11)
project(Lib1_Test)
set(CMAKE_CXX_STANDARD 17)

find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)

set(CMAKE_INSTALL_PREFIX /home/me/Desktop/LibtorchPort/built_stuff)
include_directories( /home/me/Desktop/LibtorchPort/Dependencies/include ${TORCH_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS})
 
# Link
add_executable(lib1_dynamic_test ./Lib1_Test.cpp)
target_link_directories(lib1_dynamic_test PRIVATE /home/me/Desktop/LibtorchPort/Lib1/build)

target_link_libraries(lib1_dynamic_test lib1 )
target_link_libraries(lib1_dynamic_test ${TORCH_LIBRARIES} )
target_link_libraries(lib1_dynamic_test ${OpenCV_LIBS})
install(TARGETS lib1_dynamic_test DESTINATION bin)

这是lib2的CMakeList.txt:

cmake_minimum_required(VERSION 3.11)
project(Lib2)

set(CMAKE_CXX_STANDARD 17)

find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)

add_definitions(-D_LIB2_BUILD_DLL) 

set(CMAKE_INSTALL_PREFIX /home/me/Desktop/LibtorchPort/built_stuff)

include_directories( /home/me/Desktop/LibtorchPort/Dependencies/include ${TORCH_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS})

LINK_DIRECTORIES(/home/me/libtorch-cxx11-abi-shared-with-deps-1.6.0+cpu/libtorch/lib)
LINK_DIRECTORIES(/home/me/Desktop/LibtorchPort/Lib1/build)

set(LIB2_SRC  ./lib2.cpp )

add_library(lib2_dynamic SHARED ${LIB2_SRC} )

target_link_directories(lib2_dynamic PRIVATE /home/me/Desktop/LibtorchPort/Lib1/build)

target_link_libraries(lib2_dynamic  lib1)
target_link_libraries(lib2_dynamic  ${TORCH_LIBRARIES})
target_link_libraries(lib2_dynamic  ${OpenCV_LIBS})

install(TARGETS lib2_dynamic LIBRARY DESTINATION lib)

最后是lib2_test的CMakeList:

cmake_minimum_required(VERSION 3.11)
project(Lib2_Test)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INSTALL_PREFIX /home/me/Desktop/LibtorchPort/built_stuff)

#find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)

include_directories( /home/me/Desktop/LibtorchPort/Dependencies/include ${OpenCV_INCLUDE_DIRS})
LINK_DIRECTORIES(/home/me/Desktop/LibtorchPort/Lib1/build)

add_executable(Lib2_Test ./lib2_test.cpp)

target_link_directories(Lib2_Test PRIVATE /home/me/Desktop/LibtorchPort/Lib2/build)
#target_link_directories(Lib2_Test PUBLIC /home/me/Desktop/LibtorchPort/Lib1/build)

#Link
target_link_libraries(Lib2_Test ${OpenCV_LIBS})
target_link_libraries(Lib2_Test lib2_dynamic)
install(TARGETS Lib2_Test DESTINATION bin)

运行readelf -d lib1,这是我得到的输出:

Dynamic section at offset 0x908f8 contains 38 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libtorch.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc10.so]
 0x0000000000000001 (NEEDED)             Shared library: [libtorch_cpu.so]
 0x0000000000000001 (NEEDED)             Shared library: [libopencv_highgui.so.3.4]
 0x0000000000000001 (NEEDED)             Shared library: [libopencv_imgproc.so.3.4]
 0x0000000000000001 (NEEDED)             Shared library: [libopencv_core.so.3.4]
 0x0000000000000001 (NEEDED)             Shared library: [libcblas.so.3]
 0x0000000000000001 (NEEDED)             Shared library: [liblapack.so.3]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [ld-linux-x86-64.so.2]
 0x000000000000000e (SONAME)             Library soname: [libLib1.so]
 0x000000000000001d (RUNPATH)            Library runpath: [/home/me/anaconda3/lib/python3.8/site-packages/torch/lib:/home/me/libtorch-cxx11-abi-shared-with-deps-1.6.0+cpu/libtorch/lib:/usr/local/lib:]
 0x000000000000000c (INIT)               0x1a000
 0x000000000000000d (FINI)               0x57e00
 0x0000000000000019 (INIT_ARRAY)         0x90b28
 0x000000000000001b (INIT_ARRAYSZ)       32 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x90b48
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x328
 0x0000000000000005 (STRTAB)             0x6840
 0x0000000000000006 (SYMTAB)             0x1758
 0x000000000000000a (STRSZ)              56053 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x92000
 0x0000000000000002 (PLTRELSZ)           8112 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x17ff0
 0x0000000000000007 (RELA)               0x14b58
 0x0000000000000008 (RELASZ)             13464 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x149f8
 0x000000006fffffff (VERNEEDNUM)         5
 0x000000006ffffff0 (VERSYM)             0x14336
 0x000000006ffffff9 (RELACOUNT)          6
 0x0000000000000000 (NULL)               0x0

这是lib2的输出:

Dynamic section at offset 0x37ba0 contains 32 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libLib1.so]
 0x0000000000000001 (NEEDED)             Shared library: [libtorch.so]
 0x0000000000000001 (NEEDED)             Shared library: [libtorch_cpu.so]
 0x0000000000000001 (NEEDED)             Shared library: [libopencv_core.so.3.4]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libLib2_dynamic.so]
 0x000000000000001d (RUNPATH)            Library runpath: [/home/me/anaconda3/lib/python3.8/site-packages/torch/lib:/home/me/libtorch-cxx11-abi-shared-with-deps-1.6.0+cpu/libtorch/lib:/home/me/Desktop/LibtorchPort/Lib1/build:/usr/local/lib:]
 0x000000000000000c (INIT)               0x1e000
 0x000000000000000d (FINI)               0x2ec10
 0x0000000000000019 (INIT_ARRAY)         0x38108
 0x000000000000001b (INIT_ARRAYSZ)       16 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x38118
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x2f0
 0x0000000000000005 (STRTAB)             0x7d88
 0x0000000000000006 (SYMTAB)             0x1dd0
 0x000000000000000a (STRSZ)              62708 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x39000
 0x0000000000000002 (PLTRELSZ)           14784 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x19e90
 0x0000000000000007 (RELA)               0x17b38
 0x0000000000000008 (RELASZ)             9048 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x17a78
 0x000000006fffffff (VERNEEDNUM)         3
 0x000000006ffffff0 (VERSYM)             0x1727c
 0x000000006ffffff9 (RELACOUNT)          4
 0x0000000000000000 (NULL)               0x0

然而lib1的构建和链接很好,而依赖于lib2的{​​{1}}链接到其测试或任何其他库时却遇到问题。我在这一点上一无所知,不知道是什么原因造成的。我想念什么?

更新1

这是lib1https://paste.ee/p/pOgFk 头文件就是这样的:

lib2_test.cpp

关于评论,您可以看到#ifndef Lib2_H #define Lib2_H /* If we are we on Windows,we want a single define for it.*/ #if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)) #define _WIN32 #endif /* _WIN32 */ #if defined(_WIN32) && defined(_Lib2_BUILD_DLL) /* We are building Lib2 as a Win32 DLL */ #define LIB2_API __declspec(dllexport) #elif defined(_WIN32) && defined(Lib2_DLL) /* We are calling Lib2 as a Win32 DLL */ #define LIB2_API __declspec(dllimport) #elif defined(__GNUC__) && defined(_Lib2_BUILD_DLL) /* We are building Lib2 as a shared / dynamic library */ #define LIB2_API __attribute__((visibility("default"))) #else /* We are building or calling Lib2 as a static library */ #define LIB2_API #endif #include <string> #include <vector> #include <map> #include <memory> #include <opencv2/core.hpp> enum class ValidationStatus { None = -1,UnderValidation = 0,Validated = 1,Invalidated = 2,AnomalyDetected = 3,ToomuchAnonalyDetected = 4 }; typedef std::tuple<ValidationStatus,std::string,bool> Lib2Result; class Lib2Impl; class LIB2_API Lib2 { private: std::shared_ptr<Lib2Impl> Lib2; public: Lib2(std::string shape_predictor_path = "",std::string eyeNet_path = "",int valid_presence_delay = 5,int fpasPassed = 0); std::vector<Lib2Result> Run(std::map<std::string,bool>& validity_result,std::vector<std::tuple<std::string,float>>& ids,std::vector<cv::Mat>& faces,cv::Mat& originalImage,bool show_debug_info=false); Lib2Result Evaluate(bool& status,std::string& name,float& theta,cv::Mat& face_image,bool debug_info = true); ~Lib2(); }; #endif // !Lib2_H 上的调用是正常的,并且使用相同的签名。

更新2

我还需要添加它,该项目在Windows中使用Visual Studio构建得很好,也可以使用cmake!但是在 Linux(ubuntu 20.04),我正在面对这些问题。因此,这不仅是调用不同/错误的方法或具有错误的签名。该代码应该可以编译和链接,但是我在这里做错了什么,我不确定它是什么。

注释2

lib1和lib2只是由实际文件名组成的名称(我只是选择lib1和lib2来简化内容,并在此处替换了名称,因此,如果您发现大小写有所不同,请不要介意实际文件名一样。

解决方法

摘要

第三方lib(火炬)是使用Pre-cxx11 ABI构建的,显然,使用该库构建的lib无法链接到使用cxx11 ABI的对象!

详细说明

经过数小时的调试,这些代码在Visual Studio和CMake中都可以在Windows中正常工作,而在Linux中却令人头痛,我找到了罪魁祸首!

libtorch附带了两种类型的构建Pre-cxx11cxx11 ABI! 它使用的是Python软件包(torch1.6cpu)随附的Pre-cxx11构建的库,并且由于Anaconda3在Path中,并且我也使用它来构建库,所以我遇到了这个问题。

所有这些时间后,遗忘了未定义方法的怪异参数:std::__cxx11::basic_string,这里应该只是std::string。我没想到这两者会有所不同,并以为,那是g ++直到现在才使用的奇怪的命名方案,这让我说,让我们进行搜索,也许我可以从中找到一些东西!瞧!就是这种情况:

如果收到关于未定义符号引用的链接器错误, 在std :: __ cxx11命名空间或标记[abi:cxx11]中涉及类型 那么可能表明您正在尝试将对象链接在一起 使用不同值编译的文件 _GLIBCXX_USE_CXX11_ABI宏。当链接到使用旧版GCC编译的第三方库时,通常会发生这种情况。如果 第三方库无法使用新的ABI重建,那么您 将需要使用旧的ABI重新编译代码。

ref

要解决此问题,我只是在所有libs创建中直接使用了libtorch cxx11,就这样做了。含义,与Pytorch官方文档中显示的内容不同。不要做:

cmake -DCMAKE_PREFIX_PATH="$(python -c 'import torch.utils; print(torch.utils.cmake_prefix_path)')" ..

如果您像我一样期望通过cxx11来构建库,那么这样做会彻底崩溃!因为他们还没有!

因此,如果您使用的是Linux,只需使用CXX11 ABI抓取并使用预构建的库!并避免Pytorch附带的东西!

注意

如果您使用Pybind11和libtorch构建Python扩展,请确保您的Pytorch也使用GLIBCXX_USE_CXX11_ABI=1构建,否则由于您现在知道的原因,您将看到未定义的引用!您可以通过在terminal / cmd中运行以下代码片段来简单地进行检查:

python -c "import torch; print(f'GLIBCXX_USE_CXX11_ABI = {int(torch._C._GLIBCXX_USE_CXX11_ABI)}')"

基于information provided here的conda软件包(仅限cuda构建)应随GLIBCXX_USE_CXX11_ABI=1一起提供。我使用pip和conda测试了1.6cpu,但它们都报告了GLIBCXX_USE_CXX11_ABI = 0。因此请注意。

如果您碰巧需要从源代码进行构建,则可以遵循this guide

关于Pytorch为什么这样运送:

我们设置了该标志,因为我们使用的是gcc 4.9.x, 旧的ABI。在GCC 5.1中,更改了std :: string的ABI,并且 使用gcc> = 5.1编译的二进制文件与ABI不兼容 除非您设置该标志,否则二进制文件的gcc ref

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-