我正试图为一个大型项目制作一个Makefile。
项目结构是(我已经省略了头文件)
root/feature1/feat1.c
root/feature2/feat2.c
root/srcfile1.c
root/srcfile2.c我想简单地开始,所以我用根dir中的源文件创建了一个更简单的项目。
我需要在一个目录中创建所有的对象文件,比如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运行它(与在同一个dir中更改文件名时,有Netbeans的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命令时,它试图生成directories和program。创建了dir objdir,其中有main.o和word.o文件。
简单项目的makefile有什么问题吗?
编辑:
在-c规则中添加了$(OBJDIR)/%.o标志。
将$(FLAGS)从$(CC) -o $@ $^ $(FLAGS) $(LIBS)中删除。
现在,如果我们转到我的项目问题上,我需要访问所有目录中的所有源文件:
/repo-root/repo-root/feature1/feat1.c/repo-root/feature2/feat2.c发布于 2014-03-25 15:07:20
在这一规则中:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
    $(CC) -o $@ $<你错过了-c标志。Make不是构建一个对象文件,而是尝试构建一个名为objdir/main.o的可执行文件,而main.c没有所有所需的代码。就这么做吧:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
    $(CC) -c -o $@ $<发布于 2014-03-25 15:45:58
尝尝这个
#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)发布于 2014-03-25 18:19:21
更新后的根文件,在根目录/目录中使用
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,将其用于root/ file 1目录和root/file 2目录中。
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并更新源文件列表即可。
希望这能有所帮助
https://stackoverflow.com/questions/22635417
复制相似问题