-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 для общей библиотеки, а другой для статическая библиотека.

Другие вопросы по тегам