我公司最近想把编译器从gcc-3.4更新到gcc-4.5。但是,我们客户的机器可能没有最新的 libstdc++.so
,所以我们想静态链接我们的二进制文件。
我们的程序需要定制的 malloc()/free()
以满足非常高的性能要求。
我修改了 makefile,在链接时添加了一个 -static
,得到了以下错误信息:
/usr/lib64/libc.a(malloc.o)(.text+0x18c0): In function `free':
: multiple definition of `free'
../../ic/src/memmgr/libmemmgr_mt_thread.a(memmgr_mt_thread.o)(.text+0x3430): first defined here
/usr/bin/ld: Warning: size of symbol `free' changed from 271 in ../../ic/src/memmgr/libmemmgr_mt_thread.a(memmgr_mt_thread.o) to 255 in /usr/lib64/libc.a(malloc.o)
/usr/lib64/libc.a(malloc.o)(.text+0x3970): In function `malloc':
: multiple definition of `malloc'
../../ic/src/memmgr/libmemmgr_mt_thread.a(memmgr_mt_thread.o)(.text+0x29c0): first defined here
/usr/bin/ld: Warning: size of symbol `malloc' changed from 281 in ../../ic/src/memmgr/libmemmgr_mt_thread.a(memmgr_mt_thread.o) to 461 in /usr/lib64/libc.a(malloc.o)
/usr/lib64/libc.a(malloc.o)(.text+0x4050): In function `realloc':
: multiple definition of `realloc'
../../ic/src/memmgr/libmemmgr_mt_thread.a(memmgr_mt_thread.o)(.text+0x3e80): first defined here
/usr/bin/ld: Warning: size of symbol `realloc' changed from 335 in ../../ic/src/memmgr/libmemmgr_mt_thread.a(memmgr_mt_thread.o) to 927 in /usr/lib64/libc.a(malloc.o)
好的,这是合理的,因为 libc.a
已经有 malloc()/free()
。
但是令我困惑的是为什么动态链接时没有错误。我搜索了一下,发现了这个问题:How to redefine malloc() in Linux for use in C++ new .答案是链接器以不同方式处理库文件 (.a) 和目标文件 (.o)。现在我知道错误发生在静态链接而不是动态链接的原因了。
不过,我尝试了那个答案中描述的解决方案,直接用目标文件替换库文件,但没有区别。我仍然遇到多重定义链接错误。我也尝试了 -static-libgcc
(因为我不知道该怎么做,我只是尝试了我在 gcc
手册页中看到的所有内容)但它也无济于事.
我不必使用静态链接。我只是想解决libstdc++.so
版本问题。任何建议将不胜感激。
提前致谢。
编辑:对不起,我没有说清楚。使用 #define malloc ...
在这里可能无济于事。因为我们的程序是C++。 #define
习惯用法只能影响malloc()/free()
函数。但是我们的程序实际上使用 new/delete
来分配/释放内存。还是谢谢 :D
最佳答案
如果您最关心的是 libstdc++.so 在目标系统中的可用性,那么为什么不简单地将它的较新版本与您的应用程序一起分发呢?
我认为静态链接在任何情况下都不是一个好的解决方案,编译项目变得更加困难,如果你自己使用共享对象(例如当使用你自己的插件时),那么静态链接将停止工作,因为静态库的单独拷贝 需要链接到您的二进制文件、可执行文件等的每个。你能想象如果加载时同一个程序中有多个全局变量、锁等实例会发生什么吗?我会告诉你:崩溃。
所以不要静态链接,把libstdc++.so复制到私有(private)目录下(我不知道你的应用安装在哪里,但如果它有私有(private)前缀,那很简单,使用$prefix/lib)。
然后要么设置 LD_LIBRARY_PATH,要么使用 -rpath 将路径编码为二进制文件,以便链接器找到它。当然,这意味着您链接的所有库(也可能使用 libstdc++)也应该与您的应用程序一起分发。
但就大小而言,它大致相同,通过静态链接您也可以携带该代码。
关于c++ - 重新定义 malloc/free with static linking has multiple definition error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5576387/