Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linker 有没有办法知道哪个编译器生成了静态库?_Linker_Build Process_Solaris - Fatal编程技术网

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

Linker 有没有办法知道哪个编译器生成了静态库?,linker,build-process,solaris,Linker,Build Process,Solaris,第三方为我提供了一个静态库(.A),用于在solaris工作站上链接。 我试图用sunpro编译,但在链接步骤失败 我认为问题来自我使用的编译器(而不是gcc?)或者只是它的版本(因为编译器提供的std库可能会从库AFAIK所期望的版本更改,这可能会导致链接步骤出错) 我怎么知道哪个编译器用来生成这个库?有什么工具可以做到这一点吗?sunpro/gcc中的一些选项或其他什么 作为提示:我不久前读到编译器在生成对象文件时使用不同的损坏约定(true?)。尽管如此,“nm--demangle”命令行

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

我认为问题来自我使用的编译器(而不是gcc?)或者只是它的版本(因为编译器提供的std库可能会从库AFAIK所期望的版本更改,这可能会导致链接步骤出错)

我怎么知道哪个编译器用来生成这个库?有什么工具可以做到这一点吗?sunpro/gcc中的一些选项或其他什么

作为提示:我不久前读到编译器在生成对象文件时使用不同的损坏约定(true?)。尽管如此,“nm--demangle”命令行还是很好地打印了这个静态库中调试符号中的所有函数名。它是如何工作的?如果我的假设是正确的,nm确实有办法解决静态库中使用的约定,不是吗?或者这仅仅意味着lib是由gnugcc生成的,因为nm是gnubinutils的一部分


我离工作站不近,因此无法复制并粘贴链接器的错误输出(目前还没有,但我可以在进一步编辑时复制它们)

您可以尝试unix实用程序文件:


图书馆应该是C还是C++库?< /P> 如果它是一个C库,那么名称损坏就不会是问题,因为C中没有名称损坏。但是,它的格式可能是错误的。Unices以前有这种格式的库,但几乎所有较新的版本都切换到更强大的格式,如

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

例如,g++创建了一个符号

__gxx_个性_v0


在它的库中

从归档文件中提取目标文件,然后对其中一些文件运行
字符串
命令(首先对较小的文件运行,因为要筛选的噪声较小)。许多编译器在目标文件中插入ASCII签名

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

extern void blah();
当在我的Fedora 10机器上通过
gcc-c-o foo.o foo.c
编译成foo.o时,会产生一个647字节的
foo.o
对象文件。在
foo.o
上运行
strings

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:(GNU)4.3.2 20081105(红帽4.3.2-7) .symtab .strtab shstrtab先生 .文本 .数据 .bss .评论 .note.GNU-stack 富科 这说明编译器是GCC。即使我用
-fno ident
编译它,.GNU堆栈注释ELF部分仍然存在


您可以使用
ar
实用程序提取目标文件,或者使用Midnight Commander(它集成了ar),或者您可以简单地在归档文件上运行
strings
(这可能会给您带来更多的噪音和更少的相关性,但仍然会有所帮助)。

我倾向于使用
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
这表明库中的代码在过去的几年中使用了多种版本的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 ...

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

为什么不问问“第三方”呢谁提供了这个库来获取如何使用它的说明?我问了他们。但是他们的支持团队没有回答,他们不愿意问开发团队,似乎…:/我试过了,但我记得它只告诉我这个文件在SPARC平台上使用ELF格式。sunpro会像GCC一样生成ELF格式吗?
文件
工具很难恢复关于编译器使用的信息,或者只需在库上直接运行“字符串”——不需要首先提取对象文件。就像我提到的,有更多的输出,特别是在C++对象文件的情况下,更容易错过编译器签名。r、 …我正试图找到从clang编译的mac对象文件和静态库中提取编译器版本的方法。通过使用strings命令进行字符串转储,并对显示“Apple LLVM版本9.0.0(clang-900.0.39.2)”的“clang”进行灰显,我能够从库中40个对象文件中的4个中提取编译器版本但其他文件没有此字符串。在使用mach-o-view工具查看节内部时,从中提取编译器版本的目标文件有一个节64(_DWARF,_debug_str),其中包含字符串“Apple LLVM版本9.0.0(clang-900.0.39.2)”你使用的是
strings-a
还是
strings
?通常
-a
很重要。我倾向于在我的MacBook Pros上使用一个自制的GCC(目前是9.2.0),一个运行macOS Mojave 10.14.6(工作;抱怨!),另一个运行macOS Catalina 10.15.3。我刚刚用clang 11.0.0重新编译了一个小库(9个源文件)(Xcode 11.3.1),系统
strings
报告了9次Apple事件(
/usr/bin/strings libdiag.a | grep-i Apple | sort | uniq-c
生成了
9 Apple clang 11.0.0版(clang-1100.0.33.17)
。我不确定这是否有帮助。谢谢你的评论,Jonathan。我尝试过使用字符串和字符串-a。两者都没有找到。我可以在少数文件中复制相同的字符串。但是在少数对象文件中,字符串丢失了。你知道有任何编译器标志或其他东西会去掉它吗?我不知道有什么选项可以去掉此metad对象文件中的ata—我从不麻烦。使用
otool
命令可以列出各种信息—看起来
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 ...