Other [Make] Store all derived files in a sub-directory

I am learning BSD's make and would like to create a Makefile for cross-building a C-project, where all the derived files (generated assembler and object files) are stored in a dedicated sub-directory. The cross-toolchain I am using is devel/cc65 for the venerable C-64.

My project directory looks like this:
Code:
Makefile
change_border.s
hello.c
music.c
ld.cfg # Linker configuration file
As you can see, there are both assembler and C sources.

For putting all generated files into a dedicated sub-directory, the .PATH target came into my mind. Here is what I came up with so far for the Makefile:
Code:
# Name of the directory where to store all derived files.
OUTPUT = output

# All the suffixes that are relevant for this project.
.SUFFIXES: .s .c .o

# Search for .s files in the current and the $OUTPUT directory.
.PATH.s: ./ ./${OUTPUT}

# Search for object files in the $OUTPUT directory.
.PATH.o: ./${OUTPUT}

# Transformation rule how to compile C files into assembly files.
# The generated .s file is stored in the $OUTPUT directory.
.c.s:
	cl65 -C ld.cfg -S -o ${OUTPUT}/${.PREFIX}.s ${.IMPSRC} 

# Transformation rule how to turn assembly files in to object files.
# Note how the object files are stored in the $OUTPUT directory.
.s.o:
	ca65 -o ${OUTPUT}/${.PREFIX}.o ${.IMPSRC}

# All the objects needed for building the executable.
OBJS = hello.o music.o change_border.o

# The executable depends on the $OUTPUT directory and the objects.
hello.prg: ${OUTPUT} ${OBJS}
	ld65 -C ld.cfg --mapfile ${OUTPUT}/${.PREFIX}.map \
	    -o ${OUTPUT}/${.TARGET} ${.ALLSRC} c64.lib

# How to create the $OUTPUT directory.
${OUTPUT}:
	mkdir -p output

# Cleaning everything should mean just to remove the $OUTPUT
# directory.
clean:
	rm -rf ${OUTPUT}

When running make -r it gives the following output and error:
Code:
mkdir -p output
cl65 -C ld.cfg -S -o output/hello.s hello.c
ca65 -o output/hello.o hello.s
Fatal error: Cannot open input file 'hello.s': No such file or directory
*** Error code 1

Stop.
make: stopped in /usr/home/hsebert/Projects/IRQ_loader
Apparently, line 3 in the output should have been ca65 -o output/hello.o ./output/hello.s, but the .PATH directive seems to have no effect.

Any ideas?
 
You can add output/ to the line since you put all your .s in the same dir

Have a look at /usr/share/mk/*. You probably want to create SRCS and generate OBJS and ASMS from it.
From /usr/share/mk/bsd.prog.mk
Makefile:
OBJS+= ${SRCS:N*.h:${OBJS_SRCS_FILTER:ts:}:S/$/.o/g}

You can also use <bsd.prog.mk> directly and set OBJDIR
 
This should work but I'd still have a look on those .mk files. It is a bit complex at first glance but very instructive.

Makefile:
.OBJDIR: ${.CURDIR}/output
,PATH: ${.CURDIR}/output
 
Back
Top