使用自动变量进行Makefile编译

时间:2016-10-18 11:50:17

标签: c makefile gnu-make

我在makefile中尝试简单但无法使其正常工作。以下是与我的要求相关的示例文件:

生成文件:

OBJDIR=obj

dummy_build_folder := $(shell mkdir -p $(OBJDIR))

CC = gcc

SRCS =  1/print.c \
        2/add.c

INCLUDE =   -I "./1/" \
          -I "./2/" \

OBJS = $(addprefix $(OBJDIR)/,$(patsubst %.c,%.o,$(notdir $(SRCS))))

$(OBJDIR)/%.o: %.c
  @-if not exist $(OBJDIR) mkdir $(OBJDIR) 1>NUL 2>NUL  
  $(CC) -c $(INCLUDE) $< -o $@

all: $(OBJS)
  @-if not exist $(OBJDIR) mkdir $(OBJDIR) 1>NUL 2>NUL
  @echo $(OBJS)

.PHONY : clean

clean:
    rm $(OBJS)

当我试图运行时,我遇到以下错误: “make:***没有规则制作目标'obj / print.o',需要'全部'。停止。”

我也试过使用“$(OBJDIR)/%。o:$(SRCS)”,但这里$&lt;仅指向print.c,而$ @正在递增到下一个文件(即print.o&amp; add.o)。上面是尝试编译print.c文件两次并将输出放在print.o和add.o

gcc -c -I "./1/" -I "./2/"  1/print.c -o obj/print.o

gcc -c -I "./1/" -I "./2/"  1/print.c -o obj/add.o

我的目录结构是:

RootFolder:

    1/print.c

    2/add.c

    3/xyz.c (Don't want to compile this file)

    Makefile

另外,我想将所有.o文件保存在上面位置的不同文件夹(./obj/*o)中。

1 个答案:

答案 0 :(得分:0)

.o个文件与相应的.c文件之间没有依赖关系,也没有匹配规则,这是make make: *** No rule to make target 'obj/print.o', needed by 'all'. Stop.告诉您的内容。

模式规则$(OBJDIR)/%.o : %.c无法与.c.o匹配,因为目标文件在.c的路径中没有目录级别。该$(notdir ...)调用删除了该目录级别。

模式规则中的%(词干)部分必须匹配。例如。在$(OBJDIR)/1/print.o : 1/print.c中,词干是1/print。而$(OBJDIR)/print.o : 1/print.c print1/print不符。

避免此问题的一个好方法是为输出文件构建与源文件相同的目录结构。

已修复Makefile

OBJDIR := obj
CC := gcc

SRCS := 1/print.c 2/add.c

INCLUDE := -I "./1/" -I "./2/"

OBJS := $(patsubst %.c,${OBJDIR}/%.o,${SRCS})
DEPS := $(patsubst %.c,${OBJDIR}/%.d,${SRCS})

all: $(OBJS)
    @echo "Object files are $(OBJS)"

.SECONDEXPANSION:

# This rule creates the object file and its directory.
$(OBJS) : ${OBJDIR}/%.o : %.c | $$(dir $$@)
    $(CC) -c $(INCLUDE) $< -MD -MP -o $@

${OBJDIR}/%.d : ;

${OBJDIR}/% :
    mkdir -p $@

clean :
    rm -rf ${OBJDIR}

.PHONY: all clean

-include ${DEPS}

使用示例:

$ mkdir 1 2
$ touch 1/print.c 2/add.c
$ make
mkdir -p obj/1/
gcc -c -I "./1/" -I "./2/" 1/print.c -MD -MP -o obj/1/print.o
mkdir -p obj/2/
gcc -c -I "./1/" -I "./2/" 2/add.c -MD -MP -o obj/2/add.o
Object files are obj/1/print.o obj/2/add.o

注意:

  1. 使用仅订单依赖项| $$(dir $$@)自动为您创建输出目录。
  2. 使用-MD -MP-include ${DEPS}位自动为您创建头文件依赖项。