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

yve*_*mes 9 linker build-process solaris

第三方为我提供了一个静态库(.a)来链接solaris站.我试图用sunpro编译,但在链接步骤失败了.

我想问题来自我使用的编译器(gcc代替?)或仅仅是它的版本(因为编译器提供的std lib可能会从库AFAIK预期的版本改变,它可能导致链接步骤出错).

我怎么知道用哪个编译器来生成这个lib?有没有一些工具呢?sunpro/gcc或其他什么选项?

作为提示:我前段时间读过编译器在生成目标文件时使用不同的修改约定(是吗?).仍然,"nm --demangle"命令行打印出来自此静态库中调试符号的所有函数名称.它是如何工作的 ?如果我的假设没问题,nm确实有办法解决静态库中正在使用的约定,不是吗?或者它只是意味着lib是由GNU gcc生成的,因为nm是GNU binutils的一部分?

我不接近我的工作站,所以我不能从链接器复制和粘贴错误输出(暂时不能,但我可以在进一步编辑中复制它们)

Mih*_*șan 5

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

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

extern void blah();
Run Code Online (Sandbox Code Playgroud)

当我在我的Fedora 10机器上编译成foo.o时,会gcc -c -o foo.o foo.c产生一个647字节的foo.o目标文件.stringsfoo.o结果上运行

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注释ELF部分仍然存在.

您可以使用该ar实用程序或使用Midnight Commander(它集成了ar)来提取目标文件,或者您可以简单地运行strings存档(这可能会给您带来更多噪音并且不那么相关,但仍然可以提供帮助.)


Jon*_*ler 5

我倾向于使用该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
Run Code Online (Sandbox Code Playgroud)

这表明库中的代码多年来一直使用各种版本的 GCC 进行编译(实际上,我很惊讶在一个库中发现了这么多版本)。

另一个库包含:

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 ...
Run Code Online (Sandbox Code Playgroud)

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