Разница между опциями -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