This is a long standing issue. If "make" is issued from a leaf directory, e.g. kernel/mem then the files are built using a reasonable command line:
$ sdcc --oldralloc -mz80 --fverbose-asm -I../../include -DMEM_ACCOUNTING -c -o mem_seg.rel mem_seg.c
However, if "make" is issued from the top level directory, Makefile includes Makefile.tools (which initially sets CFLAGS.z80), then we recurse into kernel/Makefile which also includes them, then again into kernel/mem/Makefile which also includes it, resulting in:
$ sdcc --oldralloc -mz80 --fverbose-asm -I./include -mz80 --fverbose-asm -I../include -mz80 --fverbose-asm -I../../include -DMEM_ACCOUNTING -c -o mem_seg.rel mem_seg.c
--fverbose-asm and -mz80 are repeated, and the -I flag contains 2 non-existant directories and 1 real one (-I../../include).
Whilst this isn't a problem, it's messy, and if there were ever any intermediate-level include directories, this might break quite easily.
I think what is needed is the separation of the variables (such as BASEDIR and any additional CFLAGS) from the "execution" makefiles which contain targets.
For example, if there is a top-level Makefile which only knows how to build targets, descending into directories as required, each subsequent level contains similar Makefiles which only know how to build targets. Then, each leaf Makefile can include the relevant previous Makefile.kernel or Makefile.master as required.
This would avoid the repeated inclusion of the same top-level Makefile.common or Makefile.kernel along the way, and should avoid the repeated options as each Makefile accumulates more...