我尝试编写一个makefile,它在当前目录中搜索lib-directories,编译每个目录的源代码并将object-file放入一个单独的object-directory中。我不想拥有多个makefile。
这个makefile将执行此操作:
SRCDIR := $(shell ls -d lib_*/)
CC := gcc
DB := gdb
OBJDIR := obj
CFLAGS := -Wall -Werror -Wextra -pedantic -O3
LDFLAGS := #
# Rules
all:
@ # create object directory
@mkdir -p $(OBJDIR)/ ;
@ # go through all source dirs
@for dir in $(SRCDIR); do \
echo $$dir && \
cd $$dir && \
for n in $$(ls *.c); do \
m=$${n%%.c}; \
$(CC) -c \
$(CFLAGS) \
$(LDFLAGS) \
-o ../$(OBJDIR)/$$m.o $$n;\
done; \
cd ..; \
done
但是:makefile编译每个运行所有源。这些来源也没有任何变化。如果makefile可能识别是否有更改,并且只编译更改的源?
这里是dirs的结构:
lib
|-lib_one
| |-lib_one.c
| |-lib_one.h
|
|-lib_two
| |-lib_two.c
| |-lib_two.h
|
|-lib_n
| |-lib_n.c
| |-lib_n.h
|
|-obj
| |-lib_one.o
| |-lib_two.o
| |-
| |-lib_n.o
|
|-makefile
答案 0 :(得分:1)
您可以使用以下内容:
SRCDIR := $(shell ls -d lib_*/)
CC := gcc
DB := gdb
OBJDIR := obj
CFLAGS := -Wall -Werror -Wextra -pedantic -O3
LDFLAGS := #
# Rules
all:
@ # create object directory
@mkdir -p $(OBJDIR)/ ;
@ # go through all source dirs
@for dir in $(SRCDIR); do \
echo $$dir && \
cd $$dir && \
for n in $$(ls *.c); do \
m=$${n%%.c}; \
if [ ! -e ../$(OBJDIR)/$$m.o ] || \
[ `stat -c %Y ../$(OBJDIR)/$$m.o` -lt `stat -c %Y $$n` ] || \
([ -e $$m.h ] && [ `stat -c %Y ../$(OBJDIR)/$$m.o` -lt `stat -c %Y $$m.h` ]); then \
echo "Change detected, compiling $$n..."; \
$(CC) -c \
$(CFLAGS) \
$(LDFLAGS) \
-o ../$(OBJDIR)/$$m.o $$n;\
fi; \
done; \
cd ..; \
done
以下行添加对目标文件的检查以查看它们是否存在,如果是,则将源修改时间与对象修改时间进行比较(重复make
make
内部工作的类型)。
if [ ! -e ../$(OBJDIR)/$$m.o ] || [ `stat -c %Y ../$(OBJDIR)/$$m.o` -lt `stat -c %Y $$n` ] || ([ -e $$m.h ] && [ `stat -c %Y ../$(OBJDIR)/$$m.o` -lt `stat -c %Y $$m.h` ]); then
答案 1 :(得分:1)
如果您不关心头文件,可以这样做:
SRCS := $(wildcard */*.c)
OBJDIR := obj
OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SRCS)))
all: $(OBJS)
@:
$(OBJDIR)/%.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
vpath %.c $(wildcard *)
如果您关心明显的标题文件(例如lib_one.c
包含lib_one.h
),那么您可以进行简单的调整:
$(OBJDIR)/%.o: %.c %.h
$(CC) -c $(CFLAGS) -o $@ $<
vpath %.c $(wildcard *)
vpath %.h $(wildcard *)
如果您有其他依赖项(例如lib_n.c
包含lib_one.h
),您可以手动添加它们:
lib_n.o: lib_one.h
或者您可以使用Advanced Auto-Dependency Generation,但这是一种先进的技术,我建议您再离开一天。