将Makefile与子文件夹一起使用 [英] Using Makefile with subfolders

查看:409
本文介绍了将Makefile与子文件夹一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下目录结构.

Project/
    ├── bin/
    ├── src/
    │    ├── main.c
    │    ├── util/
    │         ├── util.c
    │         ├── util.h
    ├── obj/
    ├── .depend/

我所有的源代码都在src文件夹中.在src根目录中是我的main.c文件;其中包括与他位于同一级别(或位于同一级别文件夹中)的其他文件.我下面有一个Makefile,该文件对main.c相同级别中的所有文件都适用,但是对src内子文件夹中的文件不起作用

All my source code are in the src folder. In the src root is my main.c file; which includes other files that are on the same level that he (or within a same level folder). I have a Makefile below that works well for all files in the same level of main.c but does not work on files in a subfolder within src

如何更改我的Makefile以允许src文件夹中的子文件夹?

CC := gcc
CFLAGS := -Wall -Wextra
BINDIR := bin
OBJDIR := obj
SRCDIR := src
DEPDIR := .depend
SOURCES := $(wildcard $(SRCDIR)/*.c)
OBJECTS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SOURCES))
DEPENDS := $(patsubst $(SRCDIR)/%.c, $(DEPDIR)/%.d, $(SOURCES))

$(BINDIR)/app: $(OBJECTS) | $(BINDIR)
    @$(CC) -o $@ $^

-include $(DEPENDS)

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

$(DEPDIR)/%.d: $(SRCDIR)/%.c | $(DEPDIR)
    @$(CC) -MM -MG $< | sed 's!^\(.\+\).o:!$(DEPDIR)/\1.d $(OBJDIR)/\1.o:!' > $@

$(DEPDIR) $(BINDIR) $(OBJDIR):
    @mkdir $@

clean:
    @rm -rf $(BINDIR)/*
    @rm -rf $(OBJDIR)/*

.PHONY: clean

编辑:.o.d文件不需要遵守结构的原始设计.我正在使用Windows(MinGW)

EDIT: the .o and .d files do not need to respect the original design of the structure. And I'm using Windows (MinGW)

推荐答案

首先,您必须更改SOURCES才能递归地找到源.这可以通过纯粹的方式完成:

First, you'll have to change your SOURCES to recursively find the sources. This can be done in pure make:

subdirs = $(filter-out $1,$(sort $(dir $(wildcard $1*/))))
rfind = $(wildcard $1$2) $(foreach d,$(call subdirs,$1),$(call rfind,$d,$2))

SOURCES := $(call rfind,$(SRCDIR)/,*.c)

除目录创建外,其他所有操作均有效.首先,更改将$(@D)用于辅助扩展的先决条件:

Everything else will work, except for directory creation. First, change your prerequisites to use $(@D) with secondary expansion:

.SECONDEXPANSION:

$(OBJDIR)/%.o: $(SRCDIR)/%.c | $$(@D)
    ...
$(DEPDIR)/%.d: $(SRCDIR)/%.c | $$(@D)
    ...

然后,更改目录创建规则以包括所有目录:

Then, change your directory creation rule to include all the directories:

$(BINDIR) $(patsubst %/,%,$(sort $(dir $(OBJECTS) $(DEPENDS)))):
    @mkdir -p $@

与递归查找一样,它使用sort对目录进行重复数据删除(否则make会发出警告)并去除结尾的斜杠(因为$(@D)没有结尾的斜杠).请注意,需要-p来避免顺序问题以及目录仅包含其他目录而没有源的目录.

Like the recursive find, it uses sort to deduplicate the directories (otherwise make will warn) and strips the trailing slash (because $(@D) won't have a trailing slash). Note that -p is needed to avoid issues with order and with directories only containing other directories and no sources.

这篇关于将Makefile与子文件夹一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆