解决多个.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:


  1. XX = g++

  2. AR = ar

  3. ARFLAG = -rcs

  4. CFLAGS = -g

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

  6. SUBDIRS = ./logout ./receiver ./responser ./sender ./listener

  7. # INCLUDE = a.h b.h ... can't be defined like "INCLUDE = ./*.h"

  8. INCLUDES = $(wildcard ./include/*.h ./sender/*.h ./receiver/*.h ./responser/*.h)

  9. #指定头文件目录,代码中就不需要把头文件的完整路径写出来了

  10. INCLUDE_DIRS = -I./include -I./sender/ -I./receiver/ -I./responser/ -I./listener -I./logout

  11. OBJECTS = mainApi.o

  12. export XX CFLAGS AR ARFLAG

  13. ifeq ($(MK_STATIC_LIB),no)

  14. TARGET = libSendMsgModel.so

  15. CFLAGS += -fPIC # 静态库链接成.so动态库,编译静态库的时候需要加 -fPIC这个参数。

  16. else

  17. TARGET = libSendMsgModel.a

  18. endif

  19. ifeq ($(MK_STATIC_LIB),no)

  20. $(TARGET) : $(OBJECTS) $(SUBDIRS)

  21. $(XX) $(CFLAGS) -shared -fPIC $< -o $@ $(CLIBS) # $< 表示依赖列表的第一个 也就是 $(OBJECTS)

  22. $(OBJECTS) : %.o : %.cpp

  23. $(XX) -c $(CFLAGS) $< -o $@ $(INCLUDE_DIRS)

  24. else

  25. $(TARGET) : $(OBJECTS) $(SUBDIRS)

  26. $(AR) $(ARFLAG) $@ $< # $< 表示依赖列表的第一个 也就是 $(OBJECTS)

  27. $(OBJECTS) : %.o : %.cpp

  28. $(XX) -c $(CFLAGS) $< -o $@ $(INCLUDE_DIRS)

  29. endif

  30. $(SUBDIRS):ECHO

  31. +$(MAKE) -C $@

  32. ECHO:

  33. @echo $(SUBDIRS)

  34. @echo begin compile

  35. .PHONY : clean

  36. clean:

  37. for dir in $(SUBDIRS);\

  38. do $(MAKE) -C $$dir clean||exit 1;\

  39. done

  40. rm -rf $(TARGET) $(OBJECTS) ./lib/*.a

receiver子目录下的Makefile: 


  1. LIB_DIR = ./../lib/

  2. TOP_DIR = ./..

  3. SOURCES = $(wildcard ./*.cpp)

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

  5. TARGET = libReceiver.a

  6. OBJECTS = $(patsubst %.cpp,%.o,$(SOURCES))

  7. $(TARGET) : $(OBJECTS)

  8. $(AR) $(ARFLAG) $@ $^

  9. cp $@ $(LIB_DIR)

  10. $(OBJECTS) : %.o : %.cpp

  11. $(XX) -c $(CFLAGS) $< -o $@ $(INCLUDE_DIRS)

  12. .PHONY : clean

  13. clean:

  14. rm -rf $(TARGET) $(OBJECTS)

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

(127条消息) 学习笔记:relocation R_X86_64_32 against `.rodata‘ can not be used when making a shared object;_fanchenxinok的专栏-CSDN博客

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐