在已经使用fPIC的情况下创建共享库时,无法使用针对符号的R_X86_64_PC32重定位

问题描述

我看过许多有关解决此类链接错误文章,在大多数情况下,人们只是忘记使用-fPIC进行编译,有时人们在使用内联函数时遇到了麻烦,等等,在这里不是这种情况。我正在尝试使用Pybind11为python包装一个c ++库。在此过程中,我想将一些静态库(其中一个newmat11链接.so文件中。

我使用带有-fPIC自动制作系统来构建newmat11库(这是一些输出...)

...
g++ -DHAVE_CONfig_H -I. -g -O2 -MT newmat8.lo -MD -MP -MF .deps/newmat8.Tpo -c newmat8.cpp  -fPIC -DPIC -o newmat8.o
...
ar cru libnewmat11.a  bandmat.o cholesky.o evalue.o fft.o jacobi.o hholder.o myexcept.o newfft.o newmat1.o newmat2.o newmat3.o newmat4.o newmat5.o newmat6.o newmat7.o newmat8.o newmat9.o newmatex.o newmatrm.o solution.o sort.o submat.o svd.o

实际上,当我运行readelf --relocs libnewmat11.a时,我看到了很多重新定位的符号。这是一个给我带来麻烦的事情:

$readelf --relocs libnewmat11.a | grep ZTIN6NEWMAT17Sing
000000001d20  013c00000002 R_X86_64_PC32     0000000000000000 _ZTIN6NEWMAT17Singular - 4
Relocation section '.rela.data.rel.ro._ZTIN6NEWMAT17SingularExceptionE' at offset 0x21280 contains 3 entries:
000000005b0b  013c00000001 R_X86_64_64       0000000000000000 _ZTIN6NEWMAT17Singular + 0
0000000009fc  008d00000002 R_X86_64_PC32     0000000000000000 _ZTIN6NEWMAT17Singular - 4
Relocation section '.rela.data.rel.ro._ZTIN6NEWMAT17SingularExceptionE' at offset 0x20b38 contains 3 entries:
000000008280  008d00000001 R_X86_64_64       0000000000000000 _ZTIN6NEWMAT17Singular + 0
...

到目前为止,一切似乎都还不错,但是当我运行python3 setup.py build时,出现了此错误

running build
running build_py
running build_ext
building 'mytest' extension
x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I../.. -I../../mhfe -I/usr/include/python3.8 -I/usr/local/include/newmat11/include -c src/my_python_binding.cpp -o build/temp.linux-x86_64-3.8/src/my_python_binding.o -std=c++11 -DPYBIND11_PYTHON_VERSION=3.8
...
x86_64-linux-gnu-g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 -Wl,relro -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.8/src/my_python_binding.o -L/usr/lib64python3.8 -o build/lib.linux-x86_64-3.8/mytest.cpython-38-x86_64-linux-gnu.so -fPIC -Wl,--whole-archive /usr/local/lib/newmat11/lib/libnewmat11.a -Wl,--no-whole-archive
/usr/bin/ld: /usr/local/lib/newmat11/lib/libnewmat11.a(newmat8.o): relocation R_X86_64_PC32 against symbol `_ZTIN6NEWMAT17SingularExceptionE' can not be used when making a shared object; recompile with -fPIC

如上所述,我正在使用-fPIC构建静态库,并且可以在.a文件中看到重定位符号。 R_X86_64_PC32是否有某些与共享对象不兼容的东西?我想我需要让它产生R_X86_64_plt32重定位符号,但是我不确定。我可以在库中看到其他R_X86_64_plt32重定位符号,但有关符号却看不到。另外,根据记录,我对setuptools添加到构建中的所有标志并不熟悉,也许其中之一给我带来了麻烦?

感谢所有帮助。

解决方法

我找到了解决方法。

尽管我的构建使用-fPIC作为依赖库,但我注意到我没有在cp -R中使用TargetApp/www进行自动制作。我添加它只是为了看看会有什么不同。

echo "copying $SRCROOT/TargetApp/www to $TARGET_BUILD_DIR/$CONTENTS_FOLDER_PATH" cp -R "$SRCROOT/TargetApp/www" "$TARGET_BUILD_DIR/$CONTENTS_FOLDER_PATH" 现在显示:

--with-pic

这具有configure重定位符号类型。我还发现我的链接器错误已解决。

添加readelf --relocs后看不到编译标志的任何区别,因此在编译器级别,我不确定有什么区别。无论如何,希望这将对遇到类似问题的人有所帮助。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...