makefile中的宏?有条件的 h 文件包含?

Posted

技术标签:

【中文标题】makefile中的宏?有条件的 h 文件包含?【英文标题】:macro in makefile? Conditional h-file inclusion? 【发布时间】:2016-09-14 11:29:10 【问题描述】:

让我解释一下我的情况: 我有一个包含不同类型模型的程序(比如说 10 个,但实际数量非常高)。所有这些模型都有一个名称和相应的文件“model1.cu”和“model1.h”。所有这些文件都有一个函数,它产生一个浮点数并返回它,它在所有名称相同的文件中,具有相同的参数(比如说float returnfunction(float voltage))。主文件中需要此特定功能。 在 makefile 中,我设置了一个选项,您可以只编译您将要计算的模型的代码,如下所示:

ifdef MODEL1
SRCS := model1.cu
OBJS := model1.o
endif

ifdef MODEL2
SRCS := model2.cu
OBJS := model2.o
endif

SRCS += main.c

现在我可以通过键入“make MODEL1=1”来选择正确的模型。问题出现在主文件中。函数returnfunction(float voltage) 定义在model1.h 中,所以我应该包含它。但是当我包括

#ifdef MODEL1
#include "model1.h"
#endif

#ifdef MODEL2
#include "model2.h"
#endif

在我的 main.c 文件中,我收到函数 returnfunction 未在任何地方定义的错误。 有没有办法让我的主文件中包含正确的 h 文件?最好使用我已经使用 MODEL1 = 1 编译的那个。

非常感谢任何帮助!

【问题讨论】:

顺便说一下,更简洁的方法是将每个模型放在一个单独的子目录中,文件名为 e.g. model.cumodel.h。设置VPATH 并从您的makefile 中添加-I 标志,然后您可以在main.c 中设置SRCS := model.cuOBJS := model.o 和一般#include <model.h> 我喜欢你的想法,但你能指定 VPATH 和 -I 的使用吗?我不熟悉 makefile 中所有可能的选项,而且文档对我来说通常很难理解。我想知道的是您将在makefile中放入的行(假设地图称为:NewModel,它包含model.cu和model.h)(我得到的其余概念)。是否类似于:#ifdef MODEL1 VPATH = -I ./NewModel #endif ? 评论太长了,所以我为此写了一个答案,基本上每个ifdef都会丢掉。这只是一个建议,接受的答案将修复您发布的代码。 【参考方案1】:

您可以简单地为您拥有的每个模型添加一个预处理器定义到您的 Makefile。例如,在 MODEL1=1 的情况下:

ifdef MODEL1
SRCS := model1.cu
OBJS := model1.o
CFLAGS += -DMODEL1
endif

假设您使用的是implicit rules,修改后的CFLAGS 将被传递给每个编译的文件。如果您使用自己的规则编译 main.c(并且没有使用 CFLAGS),那么您可以创建一个变量,然后显式传递它。

【讨论】:

【参考方案2】:

另一个答案是重点,并修复了您丢失的#define。我将扩展我留下的关于清洁/干燥方式的评论。

第一部分是将每个模型放在自己的目录中,并具有通用的源/标题名称。例如:

├── models
    ├── model1
    │   ├── model.cu
    │   └── model.h
    ├── model2
    │   ├── model.cu
    │   └── model.h
    └── ...

(你可能会删除***models目录,没关系)

我们将使用包含路径,因此您可以从 main.c 中删除整个 #ifdef 内容,并将其替换为单个 #include <model.h>

接下来,让我们更聪明地了解如何指定模型。而不是MODEL1MODEL2 等,让我们使用一个通用的MODEL 变量来获取模型名称,所以make 命令看起来像MODEL=model1 make(如果有单独的变量是一个硬性要求,有办法不用大量 ifdefs 就可以做到这一点,但它仍然更丑)。

此时编写 Makefile 变得微不足道:

SRCS := models/$(MODEL)/model.cu main.c
OBJS := $(addsuffix .o,$(basename $(SRCS)))
CFLAGS += -Imodels/$(MODEL)

我不知道您稍后在 Makefile 中是如何处理 SRCSOBJS 的,所以我只是使用 addsuffixbasename 在其中添加了 .o,但您可以更改它根据您的需要。我通过CFLAGS 将模型目录添加到包含路径中,这样它就会选择正确的model.h

您也可以像这样指定来源:

VPATH := models/$(MODEL)
SRCS := model.cu main.c

由于 make 会查看 VPATH 的来源。

一些杂项:如果您仍然需要 C #define,您可以通过 CFLAGS 添加它。如果您的.h 文件中有一些常见的东西,请考虑将其重构为***.h,然后再将其重构为#include <model.h>。如果您的编译器支持它,#include_next 可能也很方便。

【讨论】:

以上是关于makefile中的宏?有条件的 h 文件包含?的主要内容,如果未能解决你的问题,请参考以下文章

跟我一起写Makefile

define

Makefile - 将多个文件夹中的头文件复制到一个包含依赖项的包含文件夹中

uboot中 各个c文件是怎么读取 uboot/include/configs/(board name).h里定义的宏。

Makefile中的宏定义必须采用 和 么

关于makefile的生成原理以及make相关命令的使用