确定用于在*ix操作系统上构建共享对象的编译器和版本
Determining compiler and version used to build a shared object on *ix operating system
我在一些软件上工作,这些软件加载一组用户指定的共享对象。我想向我们的"加载器"组件添加一些代码,这些代码可以查询每个指定的共享对象并找出用于构建/链接共享对象的编译器和编译器版本。
在过去,我已经能够使用"strings-a|grep"方法,如下所示。然而,这种方法不适用于在powerAIX上使用g++4.8编译的代码,对于在x86Linux上使用g++4.8编译的代码来说,它的工作效果不是特别好。
如果可能的话,我也想找到一些比查找字符串更干净的方式来获取这些信息。
有人能就如何在共享对象中查询构建该对象的编译器的名称以及该编译器的版本提供建议吗
以下是我当前技术的一些命令和输出示例:
在x86 linux g++4.1编译的共享对象上:
$ strings -a libshareme.so | grep GNU
GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-50)
<etc>
(这里有很多重复输出,但很明显版本是GCC 4.1.2)
在强大的AIX xlC v11编译对象上
$ strings -a libshareme.so | grep XL
XL
IBM XL C/C++ for AIX, Version 11.1.0.6
IBM XL C/C++ for AIX, Version 10.1.0.6
(显示v11和v10有点令人困惑,但XL C很清楚)
在x86 linux g++4.8编译的共享对象上:
$ strings -a libshareme.so | grep GNU
GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4)
GCC: (GNU) 4.8.2 20131111 (Red Hat 4.8.2-4)
GNU C++ 4.8.2 20131111 (Red Hat 4.8.2-4) -m32 -mtune=generic -march=i686 -g -fmessage-length=0 -fPIC
(这里也有点令人困惑,因为它显示了多个版本)
在一个强大的AIX g++4.8编译对象上
$ strings -a libshareme.so | grep GNU
<no output>
在x86/linux上,我通常在字符串中看到一个"GNU"类型的字符串,这是我可以匹配的输出。然而,在这个使用g++4.8在power/aix上编译的libshareme.so上使用字符串-a并没有向我展示任何关于编译器版本的明显信息。
多亏了一位同事,我发现了这种方法,可以检测库是否在AIX上使用g++编译:
dump -X32_64 -Tv libshareme.so | grep libgcc
[1] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __cxa_finalize
[2] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __register_frame_info_table
[3] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __deregister_frame_info
[4] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __cmpdi2
[5] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __gcc_qdiv
[6] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __udivdi3
[7] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) _Unwind_Resume
[635] 0x20118d70 .data EXP DS Ldef [noIMid] __init_aix_libgcc_cxa_atex
it
这种方法加上最初问题中的方法,基本上可以让我编写代码,检测编译器(至少是我正在使用的编译器)以及加载失败期间编译器的任何潜在不匹配。
不可能万无一失地实现您想要实现的目标。您有时可能能够找到编译器的随机符号或某些编译器标志,但肯定没有获得这些信息的通用方法。而且这些信息中的大多数根本不存在于对象文件中(例如,据我所知,没有一个编译器会将使用的编译器标志存储到对象文件中)。
您可以看看其他包的作者做了什么,我首先检查Perl。Perl使用自己的"./configure"脚本,该脚本收集不同工具的路径和要与它们一起使用的标志,然后在编译Perl二进制文件和提供的标准模块时使用这些信息。这些信息也被编译成perl二进制文件,为了方便起见,可以稍后打印(perl -V
),或者用于通过perl自己的make-helper库编译"匹配"的额外perl模块(请参阅perl Makefile.PL
)。即使是perl的功能也不是万无一失的,因为您可能会尝试加载不兼容编译/链接的共享库。
- 如何从具有移动语义的类对象中生成共享指针
- 使用共享指针的函数调用,其对象应为 const
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 在共享缓冲区内存中创建 ::std::string 对象
- 如何创建一个共享对象与另一个.所以在Cmake
- 内联函数的函数本地静态对象是否在共享对象文件之间共享?
- 有没有办法列出所有共享内存对象的名称?
- 共享的从属对象
- 在 Android Studio 中使用 C++ 共享对象时出现问题
- 共享对象、符号、C/C++ 库链接和加载
- ./main:加载共享库时出错:libopencv_highgui.so.4.0:无法打开共享对象文件:没有这样的文件或
- 在 win32 上生成 R 包:无法加载共享对象 (.dll)
- C++对象共享属性 - 使用指针或引用
- 如何测试共享对象/共享库已正确编译
- 创建对象共享指针以共享指针为参数
- 限制C++中虚拟基类的对象共享
- 在Ada95中跨共享库/对象共享数据
- 这种线程间对象共享策略是否合理
- 如何更改对象共享指针指向,而它被其他线程占用
- 初始化仅由一组对象共享的静态变量