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.cu
和 model.h
。设置VPATH
并从您的makefile 中添加-I
标志,然后您可以在main.c
中设置SRCS := model.cu
、OBJS := 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>
。
接下来,让我们更聪明地了解如何指定模型。而不是MODEL1
、MODEL2
等,让我们使用一个通用的MODEL
变量来获取模型名称,所以make 命令看起来像MODEL=model1 make
(如果有单独的变量是一个硬性要求,有办法不用大量 ifdef
s 就可以做到这一点,但它仍然更丑)。
此时编写 Makefile 变得微不足道:
SRCS := models/$(MODEL)/model.cu main.c
OBJS := $(addsuffix .o,$(basename $(SRCS)))
CFLAGS += -Imodels/$(MODEL)
我不知道您稍后在 Makefile 中是如何处理 SRCS
和 OBJS
的,所以我只是使用 addsuffix
和 basename
在其中添加了 .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 - 将多个文件夹中的头文件复制到一个包含依赖项的包含文件夹中
uboot中 各个c文件是怎么读取 uboot/include/configs/(board name).h里定义的宏。