有没有办法知道哪个编译器生成了静态库?

发布于 2024-07-16 08:25:38 字数 594 浏览 10 评论 0原文

第三方为我提供了一个静态库 (.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

允世 2024-07-23 08:25:38

从存档中提取目标文件,然后对其中一些文件运行 strings 命令(首先在较小的文件上运行,因为筛选的噪音会更少)。 许多编译器在目标文件中插入 ASCII 签名。

例如,以下无意义的源文件 foo.c

extern void blah();

在我的 Fedora 10 机器上通过 gcc -c -o foo.o foo.c 编译为 foo.o结果是一个 647 字节的 foo.o 对象文件。 在 foo.o 上运行 string 结果

GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)
.symtab
.strtab
.shstrtab
.text
.data
.bss
.comment
.note.GNU-stack
foo.c

表明编译器是 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:

extern void blah();

when compiled on my Fedora 10 machine into foo.o via gcc -c -o foo.o foo.c results in a 647 byte foo.o object file. Running strings on foo.o results in

GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)
.symtab
.strtab
.shstrtab
.text
.data
.bss
.comment
.note.GNU-stack
foo.c

which 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 run strings on the archive (which might give you more noise and be less relevant, but would still help.)

夏末 2024-07-23 08:25:38

我倾向于使用 strings 程序(带有“-a”选项,或者我自己的变体,其中“-a”行为是标准的) )并寻找明显的迹象。 例如,在我自己的一个库中,我发现

/work1/gcc/v4.2.3/bin/../lib/gcc/sparc-sun-solaris2.10/4.2.3/include
/work1/gcc/v4.3.0/bin/../lib/gcc/sparc-sun-solaris2.10/4.3.0/include
/work1/gcc/v4.3.1/bin/../lib/gcc/sparc-sun-solaris2.10/4.3.1/include
/work1/gcc/v4.3.3/bin/../lib/gcc/sparc-sun-solaris2.10/4.3.3/include

:单个库)。

另一个库包含:

cg: Sun Compiler Common 11 Patch 120760-06 2006/05/26
acomp: Sun C 5.8 Patch 121015-02 2006/03/29
iropt: Sun Compiler Common 11 Patch 120760-06 2006/05/26
/compilers/v11/SUNWspro/prod/bin/cc -O -v -Xa -xarch=v9 ...

因此,目标文件中通常有指纹指示使用了哪个编译器。 但你必须知道如何寻找它们。

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:

/work1/gcc/v4.2.3/bin/../lib/gcc/sparc-sun-solaris2.10/4.2.3/include
/work1/gcc/v4.3.0/bin/../lib/gcc/sparc-sun-solaris2.10/4.3.0/include
/work1/gcc/v4.3.1/bin/../lib/gcc/sparc-sun-solaris2.10/4.3.1/include
/work1/gcc/v4.3.3/bin/../lib/gcc/sparc-sun-solaris2.10/4.3.3/include

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:

cg: Sun Compiler Common 11 Patch 120760-06 2006/05/26
acomp: Sun C 5.8 Patch 121015-02 2006/03/29
iropt: Sun Compiler Common 11 Patch 120760-06 2006/05/26
/compilers/v11/SUNWspro/prod/bin/cc -O -v -Xa -xarch=v9 ...

So, there are usually fingerprints in the object files indicating which compiler was used. But you have to know how to look for them.

人心善变 2024-07-23 08:25:38

该库应该是 C 或 C++ 库吗?

如果它是一个 C 库,那么名称修改就不会成为问题,因为 C 中没有名称修改。但是,它可能是错误的格式。 Unices 曾经拥有 a.out 格式的库,但几乎所有较新的版本都转为更强大的格式,例如 ELF

如果它是一个 C++ 库,那么名称修改可能是一个问题。 大多数编译器都会在代码中嵌入一些特定于编译器的符号,因此如果您有像 nm 这样的工具来列出符号,您就有希望从它来自的编译器中推断出来。

例如 g++ 创建一个符号

__gxx_personality_v0

在它的库中

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

__gxx_personality_v0

in it's libraries

胡渣熟男 2024-07-23 08:25:38

您可以尝试使用 unix 实用程序file

file foo.a

You can try the unix utility file:

file foo.a
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文