【发布时间】:2017-09-07 04:35:38
【问题描述】:
我需要一些帮助来编写 GNU makefile。我有一个 C 程序“main.c”,它取决于文件“constants.h”中定义的“CONSTANT”的值。
“main.c”
#include <stdio.h>
#include "constants.h"
void work(void)
{
int array[CONSTANT];
for (int i = 0; i < CONSTANT; i++) {
printf("%d\n", i);
}
}
int main(int argc, char const* argv[])
{
printf("constant=%d\n", CONSTANT);
work();
return 0;
}
“常数.h”
#ifndef CONSTANTS_H
#define CONSTANTS_H
#define CONSTANT 4
#endif
我在这里要做的是用不同的“CONSTANT”值来编译程序。例如,“out1”用“CONSTANT=1”和“make all”编译,我应该能够产生所有的变体(“out1”、“out2”和“out4”)。
问题是“main.c”所需的“a.o”也取决于“CONSTANT”的值。所以“a.o”必须在“sed%”之后编译。但是,据我了解,“make”中没有办法强制依赖项中的命令(我想这是使用 makefile 的全部意义)。
解决这种情况的推荐方法是什么?
“生成文件”
CC= gcc
CFLAGS = -std=c99 -Wall
CONSTANTS = 1 2 4
targets = $(addprefix out, $(CONSTANTS))
seds = $(addprefix sed, $(CONSTANTS))
.PHONY: $(seds)
$(seds): sed%:
sed -i 's/define CONSTANT [0-9]*/define CONSTANT $*/g' constants.h
$(targets): out%: main.c sed% a.o
$(CC) $(CFLAGS) $< a.o -o $@
a.o: a.c constant.h
$(CC) $(CFLAGS) $< a.o -o $@
.PHONY: all
all : $(targets)
请注意,我知道我可以重写“main.c”,以便它从命令行获取一个参数。实际上,“main.c”以外的许多其他文件都依赖于“CONSTANT”,所以我想避免重写所有这些文件。我也知道我可以执行“gcc -DCONSTANT=n main.c”之类的操作,但也必须重新编译依赖于“CONSTANT”的每个文件。
相关问题
【问题讨论】:
-
Make 假定一旦它构建了一个文件 (
a.o),它就是最新的并且在同一次运行期间不需要重新编译。因此,您必须做其他事情。一种选择是从a.c和constants.h和合适的sed-work 创建a1.o、a2.o和a4.o。如果只有一个常量,请考虑在命令行上使用-DCONSTANT=1,因为您从a.c等创建a1.o,根本不使用constants.h。但是,我怀疑这是对 SO 的最小化问题,并且您拥有的值不仅仅是要设置的值。我仍然倾向于创建不同名称的目标文件。 -
请提供minimal reproducible example 进行测试。 IE。定义改变的情况(constant.h)或调用makefile的某种方式)和期望的结果,即文件的输出或结果内容。
-
@JonathanLeffler 我按照您和 Mike 的建议生成了单独的目标文件(a1.o、a2.o、....)。我的程序只有一个常量要配置,所以你的解决方案对我有用。谢谢。
-
欢迎来到 Stack Overflow。请注意,在这里说“谢谢”的首选方式是投票赞成好的问题和有用的答案(一旦你有足够的声誉这样做),并接受对你提出的任何问题最有帮助的答案(这也给出了你的声誉小幅提升)。请参阅About 页面以及How do I ask questions here? 和What do I do when someone answers my question?