Когда я собираю свою библиотеку, я включил -fPIC
потому что я хочу иметь возможность скомпилировать его как общую библиотеку, но также как статическую.
Используя gcc 3.4.4 на cygwin, я получаю это предупреждение для всех исходных файлов:
-fPIC ignored for target (all code is position independent)
И мне действительно интересно, какой в этом смысл. Это говорит мне, что я использую переключатель, который не имеет никакого эффекта, потому что то, что переключатель должен avieche, уже выполнено. Ну, это означает, что это избыточно, хорошо. Но какой в этом смысл, и как я могу это подавить?
Я не говорю о том, почему использовать PIC или нет, просто почему он генерирует это бесполезное предупреждение IMO.
и как я могу это подавить?
Не только бесполезное предупреждение, но отвлечение, которое мешает следовать другим предупреждениям и ошибкам.
Учитывая мой делать на выходе последовательно отображались 3 связанные строки, я решил отфильтровать 3 «бесполезные» строки, используя следующее:
make 2>&1 | sed '/PIC ignored/{N;N;d;}'
Я понимаю, что это не идеальный способ подавления шума, но, возможно, это поможет в некоторой степени. Имейте в виду, что я обрезаю 3 строки, где в других ситуациях может потребоваться удаление только одной строки Обратите внимание, что я также направляю stderr в stdout.
Вот фрагмент делать вывод без СЕПГ фильтр:
libavcodec/x86/mlpdsp.c:51:36: warning: taking address of expression of type 'void'
&ff_mlp_iirorder_4 };
^
CC libavcodec/x86/motion_est_mmx.o
libavcodec/x86/motion_est_mmx.c:1:0: warning: -fPIC ignored for target (all code is position independent)
/* */
^
CC libavcodec/x86/mpegaudiodec_mmx.o
libavcodec/x86/mpegaudiodec_mmx.c:1:0: warning: -fPIC ignored for target (all code is position independent)
/* */
^
CC libavcodec/x86/mpegvideo_mmx.o
libavcodec/x86/mpegvideo_mmx.c:1:0: warning: -fPIC ignored for target (all code is position independent)
/* */
^
И то же самое с СЕПГ фильтр:
^
libavcodec/x86/mlpdsp.c:51:36: warning: taking address of expression of type 'void'
&ff_mlp_iirorder_4 };
^
CC libavcodec/x86/motion_est_mmx.o
CC libavcodec/x86/mpegaudiodec_mmx.o
CC libavcodec/x86/mpegvideo_mmx.o
CC libavcodec/x86/proresdsp-init.o
Лично я бы просто добавил обнаружение ОС в make-файл. Нечто подобное
TARGET_TRIPLE := $(subst -, ,$(shell $(CC) -dumpmachine))
TARGET_ARCH := $(word 1,$(TARGET_TRIPLE))
TARGET_OS := $(word 3,$(TARGET_TRIPLE))
ifeq ($(TARGET_OS),mingw32)
else ifeq ($(TARGET_OS),cygwin)
else
CFLAGS += -fPIC
endif
И мне действительно интересно, какой в этом смысл …
Я не говорю о том, почему использовать PIC или нет, просто почему он генерирует это бесполезное предупреждение IMO.
Это хороший вопрос, и я не видел однозначного ответа. По крайней мере, один из разработчиков GCC считает это бессмысленным предупреждением. Паоло Бонзини назвал это в своем недавнем патче Удалить бессмысленное предупреждение -fPIC на платформах Windows.
По словам Джонатана Уэйкли в списке рассылки GCC на Как подавить «предупреждение: -fPIC игнорируется для цели …» в Cygwin (Август 2015 г.):
Это предупреждение было там задолго до 2003 года (я не мог быть
надоело прослеживать историю после переименования файлов в 2003 году).
И от Александра Монакова в той же теме (ссылаясь на патч Бонзини):
Совсем недавно был предложен патч для удаления предупреждения:
https://gcc.gnu.org/ml/gcc-patches/2015-08/msg00836.html
Связанные, Windows имеет /ASLR
, который является рандомизацией размещения адресного пространства. Это необязательно, но часто требуется в качестве шлюза безопасности, то есть весь программный код должен быть скомпилирован с ним. Если у вас есть SDLC, то вы, вероятно, используете /ASLR
потому что Microsoft называет это как лучшую практику в Написание безопасного кода.
Linux / Unix эквивалент /ASLR
является -fPIE
для исполняемых файлов.
Под Windows весь код DLL можно перемещать. В Linux / Unix общий объектный код может быть перемещен с -fPIC
,
-fPIC
это «надмножество» -fPIE
(Отказ от руки). Это означает -fPIC
может использоваться где угодно -fPIE
(но не наоборот).
этот переключатель оказывает некоторое влияние на linux (в windows / cygwin он бы ничего не делал, возможно, компилятор не добавил сюда проверку для конкретной платформы) код, сгенерированный с -fPIC, не зависит от позиции, то есть все инструкции, которые ссылаются на определенный адрес, должны быть заменены путем перенаправления в ячейку памяти; место в памяти затем устанавливается динамическим загрузчиком; результат немного медленнее — и занимает больше времени для загрузки; Вам не нужно это для статической библиотеки, где все адреса устанавливаются компоновщиком, когда исполняемый файл создается / связывается.
Предупреждение, вероятно, означает, что код статической библиотеки не такой быстрый, как можно было бы ожидать. Вы можете создать два объектных файла с одинаковыми именами в разных каталогах, один с -fPIC для общей библиотеки, а другой для статическая библиотека.