C 如何包含可能存在或不存在的头文件?

C 如何包含可能存在或不存在的头文件?,c,gcc,include,header-files,C,Gcc,Include,Header Files,假设我在foo.h中定义了BAR。但是foo.h可能不存在。我如何包含它,而不让编译器对我抱怨 #include "foo.h" #ifndef BAR #define BAR 1 #endif int main() { return BAR; } 因此,如果BAR在foo.h中定义为2,那么如果foo.h存在,程序将返回2,如果foo.h不存在,程序将返回1。使用类似的工具,这就是它的设计目的。(在windows上,您可能更喜欢使用) 因此,在您的configure.ac中,有一

假设我在foo.h中定义了BAR。但是foo.h可能不存在。我如何包含它,而不让编译器对我抱怨

#include "foo.h"

#ifndef BAR
#define BAR 1
#endif

int main()
{
    return BAR;
}
因此,如果BAR在foo.h中定义为2,那么如果foo.h存在,程序将返回2,如果foo.h不存在,程序将返回1。

使用类似的工具,这就是它的设计目的。(在windows上,您可能更喜欢使用)

因此,在您的
configure.ac
中,有一行代码如下:

AC_CHECK_HEADERS([foo.h])
在运行
configure
之后,它将定义
HAVE_FOO_H
,您可以这样测试:

#ifdef HAVE_FOO_H
#include "foo.h"
#else
#define BAR 1
#endif

如果您打算使用自动工具(即autoconf和automake,因为它们可以很好地协同工作),我建议您从这一点开始。

一般来说,您需要做一些外部的事情来完成这一点-例如,通过玩搜索路径之类的事情(如注释中建议的那样)并提供一个空的
foo.h
作为后备,或将
#include
包装在
#ifdef HAS_foo_h
#endif
中,并通过编译器开关(
-DHAS_foo_h
用于gcc/clang等)设置
HAS_foo_h


如果您知道您正在使用一个特定的编译器,并且可移植性不是问题,请注意,有些编译器确实支持将可能存在或不存在的文件作为扩展名。例如,请参阅clang的功能。

提供您自己的fallback foo.h,它定义
BAR
,并相应地配置编译器的搜索路径?我想我可以这样做。为什么fallback foo.h需要包含任何内容?第二个foo.h fallback文件的可能副本是最简单的解决方案。这也是一个糟糕的解决方案,因为如果真实的
foo.h
更改其内部头保护
#define
,您会得到细微的破坏。为什么?回退foo.h是空的。我猜Jack误读了foo.h,认为它是在真正的foo.h中定义的东西。但杰克说得有道理。回退foo.h不应为空。它应该定义一个符号,指示使用了回退。这比依赖真正的foo.h.的任何符号要好。API可以更改,宏可以更改为C常量。自动工具可以。。。嗯,很痛苦,而且现在完全没有必要了。Mac和Linux有很好的CMake支持,还有其他很好的构建系统(如。ESR有一个特别令人痛心的帖子值得考虑:。CMake造成的痛苦远远超过autotools’。它将一个受MSVC启发的构建类型模型强加到unix平台上,并附带了一种新的笨拙的编程语言,该语言缺少适当的数据结构,以一种特殊的方式进行扩展,内置了随机的东西(qt4!?fltk!?)。ESR的咆哮全是硫酸,没有任何物质。我在几个项目中使用过CMake、SCons和autotools,几乎每次都会使用autotools。要替换自动工具,您不需要编译为makefile
make
的模型被微妙地破坏了,替换者必须理解这一点。