我需要一些帮助编写GNU makefile。我有一个C程序" main.c",这取决于" CONSTANT"的值。在文件" constants.h"中定义。
" 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;
}
&#34; constant.h&#34;
#ifndef CONSTANTS_H
#define CONSTANTS_H
#define CONSTANT 4
#endif
我在这里尝试做的是使用不同的值编译程序&#34; CONSTANT&#34;。例如,&#34; out1&#34;编译时使用&#34; CONSTANT = 1&#34;并且使用&#34; make all&#34;,我应该能够生成所有变体(&#34; out1&#34;,&#34; out2&#34;&#34; out4&#34;)。
问题是&#34; a.o&#34; &#34; main.c&#34;也取决于&#34; CONSTANT&#34;的价值。所以&#34; a.o&#34;必须在&#34; sed%&#34;之后编译。但是,据我所知,没有办法在&#34; make&#34;强制依赖命令(我想这是使用makefile的重点)。
解决这种情况的推荐方法是什么?
&#34;生成文件&#34;
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)
请注意,我知道我可以重写&#34; main.c&#34;这样它就会从命令行中获取一个参数。在实践中,除了&#34; main.c&#34;之外的许多其他文件。取决于&#34; CONSTANT&#34;,所以我想避免重写所有这些文件。我也知道我可以做类似&#34; gcc -DCONSTANT = n main.c&#34;,但是每个文件都依赖于&#34; CONSTANT&#34;必须重新编译。
相关问题
答案 0 :(得分:3)
我知道我可以做类似&#34; gcc -DCONSTANT = n main.c&#34; 但是每个文件都依赖于&#34; CONSTANT&#34;必须重新编译。
如果你生成了makefile,这不是一个障碍
每个编译配方中正确的-DCONSTANT=n
和不同的目标文件。
以下是一个例子:
<强> constants.h 强>
#ifndef CONSTANTS_H
#define CONSTANTS_H
#ifndef CONSTANT
#define CONSTANT 4
#endif
#endif
<强> foo.c的强>
#include "constants.h"
int foo = CONSTANT;
<强>的main.c 强>
#include <stdio.h>
#include "constants.h"
extern int foo;
int main()
{
printf("%d\n",CONSTANT + foo);
return 0;
}
<强>生成文件强>
CC := gcc
CFLAGS := -std=c99 -Wall
CONSTANTS = 1 2 4
TARGETS = $(addprefix out, $(CONSTANTS))
SRCS := main.c foo.c
define compile =
$(basename $(1))$(2).o: $(1) constants.h
$$(CC) -c -DCONSTANT=$(2) $$(CFLAGS) $$< -o $$@
endef
.PHONY: all clean
all : $(TARGETS)
$(foreach src,$(SRCS),\
$(foreach const,$(CONSTANTS),$(eval $(call compile,$(src),$(const)))))
out%: main%.o foo%.o
$(CC) $^ -o $@
clean:
rm -f $(TARGETS) *.o
这就像:
$ make
gcc -c -DCONSTANT=1 -std=c99 -Wall main.c -o main1.o
gcc -c -DCONSTANT=1 -std=c99 -Wall foo.c -o foo1.o
gcc main1.o foo1.o -o out1
gcc -c -DCONSTANT=2 -std=c99 -Wall main.c -o main2.o
gcc -c -DCONSTANT=2 -std=c99 -Wall foo.c -o foo2.o
gcc main2.o foo2.o -o out2
gcc -c -DCONSTANT=4 -std=c99 -Wall main.c -o main4.o
gcc -c -DCONSTANT=4 -std=c99 -Wall foo.c -o foo4.o
gcc main4.o foo4.o -o out4
结果程序运行如下:
$ for i in 1 2 4; do ./out$i; done
2
4
8