Gcc 使用编译器选项重写宏

Gcc 使用编译器选项重写宏,gcc,c-preprocessor,Gcc,C Preprocessor,我需要用头文件覆盖某些宏定义。我不允许更改源代码。我必须使用gcc,但是如果有人知道任何其他编译器上有类似的东西,那么它也会有所帮助 以下是我真正需要的: 假设我有很多.c文件的代码库。这些.c文件包括.h文件。在为每个文件包含所有.h文件之后,我希望编译器的行为就像我在调用编译器时要指定的另一个额外的.h文件一样。我在该.h文件中所做的是#unde一些宏,并按照我希望的方式重新定义宏 注意:我知道gcc中有--preinclude选项,但使用--preinclude会使我的额外.h超过原始源代

我需要用头文件覆盖某些宏定义。我不允许更改源代码。我必须使用gcc,但是如果有人知道任何其他编译器上有类似的东西,那么它也会有所帮助

以下是我真正需要的:

假设我有很多.c文件的代码库。这些.c文件包括.h文件。在为每个文件包含所有.h文件之后,我希望编译器的行为就像我在调用编译器时要指定的另一个
额外的.h
文件一样。我在该.h文件中所做的是
#unde
一些宏,并按照我希望的方式重新定义宏


注意:我知道gcc中有
--preinclude
选项,但使用
--preinclude
会使我的额外.h超过原始源代码的.h。我需要的是某种post include选项。

除非您统一使用一个特定的头文件,该头文件总是最后包含在源文件中,否则这将是一个棘手的问题

我认为,如果我不得不这样做,我会:

  • 创建一个新目录,称之为
    headers
  • 放入与常规头同名的合适的伪头,在末尾包含
    #include“extra.h”
    (或者可能是
    #include
    ,但我会尽量避免)
  • 虚拟头也会通过某种机制包括原始文件,甚至可能使用
    #include”/usr/include/header.h“
    ,但最好使用一些其他技术,例如
    #include“include/header.”
  • extra.h
    标题将始终重新定义其所有宏-它不会包含正常的
    \ifndef extra\u h\u
    /
    \define extra\u h\u INCLUDED
    /
    \endif
    多个包含保护,因此每次包含它时,它都会重新定义相关的宏
  • 因此,
    extra.h
    无法定义任何类型。(或者,更准确地说,如果是这样的话,则必须通过多个include-guard来保护这些宏不受多个定义的影响;关键是每次包含文件时都必须定义宏,这有点像
  • 每个重新定义的宏都将受到
    #undef redefined_宏
    的显式保护,然后是
    #define redefined_宏…
  • 在取消定义宏之前,测试宏是否已定义没有意义
  • 构建过程将被修改为先查看
    headers
    目录,然后再查看其他任何地方。编译器选项可能是
    -I./headers
    或类似的选项,具体取决于
    headers
    目录的确切位置
  • 根据您决定如何定位正常版本的标题,您可能需要另一个
    -I
    选项(例如
    -I/usr
    ,如果您使用
    #include“include/header.h”
    符号)来再次定位标准标题
结果是,编译器直接使用您的私有头,但它们包括标准头,然后是
extra.h
头,这样就可以在不修改C源代码或普通头的情况下实现您想要的


但是整个尝试中有一些错误……最好不要尝试。Makefile可以通过-U和-D编译器(gcc)选项用于重新定义宏。但为什么要在评估原始文件后重新定义它们呢?我想不出有必要做这样的事。您能告诉我您希望通过这个实现什么吗?

要求在.c文件中的所有其他.h文件之后插入额外的.h。因此,在每个.h文件的末尾添加它将在.c文件中按顺序包含的两个.h文件之间插入它,这不是目的

您可以在makefile中使用sed/awk来: -首先创建重复的.c文件,在每个.c文件中插入“#include”extra.h”,然后在其他#include行之后插入“#include”extra.h”(解析.c文件中的#ifdef块会很麻烦) -然后通过编译那些重复的.c文件来实现您的目标
-最后删除重复的.c文件

根据您的要求,我可以考虑使用两种方法,我希望这两种方法都相对简单

第一种方法根本不涉及源代码,但是它要求每个要从中定义内容的头文件都有一个头保护。您可以将需要“更改”内容的每个头文件复制并连接到一个整体文件中,即“extra.h”文件。然后在该文件的末尾,继续并重新定义所需的所有宏。然后在编译时包含此文件。收割台护罩将防止包括原始收割台。显然,这种方法存在许多潜在的问题,而且一般来说肯定不起作用

第二种方法更干净、更可靠,但它要求您直接编辑代码,尽管是非侵入性的。对于需要在中重新定义内容的每个标题,使用“.orig”后缀或其他内容复制该标题,然后直接编辑实际的标题文件。在您完成所有您正在做的事情之后,在您的客户获得代码之前,只需将所有“.orig”文件复制回实际的头文件中。我假设您的需求不是如此苛刻,以至于您甚至暂时无法更改代码

如果这些都不起作用,那么我怀疑你是否能从任何人那里找到一个有效的答案,除非你直接入侵GCC并自己添加“-postclude”选项。

你可以使用
-包括GCC的文件
选项,因为此功能:

如果提供了多个-include选项,则文件将按照它们在命令行上出现的顺序被包含。

因此,据我所知,您必须包含命令行中的所有*.h文件,-只需将“extra.h”保留在
-include中的最后一个头中即可