Разница между опциями -h <name> и -o <outputfile> в cc (C++)

Я собираю библиотеку.so, и мне было интересно - в чем разница между вариантами компилятора b/w -h и -o cc (с использованием Sun Studio C++)?

Разве они не имеют в виду одно и то же - имя выходного файла?

3 ответа

Решение

-o это имя файла, который будет записан на диск компилятором

-h это имя, которое будет записано в двоичные файлы ELF, которые ссылаются на этот файл.

Одним из распространенных применений является предоставление младших номеров версий библиотеки. Например, если вы создаете общую библиотеку libfoo, вы можете сделать:

cc -o libfoo.so.1.0 -h libfoo.so.1 *.o
ln -s libfoo.so.1.0 libfoo.so.1
ln -s libfoo.so libfoo.so.1

Затем, если вы скомпилируете свое приложение hello world и свяжетесь с ним

cc -o hello -lfoo

бинарный файл эльфа для hello запишет NEEDED запись для libfoo.so.1 (который вы можете увидеть, запустив elfdump -d hello).

Затем, когда вам нужно будет добавить новые функции позже, вы можете изменить -o значение дляlibfoo.so.1.1 но оставь -ч в libfoo.so.1 - все программы, которые вы уже создали с 1.0, все еще пытаются загрузить libfoo.so.1 во время выполнения, так что продолжайте работать без перестройки, но через ls вы увидите, что это 1.1.

Это также иногда используется при сборке библиотек в том же каталоге, в котором они используются во время выполнения, если у вас нет отдельного каталога установки или установки через систему пакетов. Во избежание сбоя программ, которые запускаются при перезаписи двоичного файла библиотеки, и во избежание невозможности запуска программ, когда вы находитесь в середине сборки, некоторые файлы Makefile будут делать:

cc -o libfoo.so.1.new -h libfoo.so.1 *.o
rm libfoo.so.1 ; mv libfoo.so.1.new libfoo.so.1

(Makefiles, созданные старым генератором make-файлов Imake из X, обычно делают это.)

Они имеют в виду разные имена. В частности, -o опция - это фактическое имя файла - имя в файловой системе. -h опция устанавливает внутренний DT_SONAME в конечном объектном файле. Это имя, под которым на общий объект ссылаются другие модули. Я считаю, что это имя, которое вы также видите, когда вы бежите ldd на объектах, которые ссылаются на него.

Опция -o присваивает имя выходному файлу, а опция -h устанавливает внутреннее имя в библиотеке. Это внутреннее имя имеет приоритет над именем файла при использовании динамическим загрузчиком и позволяет ему использовать предопределенные правила для просмотра нужной библиотеки.

Вы можете увидеть, какое собственное имя было записано в данную библиотеку с помощью этой команды:

elfdump -d xxx.so | grep SONAME

Посмотрите здесь для деталей:

http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter4-97194.html

Другие вопросы по тегам