学习笔记:relocation R_X86_64_32 against `.rodata‘ can not be used when making a shared object;

解决多个.a静态库,链接成一个.so动态库出现:



relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; 的错误。

我的总目标是:写一个mainApi.cpp的文件,这个文件提供API给外部用户使用。mainApi.cpp需要依赖其他模块生成的静态库(在lib文件下)。将mainApi.cpp编译

链接成一个.so动态库共外部使用。在编译的时候出现relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; 的错误。

原因是因为生成静态库时没有加 -fPIC 选项。

问题解决是如下(红色字体部分):

ifeq ($(MK_STATIC_LIB),no)
    TARGET = libSendMsgModel.so
    CFLAGS += -fPIC             # 静态库链接成.so动态库,编译静态库的时候需要加 -fPIC这个参数。
else
    TARGET = libSendMsgModel.a
endif

看下最后的实现目标(在主目录下生成libSendMsgModel.so文件):

看看lib下的文件:

主目录下的Makefile:

XX = g++
AR = ar
ARFLAG = -rcs
CFLAGS = -g 

CLIBS = -L./lib/ -lSender -lReceiver -lResponser -lListener -lLogout -lpthread -lrt

SUBDIRS = ./logout ./receiver ./responser ./sender ./listener 
 # INCLUDE = a.h b.h ... can't be defined like "INCLUDE = ./*.h"
INCLUDES = $(wildcard ./include/*.h ./sender/*.h ./receiver/*.h ./responser/*.h)
#指定头文件目录,代码中就不需要把头文件的完整路径写出来了
INCLUDE_DIRS = -I./include -I./sender/ -I./receiver/ -I./responser/ -I./listener -I./logout 

OBJECTS = mainApi.o

export XX CFLAGS AR ARFLAG

ifeq ($(MK_STATIC_LIB),no)
    TARGET = libSendMsgModel.so
    CFLAGS += -fPIC             # 静态库链接成.so动态库,编译静态库的时候需要加 -fPIC这个参数。
else
    TARGET = libSendMsgModel.a
endif

ifeq ($(MK_STATIC_LIB),no)
$(TARGET) : $(OBJECTS) $(SUBDIRS)
	$(XX) $(CFLAGS) -shared -fPIC $< -o $@ $(CLIBS)     # $< 表示依赖列表的第一个 也就是 $(OBJECTS)
	
$(OBJECTS) : %.o : %.cpp 
	$(XX) -c $(CFLAGS) $< -o $@ $(INCLUDE_DIRS)
else
$(TARGET) : $(OBJECTS) $(SUBDIRS)
	$(AR) $(ARFLAG) $@ $<     # $< 表示依赖列表的第一个 也就是 $(OBJECTS)
	
$(OBJECTS) : %.o : %.cpp 
	$(XX) -c $(CFLAGS) $< -o $@ $(INCLUDE_DIRS)
endif
	
$(SUBDIRS):ECHO
	+$(MAKE) -C $@

ECHO:
	@echo $(SUBDIRS)
	@echo begin compile

.PHONY : clean
clean:
	for dir in $(SUBDIRS);\
	do $(MAKE) -C $$dir clean||exit 1;\
	done
	rm -rf $(TARGET) $(OBJECTS)  ./lib/*.a

receiver子目录下的Makefile: 

LIB_DIR = ./../lib/
TOP_DIR = ./..

SOURCES = $(wildcard ./*.cpp)
INCLUDE_DIRS = -I$(TOP_DIR)/include  -I$(TOP_DIR)/responser/ -I./ #指定头文件目录,代码中就不需要把头文件的完整路径写出来了

TARGET = libReceiver.a
OBJECTS = $(patsubst %.cpp,%.o,$(SOURCES))

$(TARGET) : $(OBJECTS)
	$(AR) $(ARFLAG) $@ $^
	cp $@ $(LIB_DIR)
	
$(OBJECTS) : %.o : %.cpp 
	$(XX) -c $(CFLAGS) $< -o $@ $(INCLUDE_DIRS)

.PHONY : clean
clean:
	rm -rf $(TARGET) $(OBJECTS) 

对学习Makefile感兴趣的可以到github上下载我的工程看看:https://github.com/fanchenxinok/Makefile_models

记得双击五角星666 哈哈哈 

  • 18
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值