Makefile中的自动依赖处理(Automatic dependency processing in Makefile)

系统教程 行业动态 更新时间:2024-06-14 16:57:40
Makefile中的自动依赖处理(Automatic dependency processing in Makefile)

我有一个简单的makefile。

IDIR =./include CC=gcc CFLAGS=-I$(IDIR) SRCDIR = ./src ODIR=obj LDIR =./lib LIBS=-lm SRC = hellomake hellofunc OBJ = ${SRC:%=$(ODIR)/%.o} _DEPS = hellomake.h DEPS = ${_DEPS:%=$(IDIR)/%} $(ODIR)/%.o: $(SRCDIR)/%.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) hellomake: $(OBJ) gcc -o $@ $^ $(CFLAGS) $(LIBS) .PHONY: clean clean: rm -f $(ODIR)/*.o *~ hellomake

我不喜欢这个Makefile是依赖生成。

.CO

有没有可能教make文件,.c在src目录中,而.o在obj目录下来制作这个简单的目录?

.c.o: $(CC) -c -o $@ $< $(CFLAGS)

标头依赖

是否可以教make文件,当c文件包含的头文件发生变化时,所有c文件都会被自动重新编译?

I have a simple makefile.

IDIR =./include CC=gcc CFLAGS=-I$(IDIR) SRCDIR = ./src ODIR=obj LDIR =./lib LIBS=-lm SRC = hellomake hellofunc OBJ = ${SRC:%=$(ODIR)/%.o} _DEPS = hellomake.h DEPS = ${_DEPS:%=$(IDIR)/%} $(ODIR)/%.o: $(SRCDIR)/%.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) hellomake: $(OBJ) gcc -o $@ $^ $(CFLAGS) $(LIBS) .PHONY: clean clean: rm -f $(ODIR)/*.o *~ hellomake

What I don't like about this Makefile is that the dependency generation.

.c.o

Is it possible to teach make file that the .c is in src directory, and .o is in obj directory to make this simple one?

.c.o: $(CC) -c -o $@ $< $(CFLAGS)

header dependency

Is it possible to teach make file that all the c files are recompiled automatically when header files that the c file contains is changed?

最满意答案

预赛

生成依赖项

gcc的-MM -MG可用于创建依赖项: gcc -MM -MG src/hellofunc.c -I./include将创建hellofunc.o: src/hellofunc.c include/hellomake.h 。 但是,我们需要将.d文件本身包含到.d文件中,因此我们使用sed来实现该目标。

gcc -MM -MG src/hellofunc.c -I./include | sed -e 's@^\(.*\)\.o:@\1.d \1.o:@'

结果如下:

hellofunc.d hellofunc.o: src/hellofunc.c include/hellomake.h

当我们想要更改内容以包含不同的目录位置时,我们可以修改sed脚本。

gcc -MM -MG src/hellofunc.c -I./include | sed -e 's@^\(.*\)\.o:@obj/\1.d obj/\1.o:@'

结果如下:

obj/hellofunc.d obj/hellofunc.o: src/hellofunc.c include/hellomake.h

包括

-include $(DEPS)将包含DEPS目录中的文件, - include的前面教导make在目录不退出时忽略。

模式匹配和替换

我们可以用c(%.c)替换任何以c(%.c)结尾的模式(%)或模式,如下所示:

OBJDIRS := $(patsubst %, $(OBJDIR)/%, $(MODULES)) OBJS := $(patsubst %.c, $(OBJDIR)/%.o, $(SRCS))

我们也可以有速记形式。

DEPS := $(OBJS:.o=.d)

过滤

我们只能选择一些带过滤器的文件,这是一个例子:

OBJ := $(patsubst %.c, %.o, $(filter %.c, $(SRC)))

方法1

在此方法中,我们指定依赖项(.d依赖于.c),并使用include包含创建的依赖项文件。

.PHONY: clean depend CC := gcc CXX := g++ LD := g++ CP := cp PROG := hellomake MODULES := src OBJDIR := obj default: $(PROG) OPTFLAGS := -g -O CFLAGS += -Wall -Wno-unused-function $(OPTFLAGS) $(patsubst %, -I%, $(MODULES)) GARBAGE := core core.* *.stackdump ./tags $(PROG) include $(patsubst %, %/module.make, $(MODULES)) OBJ := \ $(patsubst %.c, %.o, $(filter %.c, $(SRC))) DEP := $(OBJ:.o=.d) # implicit rules %.d: %.c ./depends.sh $(CC) `dirname $*.c` $(CFLAGS) $*.c > $@ -include $(DEP) # Actual targets depend: $(DEP) clean: rm -rf $(PROG) $(OBJ) $(GARBAGE) $(DEP) depends $(PROG): $(OBJ) $(LD) -o $@ $^ $(LIBS)

每个模块都应包含make文件(module.make),以指定SRC变量中包含的文件。

`SRC += src/hellofunc.c \ src/hellomake.c`.

这是生成依赖项文件的脚本:

#!/bin/sh #echo "## Got: $*" CC="$1" DIR="$2" shift 2 case "$DIR" in "" | ".") $CC -MM -MG "$@" | sed -e 's@^\(.*\)\.o:@\1.d \1.o:@' ;; *) $CC -MM -MG "$@" | sed -e "s@^\(.*\)\.o:@$DIR/\1.d $DIR/\1.o:@" ;; esac

此方法很简单,但是使用这些语句在相同的src目录中创建目标文件和依赖项文件。

SRC += src/hellofunc.c src/hellomake.c OBJ := $(patsubst %.c, %.o, $(filter %.c, $(SRC))) DEP := $(OBJ:.o=.d)

方法2

此方法创建对象目录,并将所有生成的(中间)文件放入目录中。

它列出了所有模块,以指定对象文件和依赖文件生成的操作。

在示例中,我们只有一个模块,但是有多个模块,我们需要复制语句。

obj/src/%.o: src/%.c $(CC) -c $< -o $@ $(CFLAGS) obj/src/%.d: src/%.c gcc -MM -MG $< $(CFLAGS) | sed -e 's@^\(.*\)\.o:@obj/src/\1.d obj/src/\1.o:@' > $@

这是makefile:

.SUFFIX = .o .c .PHONY: clean CC := gcc LD := gcc PROG := hellomake OBJDIR = obj MODULES := src SRCS := src/hellofunc.c src/hellomake.c OBJDIRS := $(patsubst %, $(OBJDIR)/%, $(MODULES)) OBJS := $(patsubst %.c, $(OBJDIR)/%.o, $(SRCS)) DEPS := $(OBJS:.o=.d) default: $(PROG) CFLAGS += -Wall -Wno-unused-function $(OPTFLAGS) $(patsubst %, -I%, $(MODULES)) CXXFLAGS += $(CFLAGS) obj/src/%.o: src/%.c $(CC) -c $< -o $@ $(CFLAGS) $(PROG): $(OBJDIRS) $(OBJS) $(LD) $(filter %.o, $^) -o $(PROG) -include $(DEPS) obj/src/%.d: src/%.c gcc -MM -MG $< $(CFLAGS) | sed -e 's@^\(.*\)\.o:@obj/src/\1.d obj/src/\1.o:@' > $@ depend: $(DEPS) GARBAGE := core core.* *.stackdump ./tags $(PROG) clean: rm -rf $(PROG) obj/* $(OBJDIRS): mkdir -p $@

参考

在gcc中生成目标文件时创建目录 如何将目标文件放在单独的子目录中 删除依赖文件 http://scottmcpeak.com/autodepend/autodepend.html

Preliminaries

Generating dependencies

gcc's -MM -MG can be used to create the dependencies: gcc -MM -MG src/hellofunc.c -I./include will create hellofunc.o: src/hellofunc.c include/hellomake.h. However, we need to include the .d file itself into the .d file, so we use sed to achieve that goal.

gcc -MM -MG src/hellofunc.c -I./include | sed -e 's@^\(.*\)\.o:@\1.d \1.o:@'

The results will be as follows:

hellofunc.d hellofunc.o: src/hellofunc.c include/hellomake.h

When we want to change the content to include the different directory location, we can modify the sed script.

gcc -MM -MG src/hellofunc.c -I./include | sed -e 's@^\(.*\)\.o:@obj/\1.d obj/\1.o:@'

The results will be as follows:

obj/hellofunc.d obj/hellofunc.o: src/hellofunc.c include/hellomake.h

include

-include $(DEPS) will include the files in DEPS directory, the - in front of the include teaches the make to ignore when the directories does not exits.

Pattern matching and replacement

We can substitute any pattern (%) or pattern that ends with c (%.c) as follows:

OBJDIRS := $(patsubst %, $(OBJDIR)/%, $(MODULES)) OBJS := $(patsubst %.c, $(OBJDIR)/%.o, $(SRCS))

We also can have shorthand form.

DEPS := $(OBJS:.o=.d)

filter

We can select only some of the files with filter, this is an example:

OBJ := $(patsubst %.c, %.o, $(filter %.c, $(SRC)))

Method 1

In this method, we specify the dependency (.d depends on .c), and include the created dependency file with include.

.PHONY: clean depend CC := gcc CXX := g++ LD := g++ CP := cp PROG := hellomake MODULES := src OBJDIR := obj default: $(PROG) OPTFLAGS := -g -O CFLAGS += -Wall -Wno-unused-function $(OPTFLAGS) $(patsubst %, -I%, $(MODULES)) GARBAGE := core core.* *.stackdump ./tags $(PROG) include $(patsubst %, %/module.make, $(MODULES)) OBJ := \ $(patsubst %.c, %.o, $(filter %.c, $(SRC))) DEP := $(OBJ:.o=.d) # implicit rules %.d: %.c ./depends.sh $(CC) `dirname $*.c` $(CFLAGS) $*.c > $@ -include $(DEP) # Actual targets depend: $(DEP) clean: rm -rf $(PROG) $(OBJ) $(GARBAGE) $(DEP) depends $(PROG): $(OBJ) $(LD) -o $@ $^ $(LIBS)

Each module should contain the make file (module.make) to specify what files are included in the SRC variable.

`SRC += src/hellofunc.c \ src/hellomake.c`.

This is the script to generate the dependency file:

#!/bin/sh #echo "## Got: $*" CC="$1" DIR="$2" shift 2 case "$DIR" in "" | ".") $CC -MM -MG "$@" | sed -e 's@^\(.*\)\.o:@\1.d \1.o:@' ;; *) $CC -MM -MG "$@" | sed -e "s@^\(.*\)\.o:@$DIR/\1.d $DIR/\1.o:@" ;; esac

This method is simple, but the object files and dependency files are created in the same src directory with these statements.

SRC += src/hellofunc.c src/hellomake.c OBJ := $(patsubst %.c, %.o, $(filter %.c, $(SRC))) DEP := $(OBJ:.o=.d)

Method 2

This method creates the object directory, and puts all the generated (intermediate) files into the directory.

It enlists all the modules to specify the actions both for object file and dependency file generation.

In the example, we have only one module, but with multiple modules, we need to duplicate the statements.

obj/src/%.o: src/%.c $(CC) -c $< -o $@ $(CFLAGS) obj/src/%.d: src/%.c gcc -MM -MG $< $(CFLAGS) | sed -e 's@^\(.*\)\.o:@obj/src/\1.d obj/src/\1.o:@' > $@

This is the makefile:

.SUFFIX = .o .c .PHONY: clean CC := gcc LD := gcc PROG := hellomake OBJDIR = obj MODULES := src SRCS := src/hellofunc.c src/hellomake.c OBJDIRS := $(patsubst %, $(OBJDIR)/%, $(MODULES)) OBJS := $(patsubst %.c, $(OBJDIR)/%.o, $(SRCS)) DEPS := $(OBJS:.o=.d) default: $(PROG) CFLAGS += -Wall -Wno-unused-function $(OPTFLAGS) $(patsubst %, -I%, $(MODULES)) CXXFLAGS += $(CFLAGS) obj/src/%.o: src/%.c $(CC) -c $< -o $@ $(CFLAGS) $(PROG): $(OBJDIRS) $(OBJS) $(LD) $(filter %.o, $^) -o $(PROG) -include $(DEPS) obj/src/%.d: src/%.c gcc -MM -MG $< $(CFLAGS) | sed -e 's@^\(.*\)\.o:@obj/src/\1.d obj/src/\1.o:@' > $@ depend: $(DEPS) GARBAGE := core core.* *.stackdump ./tags $(PROG) clean: rm -rf $(PROG) obj/* $(OBJDIRS): mkdir -p $@

References

Create directories when generating object files in gcc How to place object files in separate subdirectory make deleting dependency files http://scottmcpeak.com/autodepend/autodepend.html

更多推荐

本文发布于:2023-04-13 12:26:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/dzcp/983f2932bc9b7e614058a9f4ddee449f.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Automatic   Makefile   processing   dependency

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!