-fPIC игнорируется для цели (весь код не зависит от положения), бесполезное предупреждение
Когда я компилирую свою библиотеку, я включил ont -fPIC
, потому что хочу иметь возможность компилировать ее как общую библиотеку, но также как статическую.
Использование gcc 3.4.4 на cygwin Я получаю это предупреждение во всех исходных файлах:
-fPIC ignored for target (all code is position independent)
И мне действительно интересно, в чем дело. Он говорит мне, что я использую переключатель, который не имеет никакого эффекта, потому что то, что коммутатор должен выполнить, уже выполнено. Ну, это означает, что это избыточно, прекрасно. Но какой смысл и как я могу его подавить?
Я не говорю о том, зачем использовать ПОС или нет, просто почему он генерирует это бесполезное предупреждение ИМО.
Ответы
Ответ 1
и как я могу его подавить?
Не только бесполезное предупреждение, но и отвлекающее внимание, затрудняющее выполнение других предупреждений и ошибок.
Учитывая, что мой вывод вывода последовательно показывал 3 связанные строки, я решил отфильтровать 3 "бесполезные" строки, используя следующее:
make 2>&1 | sed '/PIC ignored/{N;N;d;}'
Я понимаю, что это не идеальный способ подавить шум, но, возможно, это поможет в некоторой степени. Имейте в виду, что я разрезаю 3 строки, где в других ситуациях может потребоваться удаление только одной строки. Обратите внимание, что я также перенаправляю stderr в stdout.
Здесь snipit make output без фильтра 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
Ответ 2
Лично я просто добавлю os-детектирование в 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
Ответ 3
И я действительно задаюсь вопросом, в чем смысл этого...
Я не говорю о том, зачем использовать ПОС или нет, просто почему он генерирует это бесполезное предупреждение ИМО.
Это хороший вопрос, и я не видел окончательного ответа. По крайней мере один из разработчиков GCC считает это бессмысленным предупреждением. Паоло Бонзини назвал это своим недавним патчем Удалить бессмысленное предупреждение -fPIC на платформах Windows.
По словам Джонатана Вакли в списке рассылки GCC в Как подавить "предупреждение: -fpIC игнорируется для цели..." в Cygwin ( Август 2015 года):
Это предупреждение было с тех пор задолго до 2003 года (я не мог быть беспокоился об отслеживании истории назад после переименования файла в 2003 году).
И от Александра Монакова в той же теме (ссылка на патч Bonzini):
Патч был предложен совсем недавно, чтобы просто удалить предупреждение: 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
(но не наоборот).
Ответ 4
переключатель имеет некоторое влияние на linux (на windows/cygwin он ничего не сделает, может быть, компилятор не добавил специфичную для платформы проверку heregg), код, сгенерированный с -fPIC, не зависит от позиции, что означает все инструкции, относящиеся к определенному адресу должен быть заменен перенаправлением на место памяти; ячейка памяти устанавливается динамическим загрузчиком; результат немного медленнее - и требуется больше времени для загрузки; Вам не нужно это для статической библиотеки, где все адреса задаются компоновщиком, когда исполняемый файл создается/связан.
Предупреждение, вероятно, означает, что код статической библиотеки не так быстр, как вы могли ожидать, что это будет. Вы можете создать два объектных файла с тем же именем в разных каталогах, один с -fPIC для общей библиотеки и другой для статической библиотеки.