当我编译我的库时,我已经切换-fPIC
,因为我希望能够将其编译为共享库,但也是静态的。
在cygwin上使用gcc 3.4.4我在所有源文件上收到此警告:
-fPIC ignored for target (all code is position independent)
我真的很想知道这是什么意思。它告诉我,我使用的开关没有效果,因为开关应该已经完成了。嗯,这意味着它是多余的,很好。但它有什么意义呢?我该如何压制它呢?
我不是在谈论为什么使用PIC,而是为什么它会产生IMO无用的警告。
答案 0 :(得分:3)
我该如何抑制它?
不仅是一个无用的警告,而是分散注意力,使其难以遵循其他警告和错误。
鉴于我的 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
答案 1 :(得分:3)
就个人而言,我只是将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
答案 2 :(得分:2)
我真的很想知道它是什么意思......我不是在谈论为什么使用PIC,而是为什么它会产生IMO无用的警告。
这是一个很好的问题,我还没有看到明确的答案。至少有一个海湾合作委员会开发者认为这是一个毫无意义的警告。 Paolo Bonzini在他最近的补丁Remove pointless -fPIC warning on Windows platforms中称之为。
Jonathan Wakely在GCC邮件列表How to suppress "warning: -fPIC ignored for target..." under Cygwin(2015年8月)上的说法:
自2003年以来,这种警告一直存在(我无法做到) 在2003年通过文件重命名追溯历史记录。
来自Alexander Monakov的同一个帖子(引用Bonzini的补丁):
最近提出了一个补丁来删除警告: https://gcc.gnu.org/ml/gcc-patches/2015-08/msg00836.html
相关,Windows有/ASLR
,这是地址空间布局随机化。它是可选的,但通常需要作为安全门,这意味着必须使用它编译所有程序代码。如果您有SDLC,那么您可能正在使用/ASLR
,因为Microsoft将其称为Writing Secure Code中的最佳做法。
对于可执行文件,{/ 1}}的Linux / Unix等效项为/ASLR
。
在Windows下,所有DLL代码都是可重定位的。在Linux / Unix下,可以使用-fPIE
重新定位共享对象代码。
-fPIC
是"超集" -fPIC
(有些人弃权)。这意味着-fPIE
可以在您使用-fPIC
的任何地方使用(但反之亦然)。
答案 3 :(得分:0)
交换机对linux有一些影响(在windows / cygwin上它什么都不做,也许编译器没有添加平台特定的检查heregg)-fPIC生成的代码与位置无关,这意味着所有指向特定地址的指令必须通过重定向到内存位置来替换;然后由动态加载器设置内存位置;结果稍慢 - 并且需要更多时间来加载;在创建/链接可执行文件时,您不需要为静态库提供所有地址由链接器设置。
警告可能意味着静态库的代码没有您想象的那么快。您可以在不同的目录中创建两个同名的目标文件,一个用于共享库的-fPIC和另一个用于静态库。