【问题标题】:linking a static(.a) library with a shared (.so) library, getting error "relocation R_X86_64_32S against a local symbol; recompile with -fPIC"将静态 (.a) 库与共享 (.so) 库链接,出现错误“针对本地符号重新定位 R_X86_64_32S;使用 -fPIC 重新编译”
【发布时间】:2013-05-15 22:13:20
【问题描述】:

使用 eclipse 在 redhat 中使用 g++ 64 位编译。

编译错误: ../lib-EL5-64bit/libskd3_clnt_30134500.a(skd_clnt.o):制作共享对象时不能使用针对“本地符号”的重定位R_X86_64_32S;用 -fPIC 重新编译

我尝试过的事情 我在 c++ 编译器标志和链接器标志中都添加了 -fPIC。它已经存在于编译器标志中,我只是将它直接移到 g++ 之后,并在列表的末尾。

我已经要求 .a 库的创建者使用 -fPIC 重新编译,它仍然给出相同的错误

有什么方法可以确保他们的库是用 -fPIC 编译的? 错误消息是说我需要用 -fPIC 编译我的 .so,还是需要用 -fPIC 编译 .a 文件? 我还能检查什么?

这里是make文件(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 \

【问题讨论】:

  • 存档 (.a) 必须使用 -fPIC 重新编译。

标签: c++ eclipse 64-bit fpic


【解决方案1】:

当您进行静态编译时,汇编器指令将假定有关代码局部性的某些事情,例如任何跳转都在跳转/调用指令的 4GB 范围内。 (假设 64b x86)。共享库的加载可能超过 4GB,因此跳转/调用不适合。

当您使用 -fPIC(与位置无关的代码)进行编译时 - 编译器将确保代码和本地数据引用与位置无关,并安排在最坏情况/最大寻址模式下发生自身之外的调用/跳转(例如完整的 64b)。

当您遇到此错误时,静态库无法跳转到共享库 - 已使用上述快捷方式。唯一的解决方案是使用 -fPIC 重新编译。 (从技术上讲,32 位跳转可能只有 5 个字节,但您需要 9 个字节 [1 个操作码 + 8 个用于 addr];因此,再多的汇编程序也无法解决这个问题 - 并非没有其他一些卑鄙的操作,例如使用 INT 指令提供一个短手跳跃)。

现在大多数东西都可以/应该用 -fPIC 编译,无论是否共享 - 除非性能很重要。

【讨论】:

    猜你喜欢
    • 2018-12-27
    • 1970-01-01
    • 2017-07-23
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多