我正在使用c ++ -shared(在x86_64上运行gcc)创建一个共享库。我无法将问题排除在最小的测试用例之外,但我遇到的问题是我在一堆.o文件中创建了一个.so。其中一个.o文件导出一个符号(nm显示'D'),我想从.so导出。 .o的其他部分需要该符号(nm表示'U')。结果,链接器使得该符号在结果.so中是局部的(nm显示为'd')。
如果我从命令行中删除了要求的.o,则.so 会导出符号。因此,似乎链接器决定,因为用于构建.so的其他.o需要符号,它们必须仅才需要那些.o's并且它不需要实际导出。
当我尝试构建一个最小的测试用例时,它不会这样工作;无论我是否添加需要它的.o,都会导出符号。
我的完整命令行是:
c++ -fno-rtti -fno-exceptions -Wall -Wpointer-arith -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -Wcast-align -Wno-invalid-offsetof -Wno-variadic-macros -pedantic -Wno-long-long -gdwarf-2 -fno-strict-aliasing -pthread -pipe -DDEBUG -D_DEBUG -DDEBUG_sfink -DTRACING -gdwarf-2 -fPIC -shared -Wl,-z,defs -Wl,-h,libmozjs.so -o libmozjs.so jsapi.o jsarena.o jsarray.o jsatom.o jsbool.o jscntxt.o jsdate.o jsdbgapi.o jsdhash.o jsdtoa.o jsemit.o jsexn.o jsfun.o jsgc.o jsgcchunk.o jshash.o jsinterp.o jsinvoke.o jsiter.o jslock.o jslog2.o jsmath.o jsnativestack.o jsnum.o jsobj.o json.o jsopcode.o jsparse.o jsproxy.o jsprf.o jspropertycache.o jspropertytree.o jsregexp.o jsscan.o jsscope.o jsscript.o jsstr.o jstask.o jstypedarray.o jsutil.o jswrapper.o jsxdrapi.o jsxml.o prmjtime.o jsdtracef.o jstracer.o Assembler.o Allocator.o CodeAlloc.o Containers.o Fragmento.o LIR.o njconfig.o RegAlloc.o avmplus.o NativeX64.o jsbuiltins.o VMPI.o CTypes.o Library.o mozjs-dtrace.o -lpthread -Wl,-rpath-link,/bin -Wl,-rpath-link,/lib -Wl,--whole-archive ctypes/libffi/.libs/libffi.a -Wl,--no-whole-archive -L/home/sfink/moz-central/obj-dtrace/dist/lib -lplds4 -lplc4 -lnspr4 -lpthread -ldl -ldl -lm -lm -ldl
我使用这个调用的核心命令获得了相同的行为(我还手动删除了一些不相关的标志):
/usr/bin/ld --no-add-needed --eh-frame-hdr --build-id -m elf_x86_64 --hash-style=gnu -shared -o libmozjs.so /usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.4.4/crtbeginS.o -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../.. jsapi.o jsarena.o jsarray.o jsatom.o jsbool.o jscntxt.o jsdate.o jsdbgapi.o jsdhash.o jsdtoa.o jsemit.o jsexn.o jsfun.o jsgc.o jsgcchunk.o jshash.o jsinterp.o jsinvoke.o jsiter.o jslock.o jslog2.o jsmath.o jsnativestack.o jsnum.o jsobj.o json.o jsopcode.o jsparse.o jsproxy.o jsprf.o jspropertycache.o jspropertytree.o jsregexp.o jsscan.o jsscope.o jsscript.o jsstr.o jstask.o jstypedarray.o jsutil.o jswrapper.o jsxdrapi.o jsxml.o prmjtime.o jsdtracef.o jstracer.o Assembler.o Allocator.o CodeAlloc.o Containers.o Fragmento.o LIR.o njconfig.o RegAlloc.o avmplus.o NativeX64.o jsbuiltins.o VMPI.o mozjs-dtrace.o -lnspr4 -lstdc++ -lm -lgcc_s -lpthread -lc -lgcc_s /usr/lib/gcc/x86_64-redhat-linux/4.4.4/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../lib64/crtn.o
更新:可能更重要的是,这些符号位于不同的部分,并具有隐藏的可见性。使用objcopy使它们全局化并没有帮助。我不知道哪些部分用于什么规则。