2004-06-03 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / build / README.makefiles
1 The MCS makefiles (-*- outline -*-)
2 Peter Williams <peter@newton.cx>
3
4 The new makefiles try to abstract building on Windows and Linux. They
5 try to provide a consistent set of ways to express the things that our
6 build system needs to let us do, specifically:
7
8       * Build recursively
9       * Build libraries and executables easily
10       * Let developers use different runtimes and class libaries
11       * Make distributions easily
12       * Provide a framework for testing
13       * Build platform-independently whenever possible
14
15
16
17
18
19 ** Makefile structure
20
21 A general makefile looks like this:
22
23 ========================================
24 thisdir = class/Mono.My.Library
25 SUBDIRS =
26 include ../../build/rules.make
27
28 all-local:
29         do some stuff
30
31 install-local:
32         $(MKINSTALLDIRS) $(DESTDIR)$(prefix)/share/
33         $(INSTALL_DATA) myfile.txt $(DESTDIR)$(prefix)/share/myfiledir
34
35 clean-local:
36         rm -f my-generated-file
37
38 test-local: my_test_program.exe
39
40 run-test-local:
41         $(RUNTIME) my_test_program.exe
42
43 run-test-ondotnet-local:
44         $(RUNTIME) my_test_program.exe
45
46 DISTFILES = myfile.txt my_test_source.cs
47
48 dist-local: dist-default
49
50 my_test_program.exe: my_test_source.cs
51         $(CSCOMPILE) /target:exe /out:$@ $<
52 ========================================
53
54 Each makefile follows the same pattern: it does some setup, includes
55 the standard make rules, and provides rules for seven standard targets:
56 all, install, test, run-test, clean, and dist.
57
58 "Some setup" is defining two variables: $(thisdir) and
59 $(SUBDIRS). $(thisdir) is the directory that the makefile lives in,
60 relative to the top directory (ie, class/corlib) and $(SUBDIRS)
61 defines the subdirectories that should be built in.
62
63 The seven targets do the following:
64
65         * all-local builds whatever someone would expect to be built
66 when they just type 'make'. Most likely Foo.dll or Foo.exe
67
68         * install-local installs whatever got built by all-local.
69
70         * test-local _builds_ the test programs or libraries but does
71 _not_ run them.
72
73         * run-test-local actually runs the tests. It shouldn't
74 necessarily exit in an error if the test fails, but should make that
75 situation obvious. It should only run tests that take care of
76 themselves automatically; interactive tests should have an individual
77 target. The idea is that 'make run-test' from the toplevel should be
78 able to proceed unsupervised and test everything that can be tested in
79 such a manner.
80
81         * run-test-ondotnet-local is a variant of run-test-local. It is used only to validate if our tests themselves works fine under Microsoft runtime (on Windows). Basically, in this target, we should not use $(TEST_RUNTIME) to test our libraries.
82
83         * clean-local removes built files; 'make clean' should leave
84 only files that go into a distribution tarball. (But it is not necessarily
85 true that all files that go into a tarball need to be left after a make clean.)
86
87         * dist-local copies files into the distribution tree, which is
88 given by the variable $(distdir). dist-local always depends on the
89 target 'dist-default'. See ** 'make dist' below.
90
91
92
93
94
95 ** Build configuration
96
97 In general, MCS needs to be able to build relying only on the
98 existence of a runtime and core libraries (corlib, System,
99 System.Xml). So there shouldn't be any checking for libraries or
100 whatnot; MCS should be able to build out of the box. We try to keep
101 platform detection and feature testing (ie, for HP/UX echo) inside
102 the makefiles; right now, there's no configuration script, and it'd
103 be nice to keep it that way. (I am told that some people build on
104 both Windows and Linux in the same tree, which would be impossible to
105 do if we cached platform-related configury values.)
106
107 That being said, it's very convenient for developers to be able to
108 customize their builds to suit their needs. To allow this, the
109 Makefile rules are set up to allow people to override pretty much any
110 important variable.
111
112 Configuration variables are given defaults in `config-default.make';
113 `rules.make' optionally includes `$(topdir)/build/config.make', so you
114 can customize your build without CVS trying to commit your modified
115 `config-default.make' all the time.  Platform-specific variables are
116 defined in `$(topdir)/build/platforms/$(PLATFORM).make', where
117 $(PLATFORM) is detected in config-default.make. (Currently, the only
118 choices are linux.make and win32.make.)
119
120 The best way to learn what the configuration variables are is to read
121 `config.make' and `platform.make'. There aren't too many and hopefully
122 they should be self-explanatory; see the numerous examples below for
123 more information if you're confused.
124
125
126
127
128
129
130 ** Recommendations for platform specifics
131
132 If you find yourself needing a platform-specific customization, try
133 and express it in terms of a feature, rather than a platform test. In
134 other words, this is good:
135
136 ========================================
137 run-test-local: my-test.exe
138 ifdef PLATFORM_NEEDS_CRAZY_CRAP
139         crazy-crap
140 endif
141         $(RUNTIME) my-test.exe
142 ========================================
143
144 and this is bad:
145
146 ========================================
147 run-test-local: my-test.exe
148 ifdef WINDOWS
149         crazy-crap
150 else
151 ifdef AMIGA
152         crazy-crap
153 endif
154 endif
155         $(RUNTIME) my-test.exe
156 ========================================
157
158 The latter accumulates and gets unpleasant and it sucks. Granted,
159 right now we only have two platforms, so it's not a big deal, but it's
160 good form to get used to and practice. Anyway, take a look at how we
161 do the various corlib building hacks for examples of how we've done
162 platform-specificity. It certainly isn't pretty, but at least it's a
163 little structured.
164
165
166
167
168
169
170 ** Saving effort
171
172         The point of the build system is to abstract things and take
173 care of all the easy stuff. So if you find yourself writing a
174 Makefile, know that there's probably already infrastructure to do what
175 you want. Here are all the common cases I can think of ...
176
177
178
179
180
181
182 * Compiling C# code? use:
183
184 ========================================
185 my-program.exe: my-source.cs
186          $(CSCOMPILE) /target:exe /out:$@ $^
187 ========================================
188
189         or
190
191 ========================================
192 my-lib.dll: my-source.cs
193          $(CSCOMPILE) /target:library /out:$@ $^
194 ========================================
195
196 Note the '$@' and '$^' variables. The former means "the name of the
197 file that I am trying to make" and the latter means "all the
198 dependencies of the file I am trying to make." USE THESE VARIABLES
199 AGGRESSIVELY. Say that you add a new source to your program:
200
201 ========================================
202 my-program.exe: my-source.cs my-new-source.cs
203          $(CSCOMPILE) /target:exe /out:$@ $^
204 ========================================
205
206 Because of the $^ variable, you don't need to remember to add another
207 file to the command line. Similarly, if you rename your program, you
208 won't need to remember to change the rule:
209
210 ========================================
211 MonoVaporizer.exe: my-source.cs my-new-source.cs
212          $(CSCOMPILE) /target:exe /out:$@ $^
213 ========================================
214
215 will still work. Another useful variable is $<, which means "the first
216 dependency of whatever I'm building." If you order your dependencies
217 carefully it can be extremely useful.
218
219
220
221
222
223 * Just building an executable? use:
224
225 ========================================
226 PROGRAM = myprogram.exe
227 LOCAL_MCS_FLAGS = /r:System.Xml.dll
228
229 include ../build/executable.make
230 ========================================
231
232 executable.make builds a program in the current directory. Its name is
233 held in $(PROGRAM), and its sources are listed in the file
234 $(PROGRAM).sources. It might seem to make more sense to just list the
235 program's sources in the Makefile, but when we build on Windows we
236 need to change slashes around, which is much easier to do if the
237 sources are listed in a file. The variable $(LOCAL_MCS_FLAGS) changes
238 the flags given to the compiler; it is included in $(CSCOMPILE) so you
239 don't need to worry about it.
240
241 executable.make does a lot for you: it builds the program in 'make
242 all-local', installs the program in $(prefix)/bin, distributes the
243 sources, and defines empty test targets. Now, if your program has a
244 test, set the variable HAS_TEST:
245
246 ========================================
247 PROGRAM = myprogram.exe
248 LOCAL_MCS_FLAGS = /r:System.Xml.dll
249 HAS_TEST = yes
250 include ../build/executable.make
251
252 test-local: mytester.exe
253
254 run-test-local: mytester.exe
255         $(RUNTIME) $<
256
257 mytester.exe: mytester.cs
258         $(CSCOMPILE) /target:exe /out:$@ mytester.cs
259 ========================================
260
261 If your program has 'built sources', that is, source files generated
262 from other files (say, generated by jay), define a variable called
263 BUILT_SOURCES and do *not* list the sources in $(PROGRAM).sources:
264
265 ========================================
266 PROGRAM = myprogram.exe
267 LOCAL_MCS_FLAGS = /r:System.Xml.dll
268 BUILT_SOURCES = parser.cs
269 CLEAN_FILES = y.output
270
271 include ../build/executable.make
272
273 parser.cs: parser.jay
274         $(topdir)/jay/jay $< > $@
275 ========================================
276
277 executable.make will automatically delete the $(BUILT_SOURCES) files
278 on 'make clean'. Since this situation is a common occurrence and jay
279 happens to leave behind y.output files, you can also define a variable
280 called $(CLEAN_FILES) that lists extra files to be deleted when 'make clean' is
281 called. (That's in addition to your executable and the built sources).
282
283
284
285
286
287
288 * Buildling a library? Use
289
290 ========================================
291 LIBRARY = Mono.MyLib.dll
292 LIB_MCS_FLAGS = /unsafe
293 TEST_MCS_FLAGS = /r:System.Xml.dll
294
295 include ../../build/library.make
296 ========================================
297
298 Where you library is called $(LIBRARY); it will be put into
299 $(topdir)/class/lib. LIB_MCS_FLAGS is the set of MCS flags to use when
300 compiling the library; in addition, a global set of flags called
301 $(LIBRARY_FLAGS) is added (that variable is defined in
302 config-defaults.make), as well as the usual $(LOCAL_MCS_FLAGS).
303
304 As in executable.make, the sources for your library are listed in
305 $(LIBRARY).sources. Note: these source lists should have Unix forward
306 slashes and Unix newlines (\n, not \r\n.) If you get an error about
307 "touch: need a filename", that means your .sources file doesn't end in
308 a newline. It should.
309
310 Now library.make also assumes that your library has an NUnit2 test
311 harness. The files should be in a subdirectory called Test/, and if
312 your library is called Mono.Foo.dll, they should be listed in
313 Mono.Foo_test.dll.sources. The names in that files should *not* have
314 the Test/ prefix. 'make test' will build Mono.Foo_test.dll in the
315 current directory, automatically supplying the flags to reference the
316 original library and NUnit.Framework.dll. 
317
318 If you don't have a test, just do this:
319
320 ========================================
321 LIBRARY = Mono.MyLib.dll
322 LIB_MCS_FLAGS = /unsafe
323 NO_TEST = yes
324
325 include ../../build/library.make
326 ========================================
327
328 and feel ashamed. Every good library has a test suite!
329
330 Extra flags needed to compile the test library should be listed in
331 $(TEST_MCS_FLAGS); often you will have a line like this:
332
333 ========================================
334 TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
335 ========================================
336
337 Again, library.make does a lot for you: it builds the dll, it
338 generates makefile fragments to track the dependencies, it installs
339 the library, it builds the test dll on 'make test', it runs
340 $(TEST_HARNESS) on it on 'make run-test', it removes the appropriate
341 files on 'make clean', and it distributes all the source files on
342 'make dist'. (TEST_HARNESS defaults to be nunit-console.exe but it may
343 be overridden to, say, nunit-gtk). If you have extra files to
344 distribute when using either library.make or executable.make, use the
345 variable $(EXTRA_DISTFILES):
346
347 ========================================
348 EXTRA_DISTFILES = \
349         Test/testcase1.in               \
350         Test/testcase1.out              \
351         README
352 ========================================
353
354 Again, library.make and executable.make do the right things so that we
355 can build on Windows, doing some trickery to invert slashes and
356 overcome command-line length limitations. Use them unless you have a
357 really good reason not to. If you're building a bunch of small
358 executables, check out tools/Makefile or tools/security/Makefile; if
359 all the files are in the current directory, changing slashes isn't a
360 big deal, and command-line lengths won't be a problem, so
361 executable.make isn't necessary (and indeed it won't work, since it
362 can only build one .exe in a directory).
363
364 If you're building a library, library.make is highly recommended; the
365 only DLL that doesn't use it is corlib, because building corlib is a
366 fair bit more complicated than it should be. Oh well.
367
368
369
370
371
372
373 * Running a C# program? Use $(RUNTIME)
374
375 ========================================
376 run-test-local: myprog.exe
377         $(RUNTIME) myprog.exe
378 ========================================
379
380 $(RUNTIME) might be empty (if you're on windows), so don't expect to
381 be able to give it any arguments. If you're on a platform which has an
382 interpreter or jitter, $(RUNTIME_FLAGS) is included in $(RUNTIME), so
383 set that variable.
384
385 $(TEST_RUNTIME) is the runtime to use when running tests. Right now it's
386 just "mono --debug".
387
388
389
390 * Calling the compiler directly? Use $(MCS).
391
392 Really, you should use $(CSCOMPILE) whenever possible, but $(MCS) is
393 out there. $(BOOTSTRAP_MCS) is the C# compiler that we use to build
394 mcs.exe; on Linux, we then use mcs.exe to build everything else, but
395 on Windows, we use csc.exe to build everything. Only use
396 $(BOOTSTRAP_MCS) if you know what you're doing.
397
398
399
400
401
402 * Compiling C code? Use $(CCOMPILE)
403
404 To give it flags, set $(LOCAL_CFLAGS). As with compiling C#, the
405 variable $(CFLAGS) will automatically be included on the command line.
406
407
408
409
410
411 * Installing files? Use $(MKINSTALLDIRS), $(INSTALL_DATA) or
412 $(INSTALL_BIN), $(prefix), and $(DESTDIR).
413
414 Every time a file is installed the commands should look like this:
415
416 ========================================
417 install-local:
418         $(MKINSTALLDIRS) $(DESTDIR)$(prefix)/my/dir
419         $(INSTALL_DATA) myfile $(DESTDIR)$(prefix)/my/dir
420 ========================================
421
422 This way the directory is created recursively if needed (admittedly, we could
423 probably rely on mkdir -p), the file is given the correct permissions,
424 the user can override $(MKINSTALLDIRS) and $(INSTALL) if they need to,
425 and we can support $(DESTDIR) installs. We use $(DESTDIR) to make
426 monocharge tarballs, and it's useful otherwise, so try and use it
427 consistently.
428
429
430
431
432
433 * 'make dist'? Use $(DISTFILES)
434
435 The 'dist-default' target will copy the files listed in $(DISTFILES)
436 into the distribution directory, as well as Makefile and ChangeLog if
437 they exist. This is almost always all that you need, so ideally your
438 make dist support should only be:
439
440 ========================================
441 DISTFILES = README Test/thoughts.txt
442
443 dist-local: dist-default
444 ========================================
445
446 DISTFILES will cope correctly with files in subdirectories, by the
447 way. Note that if you put a nonexistant file or a directory in
448 DISTFILES it will *not* complain; it will just ignore it.
449
450 If you want to test your 'make dist' code, you can try
451
452 ========================================
453 $ cd class/Mono.MyClass
454 $ make dist-local distdir=TEST
455 ========================================
456
457 And your files should be copied into TEST/ in the current directory.
458 There is a toplevel 'make distcheck' target, which will build a dist
459 tarball, try to build it, install files to a temporary prefix, make
460 clean it, make a distribution, and compare the files left over to the
461 files originally in the tarball: they should be the same. But this
462 takes about 15 minutes to run on my 1.1 Ghz computer, so it's not for
463 the faint of heart.
464
465
466
467
468
469 * Lots of files? Use $(wildcard *.foo)
470
471 When specifying the sources to a library or executable, wildcards are
472 not encouraged; in fact they're not allowed if you use library.make or
473 executable.make. But there are times when they're useful, eg:
474
475 ========================================
476 DISTFILES = $(wildcard Test/*.in) $(wildcard Test/*.out)
477 ========================================
478
479 Just so you know that 'make' has this feature.
480
481
482
483
484
485
486 * Referencing files in other directories? Use $(topdir).
487
488 $(topdir) is the path to the top directory from the current build
489 directory. Basically it's a sequence of ../.. computed from the value
490 that you give $(thisdir) at the top of your Makefile. Try to reference
491 things from $(topdir), so your code can be moved or cut-and-pasted
492 around with a minimum of fuss.
493
494
495
496
497
498
499 * Conditional building? Use ifdef/ifndef/endif
500
501 Now in general we want to avoid conditional building, but sometimes
502 something doesn't work on Linux or already exists on Windows or
503 whatnot. (See below on recommended form for how to build
504 platform-specifically.) GNU Make supports the following construction:
505
506 ========================================
507 BUILD_EXPERIMENTAL = yes
508
509 ifdef BUILD_EXPERIMENTAL
510 experimental_stuff = my-experiment.exe
511 else
512 experimental_stuff = 
513 endif
514
515 all-local: my-sane.exe $(experimental_stuff)
516 ========================================
517
518 'ifdef' means 'if the variable is set to nonempty', so you could have 
519
520 ========================================
521 BUILD_EXPERIMENTAL = colorless green ideas sleep furiously
522 ========================================
523
524 and Make would be happy. I hope that the meaning of 'ifndef' should be
525 obvious. If you want to only sometimes build a target, the above
526 construction is the recommended way to go about it; it's nice to have
527 the rules exist in a Makefile even if they aren't invoked.
528
529 If you want to see why conditionals aren't nice, take a look at
530 library.make or class/corlib/Makefile.
531
532
533
534
535
536 * 'Private' directories that shouldn't be built by default? Use DIST_ONLY_SUBDIRS
537
538 Several of the MCS class libraries have demo or experimental
539 implementations that depend on things not included with MCS (say,
540 Gtk#). We don't want to build them by default, because the user might
541 not have those dependencies installed, but it's nice to have a
542 Makefile for them to be built nicely.
543
544 First of all, there's nothing stopping you from writing a Makefile for
545 such a directory; just don't put it in the SUBDIRS line of its parent
546 directory. That way, you can do all the normal build things like 'make
547 all' or 'make clean' in that directory, but people trying to bootstrap
548 their system won't run into problems.
549
550 At the same time you probably want to include this directory in the
551 distribution so that people can use your demo or experimental code if
552 they know what they're doing. Hence the variable
553 $(DIST_ONLY_SUBDIRS). As you might guess, it's like the SUBDIRS
554 variable: it lists subdirectories that a regular shouldn't recurse
555 into, but should have their 'make dist' rules invoked. 
556
557 Say you've written Mono.MyFancyLib.dll and you have
558 a demo app using Gtk# called MyFancyDemo. The Makefile rules might
559 look like this:
560
561 class/Mono.MyFancyLib/Makefile
562 ========================================
563 thisdir = class/Mono.MyFancyLib
564 SUBDIRS =
565 DIST_ONLY_SUBDIRS = MyFancyDemo
566 include ../../build/rules.make
567
568 LIBRARY = Mono.MyFancyLib.dll
569 LIB_MCS_FLAGS = /r:System.dll
570 TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
571
572 include ../../build/library.make
573 ========================================
574
575 class/Mono.MyFancyLib/MyFancyDemo/Makefile
576 ========================================
577 thisdir = class/Mono.MyFancyLib/MyFancyDemo
578 SUBDIRS =
579 include ../../../build/rules.make
580
581 PROGRAM = FancyDemo.exe
582 LOCAL_MCS_FLAGS = /r:gtk-sharp.dll
583
584 include ../../../build/executable.make
585 ========================================
586
587
588
589
590 * Special recursion needs? Use OVERRIDE_BARE_TARGETS
591
592 By default, rules.make defines the all, install, clean, etc. targets
593 to look something like this:
594
595    all: all-recursive all-local
596
597 Sometimes that doesn't cut it; say for example you want to check for
598 something before doing a lengthy recursive build (see
599 $(topdir)/Makefile) or you have a something like this
600
601         class/MyLibrary:
602                 Build MyLibrary.dll
603         class/MyLibrary/Test:
604                 Build TestMyLibrary.exe
605
606 'make clean test' will fail here, because the build will happen in
607 the Test subdirectory first, so there will be no MyLibrary.dll to link
608 against. (Unless you write a nasty evil relative path rule which is
609 strongly discouraged.)
610
611 Anyway, to solve this problem you can do
612
613 ========================================
614 OVERRIDE_BARE_TARGETS = yes
615 thisdir = class/MyLibrary
616 SUBDIRS = Test
617 include ../../build/rules.make
618
619 # This is normally "all-recursive all-local"
620 all: all-local all-recursive
621
622 test: test-local test-recursive
623 ...
624 ========================================
625
626
627
628
629
630 ** A few implementation details
631
632 The way rules.make does its recursion is very standard; it maps
633 {all,install,clean, dist,test} to $@-recursive, which executes that
634 rule in each directory in $(SUBDIRS), and then calls $@-local in the
635 current directory. So something that gets built in a subdirectory
636 cannot rely on something that gets built in its parent directory. If
637 this is a problem, see the bit about using OVERRIDE_BARE_TARGETS;
638 since the recursive rules do $(MAKE) $* in their subdirectories,
639 changing the 'all' target will do the right thing in a recursive
640 build. Note that the recursive rule for 'dist' is different; it makes
641 dist-recursive in subdirectories, so you at least have to define that
642 rule, even if you use OVERRIDE_BARE_TARGETS.
643
644 Note that even a directory that doesn't, for example, have any tests
645 must still define test-local; otherwise 'make test' run from the
646 toplevel directory will break.
647
648
649
650
651
652
653 ** Flags for Tools
654
655 We want to make it so that the user can specify certain flags to
656 always be given to a tool, so there's a general way of implementing
657 FLAGS variables:
658
659         * $(foo_FLAGS) remains unset or defaulted to something
660           sensible; the user can provide overrides this way.
661
662         * $(LOCAL_foo_FLAGS) is set in a specific Makefile to
663           provide necessary values.
664
665         * $(PLATFORM_foo_FLAGS) is set in the platform configuration
666           to provide platform-specific values.
667
668         * $(PROFILE_foo_FLAGS) is set in the profile configuration
669           to provide profile-specific values.
670
671         * $(USE_foo_FLAGS) is defined to be the combination of all of
672           the above, and it's what is actually passed to $(foo).
673
674 $(MCS_FLAGS) and $(CFLAGS) follow this model. If you end up finding
675 that another tool is used commonly (hm, jay...), please follow this form.
676
677
678
679
680
681
682 ** Portability tips
683
684 Always use the icky Windows /argument way of passing parameters to the C#
685 compiler so that csc can be used.
686
687 Always use /r:foo.dll, not /r:foo. Windows requires the former.
688
689 Use /r:$(corlib), not /r:corlib.
690
691 If you're writing shell script code as part of a make rule, remember
692 that Windows has command-line length limits. So something like
693
694 ========================================
695 mytool $(all_the_sources_to_corlib)
696 ========================================
697
698 Is probably going to cause problems. As I understand it, 
699
700 ========================================
701 for f in  $(all_the_sources_to_corlib) ; do ...
702 ========================================
703
704 is ok, since the shell itself doesn't have those limitations. Other
705 than that, you should still try to write fairly portable shell
706 script. Linux and Cygwin both use the GNU utilities, but there's at
707 least one hardy soul trying to build Mono on HP/UX, and no doubt there
708 will be ports to more Unices as time goes on.
709
710
711
712
713
714
715 ** Misc
716
717 We still don't use /d:NET_1_1 ; it causes some build problems right
718 now.
719
720 There's a hack in class/System.Data/Makefile to work around a very
721 strange crash in the runtime with some custom attribute stuff. It'd be
722 nice to fix it.
723
724 Also, there's a /lib:$(prefix)/lib in the System.dll Makefile, which
725 is for some reason necessary if System.Xml.dll hasn't been built yet.
726 (Well, it's necessary because of the /r:System.Xml.dll, but that
727 should be in the search path, it seems.)
728
729 A lot of the weird targets in the old makefiles have been dropped; I
730 have a feeling that a lot of them are archaic and not needed anymore.
731
732 I'd really like to write a build tool in C#. It would be nice to have
733 something really extensible and well-designed and clean. NAnt is,
734 IMHO, an apalling abomination and a tragically bad attempt at solving
735 the software building problem. Just so you know.
736
737 (On the other hand, NUnit is really neat.)
738
739 Peter