将静态(.a)库与共享(.so)库链接,针对本地符号获取错误“重定位 R_X86_64_32S";用 -fPIC"重新编译 [英] linking a static(.a) library with a shared (.so) library, getting error "relocation R_X86_64_32S against a local symbol; recompile with -fPIC"
问题描述
使用 eclipse 在 redhat 中用 g++ 64 位编译.
Compiling with g++ 64 bit in redhat using eclipse.
编译错误:../lib-EL5-64bit/libskd3_clnt_30134500.a(skd_clnt.o):制作共享对象时不能使用针对本地符号"的重定位R_X86_64_32S;用 -fPIC 重新编译
Compile Error: ../lib-EL5-64bit/libskd3_clnt_30134500.a(skd_clnt.o): relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC
我尝试过的事情我将 -fPIC 添加到 C++ 编译器标志以及链接器标志中.它已经存在于编译器标志中,我只是将它直接移到 g++ 之后,以及列表的末尾.
Things I have tried I added -fPIC to both the c++ compiler flags, as well as the linker flags. It already existed in the compiler flags, i just moved it to directly after the g++, and at the end of the list.
我已经要求 .a 库的创建者使用 -fPIC 重新编译,但它仍然给出相同的错误
I've asked the creator of the .a library to recompile with -fPIC and it still gives the same error
有什么方法可以确保他们的库是用 -fPIC 编译的?错误消息是说我需要用 -fPIC 编译我的 .so,还是需要用 -fPIC 编译 .a 文件?我还能检查什么?
Is there any way to make sure that their library was compiled with -fPIC? Does the error message say that I need to compile my .so with -fPIC, or the .a file needs to be compiled with -fPIC? What else can I check?
这里是make文件(由eclipse自动生成)
Here is the make file (auto generated by eclipse)
制作文件:
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
-include ../makefile.init
RM := rm -rf
# All of the sources participating in the build are defined here
-include sources.mk
-include subdir.mk
-include generic_d2s/subdir.mk
-include objects.mk
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C++_DEPS)),)
-include $(C++_DEPS)
endif
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
ifneq ($(strip $(CC_DEPS)),)
-include $(CC_DEPS)
endif
ifneq ($(strip $(CPP_DEPS)),)
-include $(CPP_DEPS)
endif
ifneq ($(strip $(CXX_DEPS)),)
-include $(CXX_DEPS)
endif
ifneq ($(strip $(C_UPPER_DEPS)),)
-include $(C_UPPER_DEPS)
endif
endif
-include ../makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
# All Target
all: libFUSE.so
# Tool invocations
libFUSE.so: $(OBJS) $(USER_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GCC C++ Linker'
g++ -fPIC -L../../CRYPTOPP/lib-EL5-64bit -L../lib-EL5-64bit -Wl,-rpath /lib -shared -o"libFUSE.so" $(OBJS) $(USER_OBJS) $(LIBS)
@echo 'Finished building target: $@'
@echo ' '
# Other Targets
clean:
-$(RM) $(OBJS)$(C++_DEPS)$(C_DEPS)$(CC_DEPS)$(LIBRARIES)$(CPP_DEPS)$(CXX_DEPS)$(C_UPPER_DEPS) libFUSE.so
-@echo ' '
.PHONY: all clean dependents
.SECONDARY:
-include ../makefile.targets
子目录.mk
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
CPP_SRCS +=
../CRI.cpp
C_SRCS +=
../client_rsa.c
OBJS +=
./CRI.o
C_DEPS +=
./client_rsa.d
CPP_DEPS +=
./CRI.d
# Each subdirectory must supply rules for building sources it contributes
%.o: ../%.cpp
@echo 'Building file: $<'
@echo 'Invoking: GCC C++ Compiler'
g++ -D_TM_CDIR='"/proj/kronos/test/hho/testprograms/trunk/testmethods/FUSE"' -I../../CRYPTOPP/include/cryptopp -I"/opt/hp93000/soc/pws/lib" -I"/opt/hp93000/soc/com/include" -I/opt/hp93000/soc/prod_com/include -I/opt/hp93000/soc/prod_com/include/MAPI -I/opt/hp93000/soc/testmethod/include -O0 -g3 -Wall -c -fmessage-length=0 -shared -fPIC -Wreturn-type -Wmissing-braces -Wparentheses -Wswitch -Wunused-function -Wunused-label -Wunused-parameter -Wunused-variable -Wunused-value -Wunknown-pragmas -Wsign-compare -Wconversion -fPIC -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
@echo 'Finished building: $<'
@echo ' '
%.o: ../%.c
@echo 'Building file: $<'
@echo 'Invoking: GCC C Compiler'
gcc -D_TM_CDIR='"/proj/kronos/test/hho/testprograms/trunk/testmethods/FUSE"' -I/opt/hp93000/soc/prod_com/include -I/opt/hp93000/soc/prod_com/include/MAPI -I/opt/hp93000/soc/testmethod/include -I/opt/hp93000/soc/com/include -I/opt/hp93000/soc/pws/lib -O0 -g3 -Wall -c -fmessage-length=0 -fPIC -Wreturn-type -Wmissing-braces -Wparentheses -Wswitch -Wunused-function -Wunused-label -Wunused-parameter -Wunused-variable -Wunused-value -Wunknown-pragmas -Wsign-compare -Wconversion -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
@echo 'Finished building: $<'
@echo ' '
objects.mk
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
USER_OBJS :=
LIBS := -lBB_IO_lib.0.1 -lskd3_clnt_30134500 -lcryptopp
sources.mk
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
O_SRCS :=
CPP_SRCS :=
C_UPPER_SRCS :=
C_SRCS :=
S_UPPER_SRCS :=
OBJ_SRCS :=
ASM_SRCS :=
CXX_SRCS :=
C++_SRCS :=
CC_SRCS :=
OBJS :=
C++_DEPS :=
C_DEPS :=
CC_DEPS :=
LIBRARIES :=
CPP_DEPS :=
CXX_DEPS :=
C_UPPER_DEPS :=
# Every subdirectory with source files must be described here
SUBDIRS :=
.
generic_d2s
推荐答案
当您进行静态编译时,汇编器指令将假定有关代码局部性的某些事情,例如任何跳转都在跳转/调用指令的 4GB 以内.(假设 64b x86).共享库可能加载到超过 4GB 的地方,因此跳转/调用不适合.
When you compile statically, the assembler instructions will assume certain things about the locality of code, e.g. any jump is within 4GB of the jumping/calling instruction. (Assuming 64b x86). Shared libraries may be loaded further away than 4GB, so that jump/call wont fit.
当您使用 -fPIC(位置无关代码)编译时 - 编译器将确保代码和本地数据引用位置无关,并安排在最坏情况/最大寻址模式下发生的调用/跳转完整的 64b).
When you compile with -fPIC (position independent code) - the compiler will ensure that the code and local data references are position indepdent, and arrange for calls/jumps outside of itself happen with the worst case/maximum addressing mode (eg full 64b).
当您收到此错误时,如您所见,静态库无法跳转到共享库 - 采取了上述快捷方式.唯一的解决方案是使用 -fPIC 重新编译.(从技术上讲,32 位跳转可能只有 5 个字节,但您需要 9 个字节 [1 个操作码 + 8 个用于 addr];因此,没有多少汇编器的聪明才智可以解决这个问题 - 不是没有其他一些卑鄙的操作,例如使用 INT 指令提供短手跳跃).
When you get this error, as you have, the static library cannot jump to the shared library - the shortcuts above were taken. The only solution is a recompile with -fPIC. (Technically, the 32-bit jump may only be 5 bytes but you need 9 bytes [1 opcode + 8 for the addr]; so no amount of assembler cleverness can work around this - not without some other dastardly operation, like using INT instructions to provide a short hand jump).
如今,大多数东西都可以/应该使用 -fPIC 进行编译,无论是否共享 - 除非性能很重要.
Nowadays most everything can/should be compiled with -fPIC irrespective of being shared - unless performance is important.
这篇关于将静态(.a)库与共享(.so)库链接,针对本地符号获取错误“重定位 R_X86_64_32S";用 -fPIC"重新编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!