如何使Makefile更好/更容易/更少冗余?

时间:2010-02-06 21:20:15

标签: makefile

我想了解以下Makefile的一些建议。它工作正常,但它过于冗余,并没有利用任何大多数魔法制作可以帮助C项目。

其目的是测试一个小的ANSI C库。便携性很重要。

.PHONY : test

OPTIMIZE = -g
INCLUDE  = -I.
CC       = gcc
WARNINGS = -Wall -ansi -pedantic -Wno-long-long -Wextra -Wdeclaration-after-statement -Wendif-labels -Wconversion
CFLAGS   = $(WARNINGS) $(OPTIMIZE) $(INCLUDE)
COMPILE  = $(CC) $(CFLAGS)
LINK     = $(COMPILE)

all : time64.o bin/check_max

bin/check_max : time64.o time64_config.h bin/check_max.c
    $(LINK) time64.o bin/check_max.c -o $@

time64.o : time64_config.h time64.h time64.c Makefile

t/bench : t/bench.c time64.o
    $(LINK) time64.o t/bench.c -o $@

bench : t/bench
    time t/bench

t/localtime_test : t/localtime_test.c time64.o
    $(LINK) time64.o t/localtime_test.c -o $@

t/gmtime_test : t/gmtime_test.c time64.o
    $(LINK) time64.o t/gmtime_test.c -o $@

t/year_limit.t : t/tap.c t/year_limit.t.c time64.o
    $(LINK) time64.o t/year_limit.t.c -o $@

t/negative.t : t/tap.c t/negative.t.c time64.o
    $(LINK) time64.o t/negative.t.c -o $@

t/overflow.t : t/tap.c t/overflow.t.c time64.o
    $(LINK) time64.o t/overflow.t.c -o $@

t/timegm.t : t/tap.c t/timegm.t.c time64.o
    $(LINK) time64.o t/timegm.t.c -o $@

t/safe_year.t : t/tap.c t/safe_year.t.c time64.c
    $(LINK) t/safe_year.t.c -o $@

t/gmtime64.t : t/tap.c t/gmtime64.t.c time64.o
    $(LINK) time64.o t/gmtime64.t.c -o $@

t/mktime64.t : t/tap.c t/mktime64.t.c time64.o
    $(LINK) time64.o t/mktime64.t.c -o $@

t/asctime64.t : t/tap.c t/asctime64.t.c time64.o
    $(LINK) time64.o t/asctime64.t.c -o $@

t/ctime64.t : t/tap.c t/ctime64.t.c time64.o
    $(LINK) time64.o t/ctime64.t.c -o $@

t/seconds_between_years.t : t/tap.c t/seconds_between_years.t.c time64.c
    $(LINK) t/seconds_between_years.t.c -o $@

test : tap_tests localtime_tests

localtime_tests: t/localtime_test t/gmtime_test
    @which bzdiff > /dev/null || (echo 'You need bzdiff to run these tests'; exit 1)
    @which less   > /dev/null || (echo 'You need less to run these tests';   exit 1)
    @echo "On failure, these tests will produce a diff between the failed and expected results.  If they pass they'll be quiet."
    TZ=Canada/Eastern t/gmtime_test | bzip2 -9 > t/gmtime_test.out.bz2
    bzdiff -u t/gmtime_test.out.bz2 t/gmtime.out.bz2 | less -F
    TZ=Canada/Eastern t/localtime_test | bzip2 -9 > t/eastern_test.out.bz2
    bzdiff -u t/eastern_test.out.bz2 t/eastern.out.bz2 | less -F
    TZ=Australia/West t/localtime_test | bzip2 -9 > t/oz_test.out.bz2
    bzdiff -u t/oz_test.out.bz2 t/oztime.out.bz2 | less -F

tap_tests: t/year_limit.t t/negative.t t/overflow.t t/timegm.t t/safe_year.t t/gmtime64.t t/asctime64.t t/ctime64.t
    @which prove > /dev/null || (echo 'You need prove (from the Test::Harness perl module) to run these tests'; exit 1)
    @prove --exec '' t/*.t

clean:
    -rm     t/*.t           \
        t/localtime_test    \
        t/gmtime_test       \
        t/*_test.out.bz2    \
        t/bench         \
        *.o

You can see it in situ here

1 个答案:

答案 0 :(得分:3)

使用隐式规则,不要重新声明make可以自动查找的内容。还简化了顶部的变量,但这更偏好(几个只是重置默认值)。这可能稍微不那么便携,但不是很明显,恕我直言。它在某些方面也更便携,例如在'gcc'不是默认编译器的系统上。

将localtime_tests和tap_tests转换为shell脚本(但不改变它们的作用),将该逻辑移到别处,这是使makefile每天都可读的主要内容。

CFLAGS = -g -Wall -ansi -pedantic -Wno-long-long -Wextra \
-Wdeclaration-after-statement -Wendif-labels -Wconversion

all : bin/check_max

bin/check_max : time64.o time64_config.h 
time64.o : time64_config.h time64.h Makefile

bench : t/bench
    time t/bench

t/bench : t/bench.c time64.o
t/localtime_test : time64.o
t/gmtime_test : time64.o

t/year_limit.t: t/tap.c time64.o
t/negative.t  : t/tap.c time64.o
t/overflow.t  : t/tap.c time64.o
t/timegm.t    : t/tap.c time64.o
t/safe_year.t : t/tap.c time64.c
t/gmtime64.t  : t/tap.c time64.o
t/mktime64.t  : t/tap.c time64.o
t/asctime64.t : t/tap.c time64.o
t/ctime64.t   : t/tap.c time64.o
t/seconds_between_years.t: t/tap.c time64.c

test : tap_tests localtime_tests
tap_tests: t/year_limit.t t/negative.t t/overflow.t t/timegm.t t/safe_year.t \
t/gmtime64.t t/asctime64.t t/ctime64.t
    ./tap_tests
localtime_tests: t/localtime_test t/gmtime_test
    ./localtime_tests
.PHONY : test tap_tests localtime_tests

clean:
    -rm t/*.t t/localtime_test t/gmtime_test t/*_test.out.bz2 t/bench
    -rm *.o
.PHONY : clean

如果可移植性丢失可以接受,您可以使用GNUmake特定功能simplify甚至more