Есть ли способ узнать, какой компилятор генерирует статическую библиотеку? - PullRequest
9 голосов
/ 08 апреля 2009

Третья сторона предоставила мне статическую библиотеку (.a) для связи на станции Solaris. Я попытался скомпилировать с SunPro, и не удалось на шаге ссылки.

Я полагаю, что проблема исходит от используемого мной компилятора (вместо gcc?) Или просто его версии (поскольку библиотека std, предоставляемая компилятором, может измениться по сравнению с версией, ожидаемой библиотекой AFAIK, это может привести к ошибкам на этапе компоновки ).

Как я мог узнать, какой компилятор использовался для генерации этой библиотеки? Есть ли инструменты, которые делают это? Какой-нибудь вариант в sunpro / gcc или как там?

Подсказка: Некоторое время назад я читал, что компиляторы используют разные соглашения о искажениях при генерации объектных файлов (верно?). Тем не менее, "nm --demangle" командная строка выводит мне все имена функций из символов отладки в этой статической библиотеке. Как это работает ? Если мое предположение в порядке, nm действительно может решить, какое соглашение используется в статической библиотеке, не так ли? Или это просто означает, что lib была сгенерирована GNU gcc, так как nm является частью GNU binutils?

Я не близко к своей рабочей станции, поэтому я не могу скопировать и вставить вывод ошибок из компоновщика (на данный момент, но я мог бы скопировать их в дальнейшем редактировании)

Ответы [ 4 ]

5 голосов
/ 08 апреля 2009

Извлеките объектные файлы из архива, затем выполните команду strings для некоторых из них (сначала для меньших, так как будет меньше шума просеивать). Многие компиляторы вставляют подписи ASCII в объектные файлы.

Например, следующий бессмысленный исходный файл, foo.c:

extern void blah();

при компиляции на моей машине Fedora 10 в foo.o через gcc -c -o foo.o foo.c приводит к объектному файлу foo.o размером 647 байт. Запуск strings на foo.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, секция ELF с примечанием к стеку .GNU все равно присутствовала бы.

Вы можете извлечь объектные файлы, используя утилиту ar, или используя Midnight Commander (который интегрирует ar), или вы можете просто запустить strings для архива (который может дать вам больше шума и быть менее актуальным, но все равно поможет.)

2 голосов
/ 08 апреля 2009

Я склонен использовать программу 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 ...

Итак, в объектных файлах обычно есть отпечатки пальцев, указывающие, какой компилятор использовался. Но вы должны знать, как их искать.

2 голосов
/ 08 апреля 2009

Предполагается, что библиотека является библиотекой C или C ++?

Если это библиотека C, то искажение имени не может быть проблемой, поскольку ее нет в C. Однако она может быть в неправильном формате. У Unix раньше были библиотеки в формате a.out , но почти все более новые версии переключались на более мощные форматы, такие как ELF .

Если это библиотека C ++, то искажение имени может стать проблемой. Большинство компиляторов встраивают некоторые символы, специфичные для компилятора, в код, поэтому, если у вас есть инструмент, подобный nm, для перечисления символов, можно надеяться, что он получен из компилятора.

Например, g ++ создает символ

__ gxx_personality_v0

в его библиотеках

0 голосов
/ 08 апреля 2009

Вы можете попробовать утилиту unix file :

file foo.a
...