<!doctype linuxdoc system>

<article>

<title>Using GNU Make with cc65
<author><url url="mailto:ol.sc@web.de" name="Oliver Schmidt">
<date>2014-04-12

<abstract>
How to build your program using the GNU Make utility.
</abstract>

<!-- Table of contents -->
<toc>

<!-- Begin the document -->

<sect>Overview<p>

This document describes how to build your programs using the cc65 development
tools and the GNU Make utility.

The cc65 development package doesn't come with a make utility. However this is
no issue because GNU Make works very nicely with cc65.



<sect>What is GNU Make?<p>

GNU Make is a both very powerful and very popular make utility. It might even
be called the de facto standard for make utilities. For more information see
the GNU Make home page:

<url url="http://www.gnu.org/software/make/">

The cc65 development package is available as binaries for several host systems
and can easily built for quite some additional systems. The very same is true
for GNU Make so a cc65-based project coming with a GNU Make Makefile can easily
be built by any cc65 developer no matter what host system is used.

Because of the strong alignment of the cc65 compiler with the ISO C standard it
is very well feasible to compile a single C code base both with the cc65
compiler and other C compilers like for example GCC. GNU Make turns out to be
very well suited to build projects for several target systems using multiple
compilers as it isn't tied to any C compiler.



<sect>A sample Makefile<p>

This Makefile is a fully functional sample for compiling several C sources
(here <tt/foo.c/ and <tt/bar.c/) and link the resulting object files into an
executable program (here <tt/foobar/):

<tscreen><verb>
SOURCES = foo.c bar.c

PROGRAM = foobar

ifdef CC65_TARGET
CC      = cl65
CFLAGS  = -t $(CC65_TARGET) --create-dep $(<:.c=.d) -O
LDFLAGS = -t $(CC65_TARGET) -m $(PROGRAM).map
else
CC      = gcc
CFLAGS  = -MMD -MP -O
LDFLAGS = -Wl,-Map,$(PROGRAM).map
endif

########################################

.SUFFIXES:
.PHONY: all clean
all: $(PROGRAM)

ifneq ($(MAKECMDGOALS),clean)
-include $(SOURCES:.c=.d)
endif

%.o: %.c
	$(CC) -c $(CFLAGS) -o $@ $<

$(PROGRAM): $(SOURCES:.c=.o)
	$(CC) $(LDFLAGS) -o $@ $^

clean:
	$(RM) $(SOURCES:.c=.o) $(SOURCES:.c=.d) $(PROGRAM) $(PROGRAM).map
</verb></tscreen>

<bf/Important:/ When using the sample Makefile above via copy & paste it is
necessary to replace the eight spaces at the beginning of command lines (lines
26, 29 and 32) with a tab character (ASCII code 9).


<sect1>Invoking the sample Makefile<p>

Without any specific configuration the sample Makefile will compile and link
using GCC. In order to rather use cc65 the variable <tt/CC65_TARGET/ needs to be
defined. This may by done as an environment variable or simply as part of the
Makefile. However to quickly switch between compilers and/or cc65 targets it is
best done on the GNU Make command line like this:

<tscreen><verb>
make CC65_TARGET=c64
</verb></tscreen>


<sect1>Understanding the sample Makefile<p>

Most parts of the sample Makefile follow the guidelines in the
<url url="http://www.gnu.org/software/make/manual/make.html" name="GNU Make Manual">
that can be searched online for background information. The automatic generation of
dependency however rather works as described by the GNU Make maintainer Paul D. Smith in
<url url="http://make.paulandlesley.org/autodep.html#advanced" name="&dquot;Advanced Auto-Dependencies&dquot;">.
Fortunately both GCC and cc65 directly support this method in the meantime.


<sect1>Invoking the sample Makefile on Windows<p>

The recommended way to use GNU Make on Windows is to install it as part of a
Cygwin environment. For more information see the Cygwin home page:

<url url="http://www.cygwin.com/">
  
If however installing Cygwin shouldn't be an option for one or the other reason
then the sample Makefile may be invoked from the Windows Command Prompt (cmd.exe)
by downloading the following programs:

<itemize>
<item><url name="make.exe" url="http://gnuwin32.sourceforge.net/packages/make.htm">
<item><url name="rm.exe" url="http://gnuwin32.sourceforge.net/packages/coreutils.htm">
</itemize>



<sect>Target-specific Variable Values<p>
  
The very limited resources of the cc65 target machines now and then require
manual optimization of the build process by compiling individual source files
with different compiler options. GNU Make offers
<url url="http://www.gnu.org/software/make/manual/html_node/Target_002dspecific.html" name="Target-specific Variable Values">
perfectly suited for doing so. For example placing the code of the two modules 
<tt/foo/ and <tt/bar/ in the segment <tt/FOOBAR/ can be achieved with this
target-specific variable definition:

<tscreen><verb>
foo.o bar.o: CFLAGS += --code-name FOOBAR
</verb></tscreen>
  
</article>
