-fPIC忽略目标(所有代码都与位置无关),无用的警告

当我编译我的库时,我已经切换了-fPIC因为我希望能够将其编译为共享库,但也可以作为静态编译。

在cygwin上使用gcc 3.4.4我在所有源文件上收到此警告:

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

我真的很想知道它有什么意义。 它告诉我,我使用的开关没有效果,因为开关应该已经完成​​了。 嗯,这意味着它是多余的,很好。 但它有什么意义呢?我该如何压制它呢?

我不是在谈论为什么使用PIC,而是为什么它会产生IMO无用的警告。

我怎么能抑制它呢?

这不仅是一个无用的警告,而且是一种让人难以理解其他警告和错误的注意力。

鉴于我的make输出始终显示3条相关行,我选择使用以下内容过滤掉3个“无用”行:

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

我意识到这不是抑制噪音的理想方法,但也许它会在某种程度上有所帮助。 请注意,我正在削减3行,其他情况可能只需要删除一行。 请注意,我也将stderr路由到stdout。

这里是没有sedfilter的make输出的片段

 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) /* */ ^ 

sedfilter一样:

  ^ 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 

就个人而言,我只是将os检测添加到makefile中。 有点像

 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无用的警告。

这是一个很好的问题,我还没有看到明确的答案。 至少有一个海湾合作委员会开发者认为这是毫无意义的警告。 Paolo Bonzini称他在最近的补丁中删除了Windows平台上的无意义-fPIC警告 。

根据GCC邮件列表中的Jonathan Wakely所说, 如何在Cygwin (2015年8月) 下抑制“警告:-fPIC忽略目标…” :

这个警告自2003年以来一直存在(我无法追溯历史回溯到2003年的文件重命名)。

来自Alexander Monakov的同一个post(引用Bonzini的补丁):

最近提出了一个补丁来删除警告: 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 (但反之亦然)。

这个开关对linux有一些影响(在windows / cygwin上它什么都不做,也许编译器没有添加平台特定的检查heregg)-fPIC生成的代码与位置无关,这意味着所有引用特定地址的指令都必须被替换通过重定向到内存位置; 然后由动态加载器设置内存位置; 结果稍慢 – 并且需要更多时间来加载; 在创建/链接可执行文件时,对于所有地址都由链接器设置的静态库,您不需要这样做。

警告可能意味着静态库的代码没有您想象的那么快。您可以在不同的目录中创建两个同名的目标文件,一个用于共享库的-fPIC,另一个用于共享库。静态库。