我正在尝试为一个大项目制作一个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 directories
和program
。
dir objdir
已创建,其中包含main.o
和word.o
个文件。
我对simpleproject的makefile做错了什么?
修改
在-c
规则中添加了$(OBJDIR)/%.o
标记
从$ $(FLAGS)
中删除了(CC) -o $@ $^ $(FLAGS) $(LIBS)
现在,如果我们转向我的项目问题,我需要访问所有目录中的所有源文件:
/repo-root
/repo-root/feature1/feat1.c
/repo-root/feature2/feat2.c
答案 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并更新源文件列表
希望这有帮助