有没有办法知道哪个编译器生成了静态库?
第三方为我提供了一个静态库 (.a),用于在 Solaris 站上链接。 我尝试使用 sunpro 进行编译,但在链接步骤失败。
我想这个问题来自我使用的编译器(而不是 gcc?)或者只是它的版本(因为编译器提供的 std lib 可能会从库预期的版本发生变化,AFAIK 它可能会导致链接步骤中的错误)。
我怎么知道哪个编译器是用来生成这个库的? 有一些工具可以做到这一点吗? sunpro/gcc 或其他什么选项?
作为提示:我不久前读过,编译器在生成目标文件时使用不同的重整约定(真的吗?)。 尽管如此,“nm --demangle” 命令行还是可以很好地打印出此静态库中调试符号中的所有函数名称。 它是如何工作的 ? 如果我的假设没问题,那么 nm 确实有办法解决静态库中使用的约定,不是吗? 或者它只是意味着 lib 是由 GNU gcc 生成的,因为 nm 是 GNU binutils 的一部分?
我离我的工作站不近,所以我无法复制和复制它。 粘贴来自链接器的错误输出(暂时不是,但我可以在进一步编辑中复制它们)
A third party provided me a static lib (.a) to link with on solaris station.
I tried to compile with sunpro, and failed at link step.
I suppose the issue is coming from the compiler I use (gcc instead?) or simply its version (as the std lib provided by the compiler could change from the version expected by the library AFAIK it could leads to errors at link step).
How could I know which compiler was used to generate this lib? Is there some tools doing that? Some option in sunpro/gcc or whatever?
As an hint: I've read some time ago that compilers use different mangling conventions when generating object files (true?). Still, "nm --demangle" command line prints me well all function names from debug symbols in this static lib. How does it work ? If my assumption is ok, nm does have a way to resolve which convention is in use in a static library, isn't it? Or is it simply meaning that lib was generated by GNU gcc, as nm is a part of GNU binutils?
I am not close to my workstation so I can't copy & paste error output from the linker (not for the moment but I could copy them in a further edit)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从存档中提取目标文件,然后对其中一些文件运行
strings
命令(首先在较小的文件上运行,因为筛选的噪音会更少)。 许多编译器在目标文件中插入 ASCII 签名。例如,以下无意义的源文件
foo.c
:在我的 Fedora 10 机器上通过
gcc -c -o foo.o foo.c
编译为 foo.o结果是一个 647 字节的foo.o
对象文件。 在foo.o
上运行string
结果表明编译器是 GCC。 即使我使用
-fno-ident
编译它,.GNU-stack note ELF 部分仍然存在。您可以使用
ar
实用程序或使用 Midnight Commander(集成了 ar)来提取目标文件,或者您可以简单地在存档上运行strings
(这可能会为您提供更多信息)噪音,相关性较低,但仍然有帮助。)Extract the object files from the archive then run the
strings
command on some of them (first on the smaller ones since there'd be less noise to sift through). Many compilers insert ASCII signatures in the object files.For example, the following meaningless source file,
foo.c
:when compiled on my Fedora 10 machine into foo.o via
gcc -c -o foo.o foo.c
results in a 647 bytefoo.o
object file. Runningstrings
onfoo.o
results inwhich makes it clear the compiler was GCC. Even if I'd compiled it with
-fno-ident
, the .GNU-stack note ELF section would have still been present.You can extract the object files using the
ar
utility, or using Midnight Commander (which integrates ar), or you can simply runstrings
on the archive (which might give you more noise and be less relevant, but would still help.)我倾向于使用
strings
程序(带有“-a
”选项,或者我自己的变体,其中“-a
”行为是标准的) )并寻找明显的迹象。 例如,在我自己的一个库中,我发现:单个库)。
另一个库包含:
因此,目标文件中通常有指纹指示使用了哪个编译器。 但你必须知道如何寻找它们。
I tend to use the
strings
program (with the '-a
' option, or my own variant where the '-a
' behaviour is standard) and look for the tell-tale signs. For example, in one of my own libraries, I find:That suggests that the code in the library has been compiled with a variety of versions of GCC over a period of years (actually, I'm quite startled to find so many versions in a single library).
Another library contains:
So, there are usually fingerprints in the object files indicating which compiler was used. But you have to know how to look for them.
该库应该是 C 或 C++ 库吗?
如果它是一个 C 库,那么名称修改就不会成为问题,因为 C 中没有名称修改。但是,它可能是错误的格式。 Unices 曾经拥有 a.out 格式的库,但几乎所有较新的版本都转为更强大的格式,例如 ELF。
如果它是一个 C++ 库,那么名称修改可能是一个问题。 大多数编译器都会在代码中嵌入一些特定于编译器的符号,因此如果您有像 nm 这样的工具来列出符号,您就有希望从它来自的编译器中推断出来。
例如 g++ 创建一个符号
在它的库中
Is the library supposed to be a C or C++ library?
If it is a C library then name mangling can not be the problem, as there is none in C. It could be however in a wrong format. Unices used to have libraries in the a.out format but almost all newer versions switched to more powerful formats like ELF.
If it is a C++ library then name mangling can be an issue. Most compilers embed some symbols that are compiler specific into the code, so if you have a tool like nm to list the symbols you can hopefully deduce from what compiler it came.
For example g++ creates a symbol
in it's libraries
您可以尝试使用 unix 实用程序file:
You can try the unix utility file: