-fPIC игнорируется для цели (весь код не зависит от позиции), бесполезное предупреждение
Когда я собираю свою библиотеку, я включил -fPIC
потому что я хочу иметь возможность скомпилировать его как общую библиотеку, но также как статическую.
Используя gcc 3.4.4 на cygwin, я получаю это предупреждение для всех исходных файлов:
-fPIC ignored for target (all code is position independent)
И мне действительно интересно, какой в этом смысл. Это говорит мне, что я использую переключатель, который не имеет никакого эффекта, потому что то, что переключатель должен avieche, уже выполнено. Ну, это означает, что это избыточно, хорошо. Но какой в этом смысл, и как я могу это подавить?
Я не говорю о том, почему использовать PIC или нет, просто почему он генерирует это бесполезное предупреждение IMO.
4 ответа
Лично я бы просто добавил обнаружение ОС в 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
и как я могу это подавить?
Не только бесполезное предупреждение, но отвлечение, которое мешает следовать другим предупреждениям и ошибкам.
Учитывая, что мой вывод make последовательно отображал 3 связанные строки, я решил отфильтровать 3 "бесполезные" строки, используя следующее:
make 2>&1 | sed '/PIC ignored/{N;N;d;}'
Я понимаю, что это не идеальный способ подавления шума, но, возможно, это поможет в некоторой степени. Имейте в виду, что я обрезаю 3 строки, где в других ситуациях может потребоваться удаление только одной строки. Обратите внимание, что я также направляю stderr в stdout.
Вот фрагмент make make без фильтра sed:
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)
/* */
^
И то же самое с фильтром sed:
^
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
И мне действительно интересно, какой в этом смысл...
Я не говорю о том, почему использовать 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 для общей библиотеки, а другой для статическая библиотека.