11

我有一个在 g++ 中编译正常的项目(我现在看不到版本),现在在 xCode 上却不是。
我认为我现在遇到了问题...我的项目中有一个 String.h 文件,似乎 xCode 编译器(即 gcc)正在尝试从 < cstring > 添加我自己的字符串文件...我我不确定,但看看这张照片
http://www.jode.com.br/Joe/xCode1.png

从它的外观来看,它包含我自己的而不是系统文件,我想知道...#include <file> 不应该是系统包含吗?因为 < > ?并且系统不应该在它自己的路径中包含一个文件,而不是我的应用程序的原始路径吗?
正如我所说,我不确定这是否会发生,因为过去 2 天我只是迁移到 osx ......
我打算将我的类和文件名更改为不冲突,所以它会起作用,如果这是真的问题,但我想知道,应该有另一种方法来做到这一点,因为现在我的项目没有那么大,所以我可以在一段时间内做到这一点,但如果项目更大怎么办?很难更改所有包含和类名......

任何帮助表示赞赏

谢谢,
乔纳森

4

7 回答 7

11

我有同样的问题,很难解决。我花了几个小时来修复/找出答案。问题是xcode的headermap。和解决方案 - 除了避免那些保留名称,这通常是一个好主意,但并不总是可以使用第三方库 - 是添加

USE_HEADERMAP = NO

到您的用户定义的设置。

向这些人致敬:http: //meidell.dk/archives/2010/05/08/xcode-header-map-files/ http://www.cocoabuilder.com/archive/xcode/262586-header-file-problem -sorry-to-bug-this-list.html

于 2011-01-27T11:53:04.223 回答
5

用与string.h等标准头文件相同的名称命名您的头文件并简单地包含它们#include <String.h>是自找麻烦(在某些平台上,大小写的差异没有区别)。

但是,正如您所说,在命名标题时很难尝试提前弄清楚这些是什么。因此,最简单的方法是设置包含路径在您的标题所在的子目录之外的一个目录级别,例如:

#include <Jonathan/String.h>

现在,您不必担心 String.h 文件名是否与您正在使用的库中的某些内容冲突,除非它们碰巧也包含<Jonathan/String.h>其中不太可能的内容。所有体面的第三方库也这样做。例如,我们不包含<function.hpp>在 boost 中,而是包含<boost/function.hpp>. 与 GL/GL.h 相同,而不是简单的 GL.h。这种做法在很大程度上避免了冲突,并且您不必通过将 String.h 重命名为 Text.h 之类的名称来解决问题。

于 2010-06-27T05:23:12.907 回答
4

是的,如果你使用

#include "file"

首先查看本地目录,然后

#include <file>

仅查看系统包含文件夹。

注意单词first仅在第一种情况下。这意味着每次都包含您的本地版本(除非您已将源路径包含在 INCLUDE 指令中)。

就是说,我的虚拟建议是用明确的名称重命名您的本地文件......

于 2010-06-26T18:55:16.550 回答
1

在 OSX 上,文件系统不区分大小写 - 所以 String.h 你可能会遇到这样的冲突。字符串.h == 字符串.h

于 2010-06-26T18:47:06.273 回答
1

它通过将名称从 String.h 更改为 Text.h 来工作

但这没有任何意义,因为 std 库包含它自己的 string.h 而不是我的。
我的意思是,对于开发人员来说,考虑他不能使用哪些名称来创建他的文件是没有意义的,例如,假设我将我的 String.h 更改为 Text.h(我已经这样做了,我需要工作并且这个不让我)广告不知何故我不得不包含另一个模板库,其中包含一个名为 Text.h 的包含,我是否必须再次更改我的 text.h 或不使用这个新库?应该有一个替代方案。
还是不应该?

感谢到目前为止的帮助,
乔纳森

于 2010-06-26T22:47:32.513 回答
1

您遇到的两件事:

  1. 如上所述,Mac OS 上的文件系统不区分大小写,除非您专门将文件系统设置为区分大小写。
  2. gcc 并没有区分本地和系统头文件包含路径。当您通过 -I 指定要添加到路径的目录时,该目录将用于定位本地和系统包含。只有当您使用 -iquote 或 -I- 时,才会跳过目录以查找系统包含。此外,始终在编译器搜索路径上的内置“系统包含”目录中搜索本地包含。
    • 请注意,当前目录用于本地而非系统包含。在这种情况下,我相信它选择了 String.h,因为项目设置明确地将顶级项目目录添加到包含路径。

我建议的解决方法,而不是重命名您的包含,是将您的实用程序放入一个名称对您的项目来说是唯一的目录中,并在您的包含指令中指定该目录。例如:

#include "Josk/String.h"

并确保Josk/它本身不在您的包含搜索路径中。这样您就不会被尴尬的重命名所困扰,尽管您可能必须在项目中随机播放一些文件。您可能还需要编辑项目设置以确保该实用程序目录的父目录位于您的包含路径中。

另一种尝试的可能性是,如果您看到顶级项目目录添加到项目的包含路径中,请将其删除。这应该使您的顶级项目目录中的项目不被搜索系统包含。

最后,您还可以通过更改文件系统的区分大小写来避免在这种特定情况下出现此问题。不过,这可能会破坏一些 Mac 应用程序,因此在开始之前先研究一下这个问题 - 或者选择一个其他没有使用的卷。

于 2010-06-27T06:22:47.767 回答
0

这个问题已经有了一些很好的答案,但是没有一个能详细地总结出编译器一般是如何搜索头文件的;或者更准确地说,Xcode 将如何让编译器搜索它们。

当您包含用户标头时,这些是引号 ( "...") 之间的标头文件,以下搜索顺序适用:

  1. 执行包含的文件的目录。
  2. 所有标题搜索路径按提供的顺序排列。
  3. 如果启用了标头映射,则在标头映射文件中首先匹配。

请注意,使用了完整的包含路径。因此,如果您的包含在文件中foo/bar/file.c并且您执行了#include "subdir/header.h",那么第一次查找将是foo/bar/subdir/header.h.

如果该文件不存在,编译器会迭代用户头搜索路径。这些由构建设置提供User Header Search Path(在配置文件中或在名为 的命令行中USER_HEADER_SEARCH_PATHS)。可以存在多个这样的路径,并且完整的包含路径会附加到每个路径,直到匹配为止。

如果不提供任何匹配项并且启用了构建设置Use Header Maps( USE_HEADERMAP),Xcode 会生成项目中所有头文件的映射文件,并在此映射文件中搜索与包含文件名称匹配的条目。在这种情况下,路径无关紧要,因为它也只匹配文件的名称。

对于系统标头,尖括号 ( <...>) 之间的标头,仅搜索构建设置System Header Search Paths( SYSTEM_HEADER_SEARCH_PATHS) 中的搜索路径。

但是,如果启用了构建设置Always Search User Paths( ALWAYS_SEARCH_USER_PATHS),也会在用户搜索路径中搜索系统标头包含。这允许您使用自己的同名用户标头覆盖系统标头。但是请注意,这已被 Xcode 弃用,不应再这样做。

如果您的文件系统不区分大小写(macOS 上的默认设置),那么在所有搜索过程中大小写将不起作用。

如果您想最大程度地控制要包含的文件,请禁用标头映射并始终包含相对于执行包含的文件的路径(您也可以使用“..”)。这避免了任何歧义。

于 2021-09-14T16:56:42.037 回答