使用编译器选项覆盖宏

时间:2010-11-15 04:48:32

标签: gcc c-preprocessor

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

这就是我所需要的:

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

注意:我知道gcc中的--preinclude选项,但使用--preinclude覆盖了原始源代码的.h的extra.h。我需要的是某种帖子包含选项。

5 个答案:

答案 0 :(得分:3)

除非您统一拥有一个始终包含在源文件中的最后一个特定标头,否则这将非常棘手。

我想我接近它的方式,如果必须的话,那就是:

  • 创建一个新目录,将其命名为headers
  • 在那里添加与常规标题同名的合适的虚拟标题,最后包含#include "extra.h"(或者可能#include <extra.h>,但我会尽量避免这种情况。)
  • 虚拟标题还会通过某种机制包含原始文件,甚至可能使用#include "/usr/include/header.h",但最好使用其他一些技术 - 例如#include "include/header."
  • extra.h标题始终会重新定义其所有宏 - 它不会有正常的#ifndef EXTRA_H_INCLUDED / #define EXTRA_H_INCLUDED / #endif多个包含守卫,因此每次都是包括在内,它将重新定义相关的宏。
  • 因此,extra.h无法定义任何类型。 (或者,更确切地说,如果确实如此,那些必须受到多个包含保护的多重定义保护;关键点是每次包含文件时都必须定义宏 - 有点像<assert.h>。)< / LI>
  • 每个重新定义的宏都会被#undef REDEFINED_MACRO明确保护,然后#define REDEFINED_MACRO ...
  • 测试宏是否在定义之前没有定义是没有意义的。
  • 在查看其他任何地方之前,将修改构建过程以查看headers目录。编译器选项可能是-I./headers或类似的,具体取决于您找到headers目录的确切位置。
  • 根据您决定如何找到标头的正常版本,您可能需要另一个-I选项(例如-I/usr如果您使用了#include "include/header.h"表示法)来定位再次标准标题。

结果是您的私有标头被编译器直接使用,但它们包括标准标头,然后是extra.h标头 - 从而实现您想要的而无需修改C源或普通标头。

但是整个尝试都有一些误导......你最好不要尝试这个。

答案 1 :(得分:0)

Makefile可用于通过-U和-D编译器(gcc)选项重新定义宏。但为什么在对原件进行评估后重新定义它们呢?我想不出对这种事情的需要。你能说出你希望通过这个实现什么目标吗?

答案 2 :(得分:0)

要求是在.c文件中的所有其他.h文件之后插入extra.h。因此,在每个.h文件的末尾添加它会将它插入到.c文件中包含的两个.h文件之间,这不是意图。

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

答案 3 :(得分:0)

根据您的要求,我可以通过两种方式来考虑这一点,我希望两者都应该相对简单。

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

第二种方式更清晰,更可靠,但它要求您直接编辑代码,尽管是非侵入性的。对于每个标题,您需要重新定义内容,使用“.orig”后缀或其他内容复制该标题,然后直接编辑实际的标题文件。完成所有操作后,只需将所有“.orig”文件复制回实际的标题中,然后客户就可以获得代码。我认为您的要求并不是那么严苛,以至于您暂时无法更改代码。

如果这些都不起作用,那么我怀疑你会找到一个有效的答案,除非直接黑客攻击GCC并自己添加“-postinclude”选项。

答案 4 :(得分:0)

你可以使用 GCC的-include file选项,因为此功能:

If multiple -include options are given, the files are included in the order they appear on the command line.

据我所知,你必须在命令行中包含所有* .h文件, - 只需将你的“extra.h”保留在-include选项列表中的最后一个标题,你应该得到你想要的。