]> git.sur5r.net Git - cc65/blob - doc/make.sgml
Added documentation on using GNU Make for building cc65 projects.
[cc65] / doc / make.sgml
1 <!doctype linuxdoc system>\r
2 \r
3 <article>\r
4 \r
5 <title>Using GNU Make with cc65\r
6 <author>Oliver Schmidt, <htmlurl url="mailto:ol.sc@web.de" name="ol.sc@web.de">\r
7 <date>26.06.2009\r
8 \r
9 <abstract>\r
10 How to build your program using the GNU Make utility.\r
11 </abstract>\r
12 \r
13 <!-- Table of contents -->\r
14 <toc>\r
15 \r
16 <!-- Begin the document -->\r
17 \r
18 <sect>Overview<p>\r
19 \r
20 This document describes how to build your programs using the cc65 development\r
21 tools and the GNU Make utility.\r
22 \r
23 The cc65 development package doesn't come with a make utility. However this is\r
24 no issue because GNU Make works very nicely with cc65.\r
25 \r
26 \r
27 \r
28 <sect>What is GNU Make?<p>\r
29 \r
30 GNU Make is a both very powerful and very popular make utility. It might even\r
31 be called the de facto standard for make utilities. For more information see\r
32 the GNU Make home page:\r
33 \r
34 <url url="http://www.gnu.org/software/make/">\r
35 \r
36 The cc65 development package is available as binaries for several host systems\r
37 and can easily built for quite some additional systems. The very same is true\r
38 for GNU Make so a cc65-based project coming with a GNU Make Makefile can easily\r
39 be built by any cc65 developer no matter what host system is used.\r
40 \r
41 Because of the strong alignment of the cc65 compiler with the ISO C standard it\r
42 is very well feasable to compile a single C code base both with the cc65\r
43 compiler and other C compilers like for example GCC. GNU Make turns out to be\r
44 very well suited to build projects for several target systems using multiple\r
45 compilers as it isn't tied to any C compiler.\r
46 \r
47 \r
48 \r
49 <sect>A sample Makefile<p>\r
50 \r
51 This Makefile is a fully functional sample for compiling several C sources\r
52 (here <tt/foo.c/ and <tt/bar.c/) and link the resulting object files into an\r
53 executable program (here <tt/foobar/):\r
54 \r
55 <tscreen><verb>\r
56 SOURCES = foo.c bar.c\r
57 \r
58 PROGRAM = foobar\r
59 \r
60 ifdef CC65_TARGET\r
61 CC      = $(CC65_HOME)/bin/cl65\r
62 CFLAGS  = -t $(CC65_TARGET) --create-dep -O\r
63 LDFLAGS = -t $(CC65_TARGET) -m $(PROGRAM).map\r
64 else\r
65 CC      = gcc\r
66 CFLAGS  = -MMD -MP -O\r
67 LDFLAGS = -Wl,-Map,$(PROGRAM).map\r
68 endif\r
69 \r
70 ########################################\r
71 \r
72 ifdef CC65_TARGET\r
73 define MAKEDEPEND\r
74 sed -e"s!.s:!.o:!p" -e"s![^\t]*\t\(.*\)!\1:!" < $(<:.c=.u) > $(@:.o=.d)\r
75 rm -f $(<:.c=.u)\r
76 endef\r
77 endif\r
78 \r
79 .SUFFIXES:\r
80 .PHONY: all\r
81 all: $(PROGRAM)\r
82 \r
83 ifneq ($(MAKECMDGOALS),clean)\r
84 -include $(SOURCES:.c=.d)\r
85 endif\r
86 \r
87 clean:\r
88         rm -f $(SOURCES:.c=.o) $(SOURCES:.c=.d) $(PROGRAM) $(PROGRAM).map\r
89 \r
90 %.o: %.c\r
91         $(CC) -c $(CFLAGS) $< -o $@\r
92         @$(MAKEDEPEND)\r
93 \r
94 $(PROGRAM): $(SOURCES:.c=.o)\r
95         $(CC) $(LDFLAGS) $^ -o $@\r
96 </verb></tscreen>\r
97 \r
98 \r
99 <sect1>Invoking the sample Makefile<p>\r
100 \r
101 Without any specific configuration the sample Makefile will compile and link\r
102 using GCC. In order to rather use cc65 the variable <tt/CC65_TARGET/ needs to be\r
103 defined. This may by done as an environment variable or simply as part of the\r
104 Makefile. However to quickly switch between compilers and/or cc65 targets it is\r
105 best done on the GNU Make command line like this:\r
106 \r
107 <tscreen><verb>\r
108 make CC65_TARGET=c64\r
109 </verb></tscreen>\r
110 \r
111 The sample Makefile doesn't require cc65 to be "installed" in any way. Rather it\r
112 only presumes the single variable <tt/CC65_HOME/ to point to the directory the\r
113 cc65 packages were unpacked into. Again there are several ways to define this\r
114 variable but as its value typically won't change often it is best done as an\r
115 environment variable.\r
116 \r
117 \r
118 <sect1>Understanding the sample Makefile<p>\r
119 \r
120 Most parts of the sample Makefile follow the guidlines in the\r
121 <htmlurl url="http://www.gnu.org/software/make/manual/make.html" name="GNU Make Manual">\r
122 that can be searched online for background information. The automatic generation of\r
123 dependency however rather works as described by the GNU Make maintainer Paul D. Smith in\r
124 <htmlurl url="http://make.paulandlesley.org/autodep.html#advanced" name="Advanced Auto-Dependencies">.\r
125 \r
126 In the meantime GCC supports this method directly with the preprocessor option\r
127 <tt/-MP/ while cc65 requires some post-processing of the dependency file with\r
128 <tt/sed/ adding a second line like in this example:\r
129 \r
130 <tscreen><verb>\r
131 foo.o:  foo.c foo.h bar.h\r
132 foo.c foo.h bar.h:\r
133 </verb></tscreen>\r
134 \r
135 \r
136 <sect1>Invoking the sample Makefile on Windows<p>\r
137 \r
138 The recommended way to use GNU Make on Windows is to install it as part of a\r
139 Cygwin environment. For more information see the Cygwin home page:\r
140 \r
141 <url url="http://www.cygwin.com/">\r
142   \r
143 If however installing Cygwin shouldn't be an option for one or the other reason\r
144 then the sample Makefile may be invoked from the Windows Command Prompt (cmd.exe)\r
145 by downloading the following programs:\r
146 \r
147 <itemize>\r
148 <item>make.exe: <url url="http://gnuwin32.sourceforge.net/packages/make.htm">\r
149 <item>sed.exe: <url url="http://gnuwin32.sourceforge.net/packages/sed.htm">\r
150 <item>rm.exe: <url url="http://gnuwin32.sourceforge.net/packages/coreutils.htm">\r
151 </itemize>\r
152 \r
153 \r
154 \r
155 <sect>Target-specific Variable Values<p>\r
156   \r
157 The very limited resources of the cc65 target machines now and then require\r
158 manual optimization of the build process by compiling individual source files\r
159 with different compiler options. GNU Make offers\r
160 <htmlurl url="http://www.gnu.org/software/make/manual/html_node/Target_002dspecific.html" name="Target-specific Variable Values">\r
161 perfectly suited for doing so. For example placing the code of the two modules \r
162 <tt/foo/ and <tt/bar/ in the segment <tt/FOOBAR/ can be archived with this\r
163 target-specific variable definition:\r
164 \r
165 <tscreen><verb>\r
166 foo.o bar.o: CFLAGS += --code-name FOOBAR\r
167 </verb></tscreen>\r
168   \r
169 </article>\r