LoginSignup
3
2

More than 5 years have passed since last update.

なんでもmake xxxで済ませたい

Last updated at Posted at 2017-08-06

シンプルなC言語のプロジェクトを作ってみる
目的は、とりあえず、何をするにもmake xxxで済ませたい。

http://qiita.com/tksmiura/items/0a77e5c301532ae30c9a
の続き

http://qiita.com/szkny/items/07b4c93702b3f8090fa3
あたりを参考にして

ut_*.c という名前のソースをテストプログラムとしてビルドして実行する。(make のwildcardを利用するのでファイルを増やしてもMakefileの変更は不要)

make testとかmake gcovとか実行するビルドして、テストやカバレッジを取ってくれる。

% make test
cc -o ut_main ut_main.c
cc -o ut_sub ut_sub.c
result ut_main.c 3/3 
result ut_sub.c 0/0

make debugと実行するとデバッグビルドしてgdbの起動まで行う。

http://www.ne.jp/asahi/hishidama/home/tech/unix/cmd/make2.html
あたりを参照

プロジェクト全体は、
https://gist.github.com/tksmiura/fc273ba726ed380dcd5bf6488c24c553

にあげておきます。

#TARGETS
PROGRAM = main
DEBUG_TARGET = main_debug
HEADERS = $(wildcard *.h)
SRCS = main.c
TEST_SRCS = $(wildcard ut_*.c)
TESTS = $(basename $(TEST_SRCS)) 
GCOV_TESTS = $(TEST_SRCS:.c=_gcov)

# ENVIRONMENT
CC ?= gcc
CFLAGS ?= -Wall -O2
DEBUG_OPTION ?= -O0 -g
DEBUGGER = gdb -tui
GCOV = gcov

# suffixes
.SUFFIXES: .c .o .debug_o

#default target
all: $(PROGRAM)

#
# target
#

# サフィックスルール
.c.o:
    $(CC) $(CFLAGS) -c $<

#依存関係
define MAKEOBJECTS
$(1:.c=.o): $(1) $(HEADERS)
endef
$(foreach VAR,$(SRCS),$(eval $(call MAKEOBJECTS,$(VAR))))

$(PROGRAM): $(SRCS:.c=.o)
    $(CC) -o $(PROGRAM) $^

#
# debug(gdb)
#
.c.debug_o:
    $(CC) $(CFLAGS) $(DEBUG_OPTION) -o $@ -c $<

#依存関係
define MAKEDEBUG
$(1:.c=.debug_o): $(1) $(HEADERS)
endef
$(foreach VAR,$(SRCS),$(eval $(call MAKEDEBUG,$(VAR))))


$(DEBUG_TARGET): $(SRCS:.c=.debug_o)
    $(CC) -o $@ $^

.PHONY: debug
debug: $(DEBUG_TARGET)
    $(DEBUGGER) $^

#
# unit test 
#

# targets for test
define MAKETARGETS
$(1): $(1).c $(HEADERS)
    $(CC) -o $(1) $(1).c
endef
$(foreach VAR,$(TESTS),$(eval $(call MAKETARGETS,$(VAR))))

.PHONY: test
test: $(TESTS)
    @for test in $(TESTS) ; do \
        ./$$test ;\
    done

#
# gcov
#

# target gov (unit test only) 
define MAKETARGETS_GCOV
$(1)_gcov: $(1).c
    $(CC) -o $(1)_gcov --coverage $(1).c
endef
$(foreach VAR,$(TESTS),$(eval $(call MAKETARGETS_GCOV,$(VAR))))

.PHONY: gcov
gcov: $(GCOV_TESTS)
    @for test in $(GCOV_TESTS) ; do \
        ./$$test ;\
    done
    $(GCOV) -b $(TEST_SRCS:.c=.gcda)

#
# clean
#
.PHONY: clean
clean:
    $(RM) $(PROGRAM) $(DEBUG_TARGET) $(TESTS) $(GCOV_TESTS)
    $(RM) $(SRCS:.c=.o) $(SRCS:.c=.debug_o) 
    $(RM) *.gcda *.gcno *.gcov 

全体的に手抜きなので、ヘッダはwildcardで*.hを検索し、

HEADERS = $(wildcard *.h)

どれかが変更されれば、リビルドされるように設定。
(defineでルールを定義してforeachで展開)

#依存関係
define MAKEOBJECTS
$(1:.c=.o): $(1) $(HEADERS)
endef
$(foreach VAR,$(SRCS),$(eval $(call MAKEOBJECTS,(VAR))))

実際、#includeしてない場合も考えられますが、いちいち依存関係を記述する手間を省くため。こうしています。

デバッグ用のオブジェクトを*.debug_oとしているは自分でもどうかと思っていますが、フォルダ分けとかも面倒な感じなのでこうしています。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2