【问题标题】:How do I prevent a quoted include from searching the directory of the current source file?如何防止引用的包含搜索当前源文件的目录?
【发布时间】:2012-07-21 06:35:34
【问题描述】:

gcc 提供了-I- 选项,在-I- 之前的-I 目录中搜索带引号的包含(#include "foo.h"),在-I- 之后的-I 目录中搜索带括号的包含(@ 987654329@),以及其他引用的包括。

-I- 还有一个非常重要的作用。它会从默认搜索路径中删除#include 所在的源文件目录。通常,带引号的包含总是搜索源文件的目录,并在任何-I 或其他目录之前搜索它。因此,-I- 允许您通过删除默认路径(否则会优先考虑)来准确指定引用包含文件的位置。

所以听起来我回答了我的问题,是吗?不,当我现在使用-I- 时,我得到了这个讨厌的图:

cc1: note: obsolete option -I- used, please use -iquote instead

问题在于-iquote 确实没有从搜索路径中删除当前目录。无论我向-iquote 提供什么,它仍然总是首先搜索。

所以问题是:如何在不使用 -I- 的情况下获得与 -I- 相同的效果,而 -I- 已被弃用并最终会消失?

阐述:

假设文件的布局如下:

srcdir/
    configure
    file1.c
    file2.c
    config.h

builddir/
    Makefile
    file1.o
    file2.o
    config.h
    libpudding.a

由于各种原因,我们无法从srcdir 中删除config.h(这会影响其他平台上的构建过程)。但是,我们希望包含来自builddirconfig.h,而不是srcdir 中的zconf.h

这可以通过 GCC 的 -I- 标志来完成,但似乎不可能。

更新问题:

好吧,看来 GNU CC 开发人员已弃用 -I-,但没有提供实现其功能的替代方法。所以我更新的问题是:让开发人员注意这一点的最有效方法是什么,以便-I- 很可能不被弃用(我认为这是最可取的,因为它是一种非常优雅的方式处理指定搜索,比 -iquotexxx 更丑更丑),或者提供某种方法从引用的包含搜索路径中删除当前目录?

【问题讨论】:

  • 快速浏览 GCC 手册让我相信这是不可能的,-I- 是该行为的唯一选择。过去,我决定对我自己的项目最简单的选择是重命名或重新组织我的头文件,而不是使用搜索路径。来源:gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/…
  • 这是针对用户要求的 zlib 的源目录外构建。这与我想如何为自己整理东西没有任何关系。
  • 嗯,过去我确保我的项目支持树外构建,但我从来不需要使用-I- 来完成它。这是你正在寻找的那种改变吗? github.com/depp/zlib
  • 这很复杂。 (这里的自然趋势似乎是,如果这个问题很难回答,那么它一定是错误的问题。)无论如何,zconf.h是构建的,需要在builddir中,并被zlib.h引用,即在 srcdir 中。源文件包括引用的 zlib.h。因此,无论 zlib.h 只是在 srcdir 中还是复制到 builddir,都存在包含正确 zlib.h 的源文件或包含正确 zconf.h 的 zlib.h 的问题。由于其他原因,我无法更改引用包含的事实。
  • 好吧,您也可以将所有源文件符号链接到 builddir。也许这只是阻力最小的路径。

标签: c gcc include-path


【解决方案1】:

在树外构建中处理了zconf.h 的烦恼后,我肯定会回到您的观点,即当问题非常棘手时,通常是错误的问题。你是绝对正确的。正确的问题是为什么zconf.h 存在于srcdir 中,而它应该从zconf.h.in 生成。对于给定的一组配置设置,应该始终生成或永远不会生成文件。它不应该在同一个构建中同时提供和生成。

这里最好的解决方案是从源代码树中删除 zconf.h 并始终从 zconf.h.in 生成它,就像在 CMake 构建中所做的那样。我一直不清楚为什么它以一种方式用于 CMake,而另一种方式用于 Make。如果关键是您没有 autoconf,因此您将使用预构建的 zconf.h 进行 make,但使用 CMake 生成的用于 CMake,那么只需将其作为 zconf.h.in 发送(您do),并将其复制到 Makefile 中的构建树中。

摆脱-I- 的怪异行为是一个很好的举措。在您的搜索路径中有多个以相同名称引用的文件非常令人困惑和难看。如果-I 搜索顺序很重要,那么您的项目或构建中的某些内容设计不正确。我永远不必猜测#include "foo.h" 指的是什么。我绝对不应该处于容易发现自己编辑错误文件的情况。

我对您改进 zlib 构建的工作表示赞赏。 zlib 肯定不是最难构建的包,但也肯定不是最简单的(特别是如果你需要 contrib/minizip 的东西,我总是这样做)。

【讨论】:

  • zconf.h 需要在源目录中,因为我要求 zlib 可以开箱即用地轻松构建,根本不需要脚本。例如。 cc -c *.c; ar rc libz.a *.o,或任何平台上的等效命令。您关于处理生成文件的正确方法的陈述仅适用于具有生成这些文件的工具的世界子集。当一个人生活在那个子集中时,很容易假设这就是整个世界。
  • 我不明白为什么 -I- 很奇怪。这是一种紧凑而优雅的方式来拆分引用和括号包含之间的包含路径。您可以通过检查立即查看引用和括号包含的实际搜索路径。它比 -iquote / -I 方法更好看、更容易阅读和更容易理解。如前所述,-iquote 失去了 -I- 所具有的基本功能。
  • 顺便说一下,正常的基于脚本的构建过程(./configure && make)确实总是从 zconf.h.in 生成 zconf.h。所以我没有得到你的评论。
  • 我正在使用 CMake 系统,这迫使我从源代码树中删除 zconf.h 以便构建(这在 Perforce 下很困难)。从那以后我转行了。回复:无需工具即可轻松构建,添加步骤cp zconf.h.in zconf.h 不是简化包含路径的过度工具要求,并且是我推荐的构建问题的解决方案。我支持我的信念,即任何依赖于顺序的包含路径都是危险且令人困惑的,并且由于 -I- 的特殊功能是支持依赖于顺序的包含路径,因此弃用它是件好事。
  • 只是为此添加不同的视图:我有一个案例,我想为单元测试存根特定的头文件,但我不想复制原始源文件。因此,我确实需要从包含搜索路径中删除源文件所在的路径。此外,包含路径总是依赖于顺序。如果您在包含的路径中有两个名称相同的文件,您将获得对顺序的依赖。
猜你喜欢
  • 2011-03-10
  • 2011-03-10
  • 2012-09-03
  • 2015-06-15
  • 2011-08-23
  • 2017-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多