需要帮助编写Makefile,将所有目标文件创建到新的子目录中

时间:2014-03-25 12:59:35

标签: c makefile

我正在尝试为一个大项目制作一个Makefile 项目结构是(我已经省略了头文件)

root/feature1/feat1.c
root/feature2/feat2.c
root/srcfile1.c
root/srcfile2.c

我想从容易开始,所以我创建了一个更简单的项目,其中包含根目录中的源文件 我需要在一个目录中创建所有目标文件,让我们说, objdir
简单项目的项目结构是:

root/main.c
root/word.c

通过查看其他问题,我提出了这个问题:

CC = gcc
FLAGS = -c
MKDIR_P = mkdir -p
OUT = words
OBJDIR = objdir
SRCDIR = .
_OBJS = main.o word.o
OBJS = $(patsubst %,$(OBJDIR)/%,$(_OBJS))


$(OBJDIR)/%.o: $(SRCDIR)/%.c
    $(CC) -c -o $@ $<

all: directories program

directories: ${OBJDIR}

${OBJDIR}:
    ${MKDIR_P} ${OBJDIR}

program: $(OBJS)
    $(CC) -o $@ $^ $(LIBS)

clean:
    rm -f $(OBJS)

当使用make -f ./myMakefile all运行它时(更改了同一目录中的文件名,有Netbeans&#39; Makefile),我得到了这个输出:

gcc -o objdir/main.o main.c
/tmp/ccatfAHu.o: In function `main':
main.c:(.text+0x15): undefined reference to `CreateWord'
main.c:(.text+0x26): undefined reference to `CreateWord'
collect2: error: ld returned 1 exit status
make: *** [objdir/main.o] Error 1

发出make all命令后,它会尝试生成tar directoriesprogram。 dir objdir已创建,其中包含main.oword.o个文件。

我对simpleproject的makefile做错了什么?

修改
-c规则中添加了$(OBJDIR)/%.o标记 从$ $(FLAGS)中删除了(CC) -o $@ $^ $(FLAGS) $(LIBS) 现在,如果我们转向我的项目问题,我需要访问所有目录中的所有源文件:

  1. /repo-root
  2. /repo-root/feature1/feat1.c
  3. /repo-root/feature2/feat2.c

3 个答案:

答案 0 :(得分:2)

在这条规则中:

$(OBJDIR)/%.o: $(SRCDIR)/%.c
    $(CC) -o $@ $<

您错过了-c标记。 Make正在尝试构建名为objdir/main.o可执行文件,而main.c没有构建所有需要的代码,而不是构建目标文件。就这样做:

$(OBJDIR)/%.o: $(SRCDIR)/%.c
    $(CC) -c -o $@ $<

答案 1 :(得分:1)

试试这个

#source files to compile relative to the src dir
CSOURCE =  main.c
CSOURCE +=  func1.c
SRCDIR = .
vpath %.c $(SRCDIR)/
CC = gcc
MKDIR_P = mkdir -p
OBJDIR = objdir
BINDIR = bindir
#list of objects
OBJS    = $(addprefix $(OBJDIR)/, $(CSOURCE:.c=.o))
#output name for executable
APP = example


all: ${OBJDIR} $(OBJS) bin

#rule to create bin and objects dir
${BINDIR}:
    ${MKDIR_P} ${BINDIR}

${OBJDIR}:
    ${MKDIR_P} ${OBJDIR}

#rule to compile c files
$(OBJDIR)/%.o: %.c
    $(CC) -c $< -o $@

#to create executable
bin: $(BINDIR) $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) -o  $(BINDIR)/$(APP)

#to clean executable and objects
clean:
    rm -rf $(OBJS) $(BINDIR) $(OBJDIR)

答案 2 :(得分:0)

更新了root make文件,在root /目录中使用

WORKDIR = $(shell pwd)
MODULES = feature1 feature2
CSOURCE =  main.c
CSOURCE +=  func1.c
SRCDIR = .
vpath %.c $(SRCDIR)/
CC = gcc
MKDIR_P = mkdir -p
OBJDIR = $(WORKDIR)/objdir
BINDIR = $(WORKDIR)/bindir
OBJS    = $(addprefix $(OBJDIR)/, $(CSOURCE:.c=.o))
APP = example

all: ${OBJDIR} modules $(OBJS) bin

modules:
    for mod in $(MODULES); do \
      echo "Building $$mod ....."; \
      $(MAKE) -C $(WORKDIR)/$$mod all; \
    done

${BINDIR}:
    ${MKDIR_P} ${BINDIR}

${OBJDIR}:
    ${MKDIR_P} ${OBJDIR}

$(OBJDIR)/%.o: %.c
    $(CC) -c $< -o $@

bin: $(BINDIR) $(OBJS)
    $(CC) $(CFLAGS) $(OBJDIR)/*.o -o  $(BINDIR)/$(APP)

clean:
    rm -rf $(OBJS) $(BINDIR) $(OBJDIR)

feature make file,在root / feature1目录和root / feature2目录中使用它

WORKDIR = $(shell cd ..; pwd)
CSOURCE =  func2.c
SRCDIR = .
vpath %.c $(SRCDIR)/
CC = gcc
MKDIR_P = mkdir -p
OBJDIR = $(WORKDIR)/objdir
OBJS    = $(addprefix $(OBJDIR)/, $(CSOURCE:.c=.o))

all: ${OBJDIR} $(OBJS) 

${OBJDIR}:
    ${MKDIR_P} ${OBJDIR}

$(OBJDIR)/%.o: %.c
    $(CC) -c $< -o $@

clean:
    rm -rf $(OBJS) $(OBJDIR)

如果要添加新目录说feature3,可以将其添加到主makefile模块列表中,并将feature1 makefile复制到feature3并更新源文件列表

希望这有帮助