I’ve never enjoyed gnu make. Most people I know don’t, but it’s a necessary evil. So I took some time out to finally get it into some shape. So, now I have a new SW structure. Here is my new directory structure:
And here are my makefiles and includes:
SW/Makefile:
1 SW_DIR = $( shell pwd | sed 's/\/cygdrive\/c\//C:\\\\/' | sed 's/\//\\\\/g' )
2 SW_DIR_CYG = $( shell pwd )
3 CFLAGS_Z80 = -mz80
4 CFLAGS_GENERIC = -c -DNDEBUG
5 AFLAGS = -o
6 LFLAGS = -mz80 --no-std-crt0 --nostdlib --code-loc 0x100 --data-loc 0x8000
7 INCLUDES = -I${ SW_DIR } /include -I${ SW_DIR } /app/include
8 INCLUDES_CYG = -I${ SW_DIR_CYG } /include -I${ SW_DIR_CYG } /app/include
9 TOOLDIR = /cygdrive/c/Program\ Files/SDCC/bin
10 LIBDIR = lib
11
12 MAKEARGS = "CFLAGS_Z80= ${ CFLAGS_Z80 } " "CFLAGS_GENERIC= ${ CFLAGS_GENERIC } " "INCLUDES= ${ INCLUDES } " "AFLAGS= ${ AFLAGS } " "TOOLDIR= ${ TOOLDIR } " "LIBDIR=../ ${ LIBDIR } " "BASEDIR=.." "LFLAGS= ${ LFLAGS } " "INCLUDES_CYG= ${ INCLUDES_CYG } "
13
14
15 # This makefile is the top level makefile that calls down to all the submakes
16 # It will get the current directory, basic flags, and then drill down
17 # includes are
18 #
19
20 #
21
22 .PHONY : all c bsp clean depends clean_bsp clean_app clean_c clean_lib
23
24 all :
25 cd app ; ${ MAKE } all ${ MAKEARGS } "DIRS=test" "PROG=mainRW"
26 # cd app ; ${MAKE} all ${MAKEARGS} "DIRS=menu" "PROG=menu"
27
28 c :
29 cd c_src ; ${ MAKE } all ${ MAKEARGS }
30
31 bsp :
32 cd bsp ; ${ MAKE } all ${ MAKEARGS } "DIRS=crt0 diag flash gpio interrupt membank spi tick uart" "LIB=bsp"
33 cd app ; ${ MAKE } all ${ MAKEARGS } "DIRS=idle intelHex ringBuffer timer" "LIB=bsp"
34
35 clean : clean_bsp clean_app clean_c clean_lib
36
37 clean_bsp :
38 cd bsp ; ${ MAKE } clean ${ MAKEARGS } "DIRS=crt0 diag flash gpio interrupt membank spi tick uart" "LIB=bsp"
39
40 clean_app :
41 cd app ; ${ MAKE } clean ${ MAKEARGS } "DIRS=idle intelHex ringBuffer test timer menu test" "LIB=bsp"
42
43 clean_c :
44 cd c_src; ${ MAKE } clean ${ MAKEARGS }
45
46 clean_lib :
47 cd lib ; rm -f *.lib; rm -f *.rel
48
49 depends :
50 cd app ; ${ MAKE } depends ${ MAKEARGS }
51
52 test :
53 cd bsp; pwd; make test ${ MAKEARGS }
SW/common.inc:
1 COMMON = INCUDED
2
3 MAKEARGS = "CFLAGS_Z80= ${ CFLAGS_Z80 } " "CFLAGS_GENERIC= ${ CFLAGS_GENERIC } " "INCLUDES= ${ INCLUDES } " "AFLAGS= ${ AFLAGS } " "TOOLDIR= ${ TOOLDIR } " "LIBDIR=../ ${ LIBDIR } " "BASEDIR=../ ${ BASEDIR } "
SW/subdirs.inc:
1 SUBDIRS = INCUDED
2
3 .PHONY : all clean
4
5 all :
6 echo ${ DIRS }
7 @for i in ${ DIRS } ; do \
8 cd $$ i; \
9 make all ${ MAKEARGS } ; \
10 cd ..; \
11 done
12
13 clean :
14 echo ${ DIRS }
15 @for i in ${ DIRS } ; do \
16 cd $$ i; \
17 make clean ${ MAKEARGS } ; \
18 cd ..; \
19 done
SW/generate.inc:
1 CC = ${ TOOLDIR } /sdcc.exe
2 AS = ${ TOOLDIR } /sdasz80.exe
3 AR = ${ TOOLDIR } /sdcclib.exe
4
5 C_SOURCES = $( wildcard *.c)
6 S_SOURCES = $( wildcard *.s)
7 REL_C = $( patsubst %.c,%.rel, ${ C_SOURCES } )
8 REL_S = $( patsubst %.s,%.rel ,${ S_SOURCES } )
9
10 all : ${REL_C } ${REL_S }
11
12 # - keeps it from crashing out if no *.d file
13 -include *.d
14
15 clean :
16 rm -f *.d
17 rm -f *.lib
18 rm -f *.rel
19 rm -f *.asm
20 rm -f *.lst
21 rm -f *.sym
22
23 %.rel : %.s
24 ${ AS } -g ${ AFLAGS } $<
25 ${ AR } r ${ LIBDIR } /${ LIB } .lib $@
26
27 %.rel : %.c
28 ${ CC } ${ CFLAGS_Z80 } ${ CFLAGS_GENERIC } ${ INCLUDES } $<
29 ${ AR } r ${ LIBDIR } /${ LIB } .lib $@
30
31 %.d : %.c
32 gcc ${ CFLAGS_GENERIC } ${ INCLUDES_CYG } -MM $< > $* .d
The Makefiles found in directories with no code:
1 include ${BASEDIR}/common.inc
2 include ${BASEDIR}/subdirs.inc
The Makefiles found in directories with code:
1 include ${BASEDIR}/common.inc
2 include ${BASEDIR}/generate.inc
SW/bsp/crt0 has a special makefile since crt0 isn’t archived but copied to SW/lib:
1 include ${BASEDIR}/common.inc
2
3 # This makefile is unique because the crt0 isn't archived. Rather it must be the first item in the list of rel/ar given to the linker
4 CC = ${ TOOLDIR } /sdcc.exe
5 AS = ${ TOOLDIR } /sdasz80.exe
6 AR = ${ TOOLDIR } /sdcclib.exe
7
8 C_SOURCES = $( wildcard *.c)
9 S_SOURCES = $( wildcard *.s)
10 REL_C = $( patsubst %.c,%.rel, ${ C_SOURCES } )
11 REL_S = $( patsubst %.s,%.rel ,${ S_SOURCES } )
12
13 all : ${REL_C } ${REL_S }
14
15 clean :
16 rm -f *.d
17 rm -f *.lib
18 rm -f *.rel
19 rm -f *.asm
20 rm -f *.lst
21 rm -f *.sym
22
23 %.rel : %.s
24 ${ AS } -g ${ AFLAGS } $<
25 # ${AR} rc ${LIBDIR}/${LIB} $@
26 cp crt0.rel ${ LIBDIR } /
27
28 %.rel : %.c
29 ${ CC } ${ CFLAGS_Z80 } ${ CFLAGS_GENERIC } ${ INCLUDES } $<
30 # ${AR} rc ${LIBDIR}/${LIB}.ar $@
And the common C directory also has a special Makefile:
1 include ${BASEDIR}/common.inc
2
3 CC = ${ TOOLDIR } /sdcc.exe
4 AS = ${ TOOLDIR } /sdasz80.exe
5 AR = ${ TOOLDIR } /sdcclib.exe
6
7
8 C_SOURCES = _calloc.c _divslong.c _divulong.c _free.c _heap.c _itoa.c _ltoa.c _malloc.c _memchr.c _memcmp.c _memcpy.c _memset.c _modslong.c _modulong.c _mullong.c _realloc.c _startup.c _strcat.c _strchr.c _strcmp.c _strcspn.c _strncat.c _strncmp.c _strncpy.c _strpbrk.c _strrchr.c _strspn.c _strstr.c _strtok.c assert.c atoi.c atol.c errno.c gets.c isalnum.c isalpha.c isblank.c iscntrl.c isdigit.c isgraph.c islower.c isprint.c ispunct.c isspace.c isupper.c isxdigit.c labs.c puts.c rand.c sprintf.c strxfrm.c time.c tolower.c toupper.c vprintf.c
9
10 # _divschar.c _modschar.c _mulschar.c _setjmp.c _strcpy.c abs.c _memmove.c _strlen.c _modsint.c _moduint.c _mulint.c _divsint.c _divuint.c
11
12 C_LONG_LONG_SOURCES = _divslonglong.c _divulonglong.c _modslonglong.c _modulonglong.c _mullonglong.c _rlslonglong.c _rlulonglong.c _rrslonglong.c _rrulonglong.c atoll.c
13
14 C_FLOAT_SOURCES = _atof.c _fs2schar.c _fs2sint.c _fs2slong.c _fs2uchar.c _fs2uint.c _fs2ulong.c _fsadd.c _fscmp.c _fsdiv.c _fseq.c _fsget1arg.c _fsget2args.c _fsgt.c _fslt.c _fsmul.c _fsneq.c _fsnormalize.c _fsreturnval.c _fsrshift.c _fssub.c _fsswapargs.c _logexpf.c _schar2fs.c _sint2fs.c _slong2fs.c _uchar2fs.c _uint2fs.c _ulong2fs.c acosf.c asincosf.c asinf.c atan2f.c atanf.c ceilf.c cosf.c coshf.c cotf.c expf.c fabsf.c floorf.c frexpf.c ldexpf.c log10f.c logf.c modff.c powf.c sincosf.c sincoshf.c sinf.c sinhf.c sqrtf.c tancotf.c tanf.c tanhf.c
15
16 REL_C_SOURCES = $( patsubst %.c,%.rel, ${ C_SOURCES } )
17 REL_C_LONG_LONG_SOURCES = $( patsubst %.c,%.rel, ${ C_LONG_LONG_SOURCES } )
18 REL_C_FLOAT_SOURCES = $( patsubst %.c,%.rel, ${ C_FLOAT_SOURCES } )
19 REL_S = $( patsubst %.s,%.rel ,${ S_SOURCES } )
20
21 .PHONY : all z 80
22
23 all : c_lib float_lib longlong_lib z 80
24
25 z80 :
26 cd z80; make all ${ MAKEARGS } "LIB=c"
27
28 c_lib : ${REL_C_SOURCES } ${REL_S }
29 ${ AR } r ${ LIBDIR } /c.lib ${ REL_C_SOURCES } ${ REL_S }
30
31 float_lib : ${REL_C_FLOAT_SOURCES }
32 ${ AR } r ${ LIBDIR } /float.lib ${ REL_C_FLOAT_SOURCES }
33
34 longlong_lib : ${REL_C_LONG_LONG_SOURCES }
35 ${ AR } r ${ LIBDIR } /longlong.lib ${ REL_C_LONG_LONG_SOURCES }
36
37 %.rel : %.s
38 ${ AS } -g ${ AFLAGS } $<
39
40 %.rel : %.c
41 ${ CC } ${ CFLAGS_Z80 } ${ CFLAGS_GENERIC } ${ INCLUDES } $<
42
43 clean :
44 rm -f *.d
45 rm -f *.lib
46 rm -f *.rel
47 rm -f *.asm
48 rm -f *.lst
49 rm -f *.sym
50 cd z80; make clean ${ MAKEARGS }
And this is how I make a clean build of the program I’m working with:
$> make clean
$> make all
It’s not perfect. It’s probably not even good. But it’s better than the
ad hoc Makefiles I had before because it’s more scalable and extensible.