【问题标题】:-fPIC ignored for target (all code is position independent), useless warning-fPIC 忽略目标(所有代码与位置无关),无用警告
【发布时间】:2013-05-23 07:36:09
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 那么,您的真正问题是什么?不要在该目标上使用-fPIC
  • 据我了解,问题是“它的意义何在,我该如何压制它?”
  • 我在 GCC 错误跟踪器上报告了这个警告的存在作为一个错误,但开发人员似乎认为它没问题。警告比无用更糟糕——它无缘无故地使我的 Makefile 复杂化。
  • 我认为您应该切换到 -fpic 以删除警告。 -fPIC 只在一些更不常见的平台上有所作为
  • 这个警告比没用还糟糕。我经常使用-Werror 进行编译,这会在某些平台上引发虚假警告。

标签: c++ c gcc-warning


【解决方案1】:

我该如何抑制它?

不仅是无用的警告,而且会让人分心,难以跟踪其他警告和错误。

鉴于我的 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

【讨论】:

  • sed 方法对我有用。自从我们改用 mingw 后,几乎所有东西都有相同的警告
【解决方案2】:

就个人而言,我只是将操作系统检测添加到 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

【讨论】:

    【解决方案3】:

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

    这是一个很好的问题,我还没有看到明确的答案。至少有一个 GCC 开发人员认为这是一个毫无意义的警告。 Paolo Bonzini 在他最近的补丁Remove pointless -fPIC warning on Windows platforms 中这样称呼它。

    根据 GCC 邮件列表 How to suppress "warning: -fPIC ignored for target..." under Cygwin(2015 年 8 月)上的 Jonathan Wakely:

    这个警告早在 2003 年之前就已经存在(我不可能 2003 年文件重命名后,费心追溯历史)。

    来自 Alexander Monakov 在同一线程上(参考 Bonzini 的补丁):

    最近提出了一个补丁来删除警告: https://gcc.gnu.org/ml/gcc-patches/2015-08/msg00836.html


    相关,Windows 有/ASLR,即地址空间布局随机化。它是可选的,但通常需要作为安全门,这意味着必须使用它编译所有程序代码。如果您有 SDLC,那么您可能正在使用 /ASLR,因为 Microsoft 在 Writing Secure Code 中将其称为最佳实践。

    对于可执行文件,/ASLR 的 Linux/Unix 等效项是 -fPIE

    在 Windows 下,所有 DLL 代码都是可重定位的。在 Linux/Unix 下,可以使用-fPIC 使共享目标代码可重定位。

    -fPIC-fPIE 的“超集”(有些人放弃)。这意味着-fPIC 可以在任何你想使用-fPIE 的地方使用(但反之不行)。

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      • 2016-11-06
      • 2012-06-27
      • 2015-09-28
      • 2016-02-26
      • 2019-08-25
      • 1970-01-01
      相关资源
      最近更新 更多