具有平面.obj目录的manu源目录的非递归makefile

时间:2013-08-08 07:58:27

标签: c makefile gnu-make

我有许多源目录的项目。但是需要将所有.obj文件保存在一个平面目录中,例如

  • SRC1
  • SRC2
  • SRC3
    • SRC4
    • src5
      • src6
      • src7
  • src8
  • 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命令的情况下实现它。

1 个答案:

答案 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