-fPIC игнорируется для цели (весь код не зависит от позиции), бесполезное предупреждение

Когда я компилирую свою библиотеку, я включил -fPIC, потому что я хочу иметь возможность компилировать ее как общую библиотеку, но также и как статическую.

Используя gcc 3.4.4 на cygwin, я получаю это предупреждение для всех исходных файлов:

-fPIC ignored for target (all code is position independent)

И мне действительно интересно, какой в ​​этом смысл. Он говорит мне, что я использую переключатель, который не имеет никакого эффекта, потому что то, что должен переключатель, уже выполнено. Ну значит лишнее, ладно. Но какой в ​​этом смысл и как я могу его подавить?

Я не говорю о том, почему используется PIC или нет, просто почему он генерирует это бесполезное предупреждение IMO.


person Devolus    schedule 23.05.2013    source источник
comment
Итак, каков ваш вопрос на самом деле? Не используйте -fPIC на этой цели.   -  person Mat    schedule 23.05.2013
comment
Как я понял вопрос в чем смысл и как его подавить?   -  person nogard    schedule 23.05.2013
comment
Я сообщил о существовании этого предупреждения как об ошибке в системе отслеживания ошибок GCC, но разработчик, похоже, считает, что это нормально. Предупреждение хуже, чем бесполезно — оно без всякой причины усложняет мой Makefile.   -  person Lee Daniel Crocker    schedule 23.05.2013
comment
@LeeDanielCrocker, спасибо! Мне было интересно, не упустил ли я что-то очевидное. :) Ну, у меня это не вызывает никаких проблем, просто раздражает, потому что я обычно стремлюсь иметь предупреждающий бесплатный код.   -  person Devolus    schedule 23.05.2013
comment
Я думаю, вам следует переключиться на -fpic, чтобы убрать предупреждение. -fPIC имеет значение только на некоторых более необычных платформах   -  person Rolle    schedule 23.05.2013
comment
@Ролл, спасибо! Я даже не знал об этих различиях и применил -fpic сейчас, прочитав gcc.gnu.org/ml/gcc-help/2006-09/msg00018.html. Предупреждение все еще там.   -  person Devolus    schedule 23.05.2013
comment
Попробуйте использовать libtool. Он установит для вас -fPIC, если поддерживается, если вы подтвердите, что предпочитаете PIC (--with-pic). См. руководство gnu.org/software/libtool/manual/libtool.html   -  person devnull    schedule 23.05.2013
comment
Просто примечание: использование -fpic действительно удалило предупреждение для меня.   -  person letmaik    schedule 18.12.2013
comment
Это предупреждение хуже, чем бесполезно. Я регулярно компилирую с использованием -Werror, и это выдает ложное предупреждение на некоторых платформах.   -  person nneonneo    schedule 30.03.2014
comment
На данный момент лучшим способом кажется libtool (возможно, управляемый automake), который использует правильные флаги в зависимости от конкретного действия.   -  person Pavel Šimerda    schedule 21.09.2014
comment
Обновите до последней версии GCC. Текущая версия (октябрь 2014 г.) — 4.9.1!   -  person Basile Starynkevitch    schedule 26.10.2014


Ответы (4)


и как я могу его подавить?

Не только бесполезное предупреждение, но и отвлечение внимания, которое затрудняет отслеживание других предупреждений и ошибок.

Поскольку мой вывод make постоянно показывал 3 связанные строки, я решил отфильтровать 3 «бесполезные» строки, используя следующее:

make 2>&1 | sed '/PIC ignored/{N;N;d;}'

Я понимаю, что это не идеальный способ подавить шум, но, возможно, в какой-то степени это поможет. Имейте в виду, что я сокращаю 3 строки, тогда как в других ситуациях может потребоваться удаление только одной строки. Обратите внимание, что я также перенаправляю stderr на stdout.

Вот фрагмент вывода 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
person bvj    schedule 21.09.2014
comment
Метод sed сработал для меня. Были одинаковые предупреждения почти для всего, так как мы перешли на использование mingw - person Joe Lyga; 31.07.2015

Лично я бы просто добавил обнаружение ОС в 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
person Christoph    schedule 21.09.2014

И мне действительно интересно, какой в ​​этом смысл...
Я не говорю о том, зачем использовать 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 называет это лучшей практикой в ​​Написание безопасного кода.

Эквивалентом /ASLR для Linux/Unix является -fPIE для исполняемых файлов.

В Windows весь код DLL можно перемещать. В Linux/Unix общий объектный код можно сделать перемещаемым с помощью -fPIC.

-fPIC - это "надмножество" -fPIE (небольшое отклонение от руки). Это означает, что -fPIC можно использовать везде, где вы использовали бы -fPIE (но не наоборот).

person jww    schedule 21.08.2015

переключатель имеет некоторое влияние на linux (на windows/cygwin он ничего не сделает, возможно, компилятор не добавил сюда проверку для конкретной платформыgg) код, сгенерированный с -fPIC, не зависит от позиции, это означает, что все инструкции, которые относятся к определенному адресу, должны быть заменены путем перенаправления на место в памяти; затем место в памяти устанавливается динамическим загрузчиком; результат немного медленнее - и требуется больше времени для загрузки; Вам это не нужно для статической библиотеки, где все адреса устанавливаются компоновщиком, когда исполняемый файл создается/связывается.

Предупреждение, вероятно, означает, что код статической библиотеки работает не так быстро, как можно было бы ожидать. Вы можете создать два объектных файла с одинаковыми именами в разных каталогах, один с -fPIC для разделяемой библиотеки, а другой для статическая библиотека.

person MichaelMoser    schedule 17.02.2014
comment
вы ошибаетесь; Windows просто не поддерживает позиционно-независимый код в смысле unix; см. en.wikipedia.org/wiki/Position-independent_code#Windows_DLLs - person Christoph; 21.09.2014