我有许多源目录的项目。但是需要将所有.obj文件保存在一个平面目录中,例如
我列出了所有源文件及其所在的目录。 使用make版本3.81我使用了混合的隐式和普通规则但是使用make 3.82我无法实现这一点。 目标是不使用shell命令只制作内置函数。
OBJECTS = $(subst .c,.o,$(SRCS))
OBJECTS_OBJ = $(patsubst %.c,$(OBJ_DIR)/%.o,$(notdir $(SRCS)))
SRCDIR = $(dir $(SRCS))
vpath %.c $(SRCDIR)
...
$(OBJ_DIR) $(OBJ_DIR)/%.o : %.c
@echo "======================================================================="
@echo "COMPILATION:" $< " --> " $@
@echo "======================================================================="
@mkdir -p $(dir $@)
$(CC) $(C_FLAGS) $(INCL) $< -c -o $@
其中SRCS是所有源文件的列表。
是否可以在没有递归makefile或没有使用shell命令的情况下实现它。
答案 0 :(得分:0)
只需包含一个创建显式依赖项的makefile:
# Makefile
OBJ_DIR:=objects
SRC_FILES := $(notdir $(SRCS))
all: $(SRC_FILES:%.c=$(OBJ_DIR)/%.o)
tmp_srcs := $(SRCS)
include $(foreach dummy, $(SRCS), object_rule.mk)
$(OBJ_DIR)/.sentinel:
mkdir -p $(dir $@) && touch $@
诀窍在于include语句和foreach的组合。 foreach将生成与SRCS中列出的文件一样多的“object_rule.mk”。包含的makefile,object_rule.mk只是生成相应源文件的对象规则,如下所示:
ifeq (,$(tmp_srcs))
$(error this makefile requires the variable tmp_srcs to be set)
endif
src_path:=$(word 1, $(tmp_srcs))
ifeq (1, $(words $(tmp_srcs)))
tmp_srcs:=
else
tmp_srcs:=$(wordlist 2, $(words $(tmp_srcs)), $(tmp_srcs))
endif
src_file:=$(notdir $(src_path))
obj_file:=$(src_file:%.c=%.o)
$(OBJ_DIR)/$(obj_file): $(src_path) $(OBJ_DIR)/.sentinel
$(CC) $(C_FLAGS) $(INCL) $< -c -o $@
请注意,我已经为$(OBJ_DIR)/。sentinel添加了一个依赖项,以获得正确和准确的依赖关系。
此解决方案不需要手工制作。您可以使用GNU Make Standard Library