GNU makefile でCのソースの依存関係を自動生成する方法

2022/07/11に公開

前回の記事で書いたMakefile に漏れがありました。
https://zenn.dev/tetsu_koba/articles/ec38bff54814f0

それはCのソースコードのヘッダの依存関係を書いていないので、ヘッダファイルを修正してもコンパイルされないのです。
ヘッダファイルの依存関係を手で入力するのも面倒なので、自動生成するようにMakefileを修正しました。
使っているmakeコマンドはこちら。

$ make --version
GNU Make 4.2.1
Built for aarch64-unknown-linux-gnu
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Makefileの修正

CPPFLAGS に -MMDを指定。こうすると依存関係が .d ファイルに書き出されます。
.d ファイルをまとめた DEPFILES を定義。
Makefileの最後に-include $(DEPFILES)を追加。
この行頭の- は$(DEPFILES)が空でインクルードするファイルが無いときでもエラーにしないという指示です。

@@ -1,17 +1,20 @@
 TARGET = libgstmyfakesink.so
 OBJS = gstmyfakesink.o
+DEPFILES = $(OBJS:%.o=%.d)
 
 CC = gcc
 PACKAGES = gstreamer-1.0 gstreamer-base-1.0
 CFLAGS = -Wall -fPIC $(shell pkg-config --cflags $(PACKAGES))
+CPPFLAGS = -MMD
 LDLIBS = $(shell pkg-config --libs $(PACKAGES))
 
 $(TARGET): $(OBJS)
        $(CC) -shared -o $@ $< $(LDLIBS)
 
 clean:
-       rm -f $(TARGET) $(OBJS)
+       rm -f $(TARGET) $(OBJS) $(DEPFILES)
 
 install: $(TARGET)
        cp $(TARGET) ${HOME}/.local/share/gstreamer-1.0/plugins/
 
+-include $(DEPFILES)
Makefile
TARGET = libgstmyfakesink.so
OBJS = gstmyfakesink.o
DEPFILES = $(OBJS:%.o=%.d)

CC = gcc
PACKAGES = gstreamer-1.0 gstreamer-base-1.0
CFLAGS = -Wall -fPIC $(shell pkg-config --cflags $(PACKAGES))
CPPFLAGS = -MMD
LDLIBS = $(shell pkg-config --libs $(PACKAGES))

$(TARGET): $(OBJS)
	$(CC) -shared -o $@ $< $(LDLIBS)

clean:
	rm -f $(TARGET) $(OBJS) $(DEPFILES)

install: $(TARGET)
	cp $(TARGET) ${HOME}/.local/share/gstreamer-1.0/plugins/

-include $(DEPFILES)

CC=gccCC=clang に変えても-MMDオプションは効きました。

Discussion