最近在Linux下编译项目时碰到了这个问题,同样的makefile,只要不编译成动态库就不会有这个问题,但要编译成动态库就老是出这个问题.
后来才发现,是-fPIC选项的问题,因为我静态链接了第三方库mupdf库,mupdf库在编译时是没有用到-fPIC选项的,而我自己的项目编译时用了-fPIC选项。之后我修改了mupdf库的makefile,在编译mupdf静态库时,添加了-fPIC选项,编译完成再和自己的项目链接时,就没有这个问题了。
问题
在使用makefile过程中遇到了这样的报错:
/usr/bin/ld: ./obj/libtest.o: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4 which may bind externally can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: ./obj/libtest.o(.text.startup+0x34): unresolvable R_AARCH64_ADR_PREL_PG_HI21 relocation against symbol _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4
make -f LibMakefile_aarch64
make[1]: 进入目录“/home/huanghe/Desktop/WSDK_Linux/samples”
g++ -std=c++11 -c -I../include ./src/libtest.cpp -Os -D_FX_OS_=_FX_LINUX_DESKTOP_
./src/libtest.cpp: In function ‘int scan_image()’:
./src/libtest.cpp:177:43: warning: ISO C++ forbids converting a string constant to ‘GCH_LPSTR’ {aka ‘char*’} -Wwrite-strings]
char *devlist = gch_GetDevicesList(";"); //返回 型号1;型号2; 需要自行分隔
^
./src/libtest.cpp:315:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
g++ -fPIC -shared -o .//libtest.so ./obj/*.o -L../lib/aarch64 -Xlinker "-(" -Wl,-rpath=../lib/aarch64/ -lScanImagesdk[aarch64] -Xlinker "-)" -lz -ldl # -fopenmp -lfontconfig
/usr/bin/ld: ./obj/libtest.o: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `_ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4' which may bind externally can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: ./obj/libtest.o(.text.startup+0x34): unresolvable R_AARCH64_ADR_PREL_PG_HI21 relocation against symbol `_ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4'
/usr/bin/ld: 最后的链结失败: bad value
collect2: error: ld returned 1 exit status
make[1]: *** [LibMakefile_aarch64:42:all] 错误 1
make[1]: 离开目录“/home/huanghe/Desktop/WSDK_Linux/samples”
make: *** [Makefile:20:default] 错误 2
解决
-
加上-mcmodel=large编译选项
-mcmodel=large使可执行文件使用64位绝对地址访问数据段,这会减慢内核速度并使其更大。 -
加上 -O2
#Winmage WSDK project DEMO for aarch64 CPU
#
# Tools.
CC = gcc
LD = gcc
RM = -/bin/rm -f
#
# Parameters for tools.
REL_FLAGS = -Os -D_FX_OS_=_FX_LINUX_DESKTOP_
# Parameters for the current project.
SRC_DIR = ./src
SOURCES = $(SRC_DIR)/libtest.cpp $(SRC_DIR)/json.hpp
OBJ_DIR = ./obj
REL_BIN_DIR = ./
LIB_DIR = ../lib/aarch64
INC_DIRS = -I../include #-I/usr/local/Trolltech/Qt-4.8.7/include
REL_DIRS = -L$(LIB_DIR)
REL_LIBS = -Xlinker "-(" -Wl,-rpath=../lib/aarch64/ -lScanImagesdk[aarch64] -Xlinker "-)"
REL_OBJ_DIR = $(OBJ_DIR)
REL_BIN = libtest.so
#
all: $(SOURCES)
$(CC) -O2 -mcmodel=large -c $(CFLAGS) $(INC_DIRS) $(SOURCES) $(REL_FLAGS)
@-mkdir -p $(REL_OBJ_DIR)
@mv *.o $(REL_OBJ_DIR)
@-mkdir -p $(REL_BIN_DIR)
$(LD) -O2 -mcmodel=large -fPIC -shared -o $(REL_BIN_DIR)/$(REL_BIN) $(REL_OBJ_DIR)/*.o $(REL_DIRS) $(REL_LIBS) -lz -ldl # -fopenmp -lfontconfig
#
clean:
$(RM) $(REL_BIN_DIR)/$(REL_BIN) $(REL_OBJ_DIR)/*.o *.o
参考:
无法解决R_AARCH64_ADR_PREL_PG_HI21重定向于符号__stack_chk_guard@GLIBC_2.17