说,有一个具有未定义内部结构的源目录,我们想要获取所有文件并声明它们应该被编译为目标的文件。
类似的东西:
SOURCES := $(shell find src -name \*.c)
OBJS := $(addprefix /tmp,$(addsuffix .o,$(basename $(notdir $(SOURCES)))))
$(OBJS): $(SOURCES)
cc $(CFLAGS) -o $@ $^
但是,它从第二行开始不起作用(它只是空的)。所以,我最终取代了它:
OBJS := $(shell find src -name \*.c -exec sh -c "basename {} | sed 's/^/\/tmp\/g' | sed 's/\.c/\./o/g'" \;)
我不太喜欢这种方法,但无论如何它似乎都不起作用。好的,现在预计会有效。但是,目标不会像预期的那样发挥作用,就像我明确宣布它们一样:
TARGETS := /tmp/foo.o /tmp/bar.o
$(TARGETS): $(SOURCES)
...
相反,我只是收到错误No rule to make target /tmp/foo.o
。
所以,猜猜,我有两个问题:
$(OBJS)
为空?答案 0 :(得分:2)
uname -a
Linux - 3.2.0-4-686-pae #1 SMP Debian 3.2.54-2 i686 GNU/Linux
make -v
GNU Make 3.81
cat makefile
SOURCES := $(shell find ./ -name \*.c)
OBJS := $(addprefix /tmp,$(addsuffix .o,$(basename $(notdir $(SOURCES)))))
$(info $(OBJS))
mkdir test; touch test/1.c; touch test/2.c; make -f makefile
输出:
/tmp1.o /tmp2.o
测试显示,{em>第一个片段没有问题,但在/tmp
之后缺少斜杠。
你如何测试OBJS
的空虚?
你确定SOURCES
没有空吗?
make
中$(info $(SOURCES))
makefile
的输出结果是什么?
*.c
目录中是否有src
个文件?
sed --version
GNU sed 4.2.1
cat makefile
SOURCES := $(shell find ./ -name \*.c)
OBJS := $(shell find ./ -name \*.c -exec sh -c "basename {} | sed 's/^/\/tmp\/g' | sed 's/\.c/\./o/g'" \;)
$(info $(OBJS))
make -f makefile
输出:
sed: -e expression #1, symbol 10: unknown modifier for s'
sed: -e expression #1, символ 12: incomplete command s'
sed: -e expression #1, символ 12: incomplete command s'
sed: -e expression #1, символ 10: unknown modifier for s'
第二个代码段OBJS
的版本不为空
(注意在第一个'\'
命令中删除了sed
,在第二个命令中删除了'/'
。)
OBJS := $(shell find ./ -name \*.c -exec sh -c "basename {} | sed 's/^/\/tmp\//g' | sed 's/\.c/\.o/g'" \;)
是的。如果您可以将.o文件存储在源目录中,这很容易
下一个片段可以解决问题:
sources := $(shell find ./ -name \*.c)
objects := $(sources:.c=.o)
$(objects): %.o: %.c
$(cc) -c $<
但也许这不是你想要的
使用VPATH
和其他几个字符串可以做得更好。
target := ./a.out
obj_dir := ./tmp/
sources := $(shell find ./ -name \*.c)
objects := $(addprefix $(obj_dir), $(notdir $(sources:.c=.o)))
dirs := $(dir $(sources))
VPATH := $(dirs)
$(target): $(objects)
$(cc) -o $@ $^
$(objects): $(obj_dir)%.o: %.c
$(cc) -o $@ -c $<