确保config.h包含一次

And*_*nga 2 linux autotools header-files

我有一个库项目,我正在移植到使用Linux中的autotools套件.我对autotools很新(本周).我已经学会了它的操作基础知识.我有一个关于如何保持内容config.h不被重新定义的问题.

我很惊讶地发现生成的config.h文件也没有,1)将每个宏包装在#ifndefor中,2)整个文件没有包装在标准中#ifndef CONFIG_H.

正如我所提到的,这段代码是基于Windows和Linux构建的.因此,宏的一些用途_linux(我不是说这是最好的名称,但它在各处都在使用)将元素引入仅存在于Linux中的类.因此,这将发生

header.h

#ifndef HEADER1_H
#define HEADER1_H

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#endif
Run Code Online (Sandbox Code Playgroud)

source.cxx

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "header.h"  // oops, preprocessor gets excited because of redefs
Run Code Online (Sandbox Code Playgroud)

一个简单的解决方案是在config.h.in生成文件后执行标准的独特包装.但是,我想知道,有没有更好的方法来处理这个?我不可能是第一个遇到这种情况,甚至可能有一种处理它的方法,configure.ac但在这方面是一个完整的新手,我不知道甚至要搜索什么.

5go*_*der 5

我这样做的方式确实是创建一个包装文件(我通常称之为global.h),就像这样.

#ifndef MY_PROJECT_GLOBAL_H
#define MY_PROJECT_GLOBAL_H

#include <config.h>

/* Maybe other global definitions… */

#endif
Run Code Online (Sandbox Code Playgroud)

请注意,建议的方式#includeconfig.h文件是通过<config.h>"config.h"那么它工作得更好VPATH的基础之上.

然后,所有在我的项目文件,#include这个global.h标题为他们的第一个#include和不关心config.h.永远不应该使用文件,#include config.h因为这会导致错误的名称冲突.实际上,如果您遵守本指南,您的代码也应该#include在配置标题中没有保护.


关于OP评论的更新

或者:如何在标题中使用配置结果?

如果你的标题需要根据configure脚本的结果声明不同的东西,你有很多选项,其中没有一个是完美的.

对于内部标题,没有问题.他们只是依赖于#define没有#include任何东西的宏.如果 - 按照建议 - 任何其他标头之前的所有源文件#include(可能间接如上所示)config.h ,这都有效.

如果要公开安装标头,这不是一个很好的解决方案.对于那些使用Autoconf的用户来说,它不会那么糟糕,尽管即使那些人必须记住要在他们的configure.ac文件中放置什么检查.对于不使用Autoconf的用户来说,这将非常糟糕.如果你只有几个开关(比如Glibc的fature测试宏),可以#define#include你的标题之前询问你的用户,但如果你需要很多,这不是一个真正的选择.更不用说你会以这种方式向用户公开大量的实现细节.

如果您需要做的就是根据您正在构建的平台进行分支,您可以探测一些预定义的宏,如__linux_WIN32.有一个Boost.Predef库,旨在通过提供更高级别的抽象来使这些检查更加方便.该库可以与C和C++一起使用,但是,它当然会为您的项目添加额外的依赖项.

最后,您可以创建一个config.h使用特定于项目的宏前缀的版本.Autoconf宏归档中有一个贡献,它完全适合您.最小的例子看起来像这样.

AC_PREREQ([2.69])
AC_INIT([example-project], [1.0], [bugs@example.org])
AC_CONFIG_SRCDIR([example.c])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AX_PREFIX_CONFIG_H([public_config.h], [EXAMPLE_PROJECT], [config.h])
AC_PROG_CC
AC_OUTPUT

保存为configure.ac,从Autoconf宏存档下载ax_prefix_config_h.m4并将其放在子目录中m4然后运行autoreconf && ./configure.它将创建正常config.h,此外public_config.h在后一个文件中,所有宏都以前缀为前缀EXAMPLE_PROJECT_.如果需要,可以在项目的公共头文件中安装该文件public_config.h(#include顺便提一下也有防护)#include.