13

当我编译我的库时,我已经打开,-fPIC因为我希望能够将它编译为共享库和静态库。

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

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

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

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

4

4 回答 4

3

我该如何抑制它?

不仅是一个无用的警告,而且是一种分心,使您难以遵循其他警告和错误。

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

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

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

这是没有sed 过滤器的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)
 /* */ 
 ^

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
于 2014-09-21T06:43:51.267 回答
3

就个人而言,我只是将操作系统检测添加到生成文件中。类似的东西

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
于 2014-09-21T09:40:02.177 回答
2

我真的很想知道它有什么意义......
我不是在谈论为什么使用 PIC,只是为什么它会产生 IMO 无用的警告。

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

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

早在 2003 年之前,该警告就已经存在(我不会费心将历史追溯到 2003 年的文件重命名)。

来自 Alexander Monakov 在同一线程上(参考 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的任何地方使用(但反之亦然)。

于 2015-08-21T01:54:03.023 回答
0

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

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

于 2014-02-17T04:26:30.053 回答