我有一组源文件,我需要从中生成多个可执行文件的变体。例如,我需要从同一 main.c app1.elf , app2.elf , app3.elf >和 comm.c 。每个应用程序之间的区别是节点地址,这是在gcc调用中传递的参数。即:
gcc -DNODE=1 -oapp1.elf main.c
gcc -DNODE=2 -oapp2.elf main.c
gcc -DNODE=3 -oapp3.elf main.c
我们假设我有以下文件:
当我按原样运行Makefile时:
制作all_nodes
仅使用以下输出构建app1.elf:
内置app1
内置app2
内置app3
FAIL! 输出似乎表明它有效,但它只生成一个可执行文件,即app1.elf。有人想指出我做错了什么吗?
为了进一步解释我的Makefile,我创建了一个 cleanobjs 目标来清除./obj子目录中的对象。这是我尝试使用新的节点地址'make'重建obj文件,但它失败了。我是否以某种不打算使用的方式使用'make'?我知道我也可以创建一个批处理文件来运行make(我已经成功完成了)但是我想知道我做错了什么。我的Makefile如下:
obj/%.o: src/%.c
gcc -DNODE=$(NODE) -o$@ $<
app.elf : ./obj/main.o ./obj/comm.o
gcc -oapp$(NODE).elf main.o comm.o
node1 : NODE=1
node1 : cleanobj app.elf
@echo 'Built app1'
node2 : NODE=2
node2 : cleanobj app.elf
@echo 'Built app2'
node3 : NODE=3
node3 : cleanobj app.elf
@echo 'Built app3'
all_nodes : node1 node2 node3
cleanobj :
rm -rf obj/main.o obj/comm.o
.PHONY : cleanobj
答案 0 :(得分:6)
您将需要针对不同版本的多个目标。每个目标都需要自己的main.o和comm.o目标,这意味着你需要将它们称为其他东西,否则它们最终会相互混淆。然后你的所有人都应该发挥作用来建立这三个。
答案 1 :(得分:3)
类似的方法:
ifeq ($(NODE),)
all:
make NODE=1
make NODE=2
make NODE=3
cleanobj:
make NODE=1 cleanobj
make NODE=2 cleanobj
make NODE=3 cleanobj
else
OBJS = main.o comm.o
objs = $(patsubst %.o,obj/$(NODE)/%.o,$(OBJS))
app$(NODE).elf: $(objs)
gcc -o app$(NODE).elf $^
@echo 'Built app$(NODE)'
obj/$(NODE)/%.o: src/%.c
gcc -c -DNODE=$(NODE) -o $@ $<
cleanobj :
rm -rf $(objs)
endif
.PHONY: all cleanobj
答案 2 :(得分:2)
这就是我要做的事情:
SRC = src/main.c
OBJ = $(patsubst src%,obj$(VERSION)%,$(patsubst %.c,%.o,$(SRC)))
C_FLAGS = -DNODE=$(VERSION)
all: app.1 app.2 app.3
#
# For each application just call make with VERSION set correctly
app.%: dir.%
$(MAKE) VERSION=$* app$*.elf
#
# Build each applications objects into a seprate directory
# So we need to make sure the obj directory exists.
dir.%:
@- if ! test -e obj$*; then mkdir obj$*; fi
app%.elf: $(OBJ)
$(CC) -o$@ $(C_FLAGS) $(OBJ)
obj$(VERSION)/%.o: src/%.c
$(CC) -c -o obj$(VERSION)/$*.o $(C_FLAGS) $<
答案 3 :(得分:1)
简单的方法是创建单独的构建目录,并使用VPATH
允许您的(大部分未修改的)Makefile在单独的目录中构建原始源。
稍微更难的方法是修改Makefile以重写目标.o
和可执行文件在子目录中。例如:
NODE = 1
OBJDIR = obj.node$(NODE)
SRC = main.c comm.o
OBJ = $(SRC:%.c=$(OBJDIR)/%.o)
然后你的目标会在设置NODE
的情况下重新调用你的Makefile。
答案 4 :(得分:0)
创建一个批处理文件或shell脚本,可以创建所有三个版本。类似的东西:
make node1
<if needed copy your executable to a different directory>
<clean all objs from make node1>
make node2
<if needed copy your executable to a different directory>
<clean all objs from make node1>
make node3
<if needed copy your executable to a different directory>
<clean all objs from make node1>
为all_node
构建规则调用此批处理文件或shell脚本。