Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mcs/build/Makefile22
-rw-r--r--mcs/build/README.configury23
-rw-r--r--mcs/build/README.makefiles696
-rw-r--r--mcs/build/README.platforms41
-rw-r--r--mcs/build/config-default.make30
-rw-r--r--mcs/build/executable.make71
-rw-r--r--mcs/build/library.make134
-rw-r--r--mcs/build/platforms/linux.make44
-rw-r--r--mcs/build/platforms/win32.make21
-rw-r--r--mcs/build/profiles/bootstrap.make18
-rw-r--r--mcs/build/profiles/default.make14
-rw-r--r--mcs/build/profiles/net_1_0.make15
-rw-r--r--mcs/build/rules.make119
13 files changed, 1248 insertions, 0 deletions
diff --git a/mcs/build/Makefile b/mcs/build/Makefile
new file mode 100644
index 00000000000..6d8e4b60493
--- /dev/null
+++ b/mcs/build/Makefile
@@ -0,0 +1,22 @@
+thisdir = build
+SUBDIRS =
+include ../build/rules.make
+
+all-local install-local test-local run-test-local clean-local:
+
+DISTFILES = \
+ README.makefiles \
+ README.platforms \
+ README.configury \
+ config-default.make \
+ executable.make \
+ library.make \
+ rules.make \
+ platforms/linux.make \
+ platforms/win32.make \
+ profiles/default.make \
+ profiles/bootstrap.make \
+ profiles/net_1_0.make
+
+dist-local: dist-default
+ mkdir $(distdir)/deps
diff --git a/mcs/build/README.configury b/mcs/build/README.configury
new file mode 100644
index 00000000000..52732e6bdad
--- /dev/null
+++ b/mcs/build/README.configury
@@ -0,0 +1,23 @@
+Configuring the build (-*- outline -*-)
+Peter Williams <peter@newton.cx>
+
+** Configuring the build
+
+It's pretty easy. You can create two files in this directory to tweak
+settings: pre-config.make and config.make.
+
+pre-config.make is included before $(PLATFORM).make and
+$(PROFILE).make, so you can set either of these variables if you want
+to change the default.
+
+Just about any other change should go in config.make, which is
+included after $(PLATFORM).make and $(PROFILE).make, so you can use
+the values defined in those files if you wish. For example,
+
+ MCS_FLAGS = $(DEFAULT_MCS_FLAGS) /my-experimental-optimizer-flag
+
+or something.
+
+(You shouldn't need to edit any of the existing Makefiles for
+site-specific hacks. CVS would complain at you and `make dist'
+wouldn't be happy.)
diff --git a/mcs/build/README.makefiles b/mcs/build/README.makefiles
new file mode 100644
index 00000000000..fedda941b00
--- /dev/null
+++ b/mcs/build/README.makefiles
@@ -0,0 +1,696 @@
+The MCS makefiles (-*- outline -*-)
+Peter Williams <peter@newton.cx>
+
+The new makefiles try to abstract building on Windows and Linux. They
+try to provide a consistent set of ways to express the things that our
+build system needs to let us do, specifically:
+
+ * Build recursively
+ * Build libraries and executables easily
+ * Let developers use different runtimes and class libaries
+ * Make distributions easily
+ * Provide a framework for testing
+ * Build platform-independently whenever possible
+
+
+
+
+
+** Makefile structure
+
+A general makefile looks like this:
+
+========================================
+thisdir = class/Mono.My.Library
+SUBDIRS =
+include ../../rules.make
+
+all-local:
+ do some stuff
+
+install-local:
+ $(MKINSTALLDIRS) $(DESTDIR)$(prefix)/share/
+ $(INSTALL_DATA) myfile.txt $(DESTDIR)$(prefix)/share/myfiledir
+
+clean-local:
+ rm -f my-generated-file
+
+test-local: my_test_program.exe
+
+run-test-local:
+ $(RUNTIME) my_test_program.exe
+
+DISTFILES = myfile.txt my_test_source.cs
+
+dist-local: dist-default
+
+my_test_program.exe: my_test_source.cs
+ $(CSCOMPILE) /target:exe /out:$@ $<
+========================================
+
+Each makefile follows the same pattern: it does some setup, includes
+the standard make rules, and provides rules for six standard targets:
+all, install, test, run-test, clean, and dist.
+
+"Some setup" is defining two variables: $(thisdir) and
+$(SUBDIRS). $(thisdir) is the directory that the makefile lives in,
+relative to the top directory (ie, class/corlib) and $(SUBDIRS)
+defines the subdirectories that should be built in.
+
+The six targets do the following:
+
+ * all-local builds whatever someone would expect to be built
+when they just type 'make'. Most likely Foo.dll or Foo.exe
+
+ * install-local installs whatever got built by all-local.
+
+ * test-local _builds_ the test programs or libraries but does
+_not_ run them.
+
+ * run-test-local actually runs the tests. It shouldn't
+necessarily exit in an error if the test fails, but should make that
+situation obvious. It should only run tests that take care of
+themselves automatically; interactive tests should have an individual
+target. The idea is that 'make run-test' from the toplevel should be
+able to proceed unsupervised and test everything that can be tested in
+such a manner.
+
+ * clean-local removes built files; 'make clean' should leave
+only files that go into a distribution tarball
+
+ * dist-local copies files into the distribution tree, which is
+given by the variable $(distdir). dist-local always depends on the
+target 'dist-default'. See ** 'make dist' below.
+
+
+
+
+
+** Build configuration
+
+In general, MCS needs to be able to build relying only on the
+existence of a runtime and core libraries (corlib, System,
+System.Xml). So there shouldn't be any checking for libraries or
+whatnot; MCS should be able to build out of the box after only
+'./configure linux' or './configure win32'.
+
+That being said, it's very convenient for developers to be able to
+customize their builds to suit their needs. To allow this, the
+Makefile rules are set up to allow people to override pretty much any
+important variable.
+
+Configuration variables are given defaults in `config-default.make';
+`rules.make' optionally includes `$(topdir)/config.make', so you can
+customize your build without CVS trying to commit your modified
+`config-default.make' all the time. Platform-specific variables are
+defined in `$(topdir)/platform.make', which should be a copy of one of
+the appropriate platform-specific makefiles. (Currently, the only
+choices are linux.make and win32.make.)
+
+The best way to learn what the configuration variables are is to read
+`config.make' and `platform.make'. There aren't too many and hopefully
+they should be self-explanatory; see the numerous examples below for
+more information if you're confused.
+
+
+
+
+
+
+** Recommendations for platform specifics
+
+If you find yourself needing a platform-specific customization, try
+and express it in terms of a feature, rather than a platform test. In
+other words, this is good:
+
+========================================
+run-test-local: my-test.exe
+ifdef PLATFORM_NEEDS_CRAZY_CRAP
+ crazy-crap
+endif
+ $(RUNTIME) my-test.exe
+========================================
+
+and this is bad:
+
+========================================
+run-test-local: my-test.exe
+ifdef WINDOWS
+ crazy-crap
+else
+ifdef AMIGA
+ crazy-crap
+endif
+endif
+ $(RUNTIME) my-test.exe
+========================================
+
+The latter accumulates and gets unpleasant and it sucks. Granted,
+right now we only have two platforms, so it's not a big deal, but it's
+good form to get used to and practice. Anyway, take a look at how we
+do the various corlib building hacks for examples of how we've done
+platform-specificity. It certainly isn't pretty, but at least it's a
+little structured.
+
+
+
+
+
+
+** Saving effort
+
+ The point of the build system is to abstract things and take
+care of all the easy stuff. So if you find yourself writing a
+Makefile, know that there's probably already infrastructure to do what
+you want. Here are all the common cases I can think of ...
+
+
+
+
+
+
+* Compiling C# code? use:
+
+========================================
+my-program.exe: my-source.cs
+ $(CSCOMPILE) /target:exe /out:$@ $^
+========================================
+
+ or
+
+========================================
+my-lib.dll: my-source.cs
+ $(CSCOMPILE) /target:library /out:$@ $^
+========================================
+
+Note the '$@' and '$^' variables. The former means "the name of the
+file that I am trying to make" and the latter means "all the
+dependencies of the file I am trying to make." USE THESE VARIABLES
+AGGRESSIVELY. Say that you add a new source to your program:
+
+========================================
+my-program.exe: my-source.cs my-new-source.cs
+ $(CSCOMPILE) /target:exe /out:$@ $^
+========================================
+
+Because of the $^ variable, you don't need to remember to add another
+file to the command line. Similarly, if you rename your program, you
+won't need to remember to change the rule:
+
+========================================
+MonoVaporizer.exe: my-source.cs my-new-source.cs
+ $(CSCOMPILE) /target:exe /out:$@ $^
+========================================
+
+will still work. Another useful variable is $<, which means "the first
+dependency of whatever I'm building." If you order your dependencies
+carefully it can be extremely useful.
+
+
+
+
+
+* Just building an executable? use:
+
+========================================
+PROGRAM = myprogram.exe
+LOCAL_MCS_FLAGS = /r:System.Xml.dll
+
+include ../executable.make
+========================================
+
+executable.make builds a program in the current directory. Its name is
+held in $(PROGRAM), and its sources are listed in the file
+$(PROGRAM).sources. It might seem to make more sense to just list the
+program's sources in the Makefile, but when we build on Windows we
+need to change slashes around, which is much easier to do if the
+sources are listed in a file. The variable $(LOCAL_MCS_FLAGS) changes
+the flags given to the compiler; it is included in $(CSCOMPILE) so you
+don't need to worry about it.
+
+executable.make does a lot for you: it builds the program in 'make
+all-local', installs the program in $(prefix)/bin, distributes the
+sources, and defines empty test targets. Now, if your program has a
+test, set the variable HAS_TEST:
+
+========================================
+PROGRAM = myprogram.exe
+LOCAL_MCS_FLAGS = /r:System.Xml.dll
+HAS_TEST = yes
+include ../executable.make
+
+test-local: mytester.exe
+
+run-test-local: mytester.exe
+ $(RUNTIME) $<
+
+mytester.exe: mytester.cs
+ $(CSCOMPILE) /target:exe /out:$@ mytester.cs
+========================================
+
+If your program has 'built sources', that is, source files generated
+from other files (say, generated by jay), define a variable called
+BUILT_SOURCES and do *not* list the sources in $(PROGRAM).sources:
+
+========================================
+PROGRAM = myprogram.exe
+LOCAL_MCS_FLAGS = /r:System.Xml.dll
+BUILT_SOURCES = parser.cs
+CLEAN_FILES = y.output
+
+include ../executable.make
+
+parser.cs: parser.jay
+ $(topdir)/jay/jay $< > $@
+========================================
+
+executable.make will automatically delete the $(BUILT_SOURCES) files
+on 'make clean'. Since this situation is a common occurrence and jay
+happens to leave behind y.output files, you can also define a variable
+called $(CLEAN_FILES) that lists extra files to be deleted when 'make clean' is
+called. (That's in addition to your executable and the built sources).
+
+
+
+
+
+
+* Buildling a library? Use
+
+========================================
+LIBRARY = Mono.MyLib.dll
+LIB_MCS_FLAGS = /unsafe
+TEST_MCS_FLAGS = /r:System.Xml.dll
+
+include ../../library.make
+========================================
+
+Where you library is called $(LIBRARY); it will be put into
+$(topdir)/class/lib. LIB_MCS_FLAGS is the set of MCS flags to use when
+compiling the library; in addition, a global set of flags called
+$(LIBRARY_FLAGS) is added (that variable is defined in
+config-defaults.make), as well as the usual $(LOCAL_MCS_FLAGS).
+
+As in executable.make, the sources for your library are listed in
+$(LIBRARY).sources. Note: these source lists should have Unix forward
+slashes and Unix newlines (\n, not \r\n.) If you get an error about
+"touch: need a filename", that means your .sources file doesn't end in
+a newline. It should.
+
+Now library.make also assumes that your library has an NUnit2 test
+harness. The files should be in a subdirectory called Test/, and if
+your library is called Mono.Foo.dll, they should be listed in
+Mono.Foo_test.dll.sources. The names in that files should *not* have
+the Test/ prefix. 'make test' will build Mono.Foo_test.dll in the
+current directory, automatically supplying the flags to reference the
+original library and NUnit.Framework.dll.
+
+If you don't have a test, just do this:
+
+========================================
+LIBRARY = Mono.MyLib.dll
+LIB_MCS_FLAGS = /unsafe
+NO_TEST = yes
+
+include ../../library.make
+========================================
+
+and feel ashamed. Every good library has a test suite!
+
+Extra flags needed to compile the test library should be listed in
+$(TEST_MCS_FLAGS); often you will have a line like this:
+
+========================================
+TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
+========================================
+
+Again, library.make does a lot for you: it builds the dll, it
+generates makefile fragments to track the dependencies, it installs
+the library, it builds the test dll on 'make test', it runs
+$(TEST_HARNESS) on it on 'make run-test', it removes the appropriate
+files on 'make clean', and it distributes all the source files on
+'make dist'. (TEST_HARNESS defaults to be nunit-console.exe but it may
+be overridden to, say, nunit-gtk). If you have extra files to
+distribute when using either library.make or executable.make, use the
+variable $(EXTRA_DISTFILES):
+
+========================================
+EXTRA_DISTFILES = \
+ Test/testcase1.in \
+ Test/testcase1.out \
+ README
+========================================
+
+Again, library.make and executable.make do the right things so that we
+can build on Windows, doing some trickery to invert slashes and
+overcome command-line length limitations. Use them unless you have a
+really good reason not to. If you're building a bunch of small
+executables, check out tools/Makefile or tools/security/Makefile; if
+all the files are in the current directory, changing slashes isn't a
+big deal, and command-line lengths won't be a problem, so
+executable.make isn't necessary (and indeed it won't work, since it
+can only build one .exe in a directory).
+
+If you're building a library, library.make is highly recommended; the
+only DLL that doesn't use it is corlib, because building corlib is a
+fair bit more complicated than it should be. Oh well.
+
+
+
+
+
+
+* Running a C# program? Use $(RUNTIME)
+
+========================================
+run-test-local: myprog.exe
+ $(RUNTIME) myprog.exe
+========================================
+
+$(RUNTIME) might be empty (if you're on windows), so don't expect to
+be able to give it any arguments. If you're on a platform which has an
+interpreter or jitter, $(RUNTIME_FLAGS) is included in $(RUNTIME), so
+set that variable.
+
+
+
+
+
+* Calling the compiler directly? Use $(MCS).
+
+Really, you should use $(CSCOMPILE) whenever possible, but $(MCS) is
+out there. $(BOOTSTRAP_MCS) is the C# compiler that we use to build
+mcs.exe; on Linux, we then use mcs.exe to build everything else, but
+on Windows, we use csc.exe to build everything. Only use
+$(BOOTSTRAP_MCS) if you know what you're doing.
+
+
+
+
+
+* Compiling C code? Use $(CCOMPILE)
+
+To give it flags, set $(LOCAL_CFLAGS). As with compiling C#, the
+variable $(CFLAGS) will automatically be included on the command line.
+
+
+
+
+
+* Installing files? Use $(MKINSTALLDIRS), $(INSTALL_DATA) or
+$(INSTALL_BIN), $(prefix), and $(DESTDIR).
+
+Every time a file is installed the commands should look like this:
+
+========================================
+install-local:
+ $(MKINSTALLDIRS) $(DESTDIR)$(prefix)/my/dir
+ $(INSTALL_DATA) myfile $(DESTDIR)$(prefix)/my/dir
+========================================
+
+This way the directory is created recursively if needed (admittedly, we could
+probably rely on mkdir -p), the file is given the correct permissions,
+the user can override $(MKINSTALLDIRS) and $(INSTALL) if they need to,
+and we can support $(DESTDIR) installs. We use $(DESTDIR) to make
+monocharge tarballs, and it's useful otherwise, so try and use it
+consistently.
+
+
+
+
+
+* 'make dist'? Use $(DISTFILES)
+
+The 'dist-default' target will copy the files listed in $(DISTFILES)
+into the distribution directory, as well as Makefile and ChangeLog if
+it exists. This is almost always all that you need, so ideally your
+make dist support should only be:
+
+========================================
+DISTFILES = README Test/thoughts.txt
+
+dist-local: dist-default
+========================================
+
+DISTFILES will cope correctly with files in subdirectories, by the
+way. Note that if you put a nonexistant file or a directory in
+DISTFILES it will *not* complain; it will just ignore it.
+
+If you want to test your 'make dist' code, you can try
+
+========================================
+$ cd class/Mono.MyClass
+$ make dist-local distdir=TEST
+========================================
+
+And your files should be copied into TEST/ in the current directory.
+There is a toplevel 'make distcheck' target, which will build a dist
+tarball, try to build it, install files to a temporary prefix, make
+clean it, make a distribution, and compare the files left over to the
+files originally in the tarball: they should be the same. But this
+takes about 15 minutes to run on my 1.1 Ghz computer, so it's not for
+the faint of heart.
+
+
+
+
+
+* Lots of files? Use $(wildcard *.foo)
+
+When specifying the sources to a library or executable, wildcards are
+not encouraged; in fact they're not allowed if you use library.make or
+executable.make. But there are times when they're useful, eg:
+
+========================================
+DISTFILES = $(wildcard Test/*.in) $(wildcard Test/*.out)
+========================================
+
+Just so you know that 'make' has this feature.
+
+
+
+
+
+
+* Referencing files in other directories? Use $(topdir).
+
+$(topdir) is the path to the top directory from the current build
+directory. Basically it's a sequence of ../.. computed from the value
+that you give $(thisdir) at the top of your Makefile. Try to reference
+things from $(topdir), so your code can be moved or cut-and-pasted
+around with a minimum of fuss.
+
+
+
+
+
+
+* Conditional building? Use ifdef/ifndef/endif
+
+Now in general we want to avoid conditional building, but sometimes
+something doesn't work on Linux or already exists on Windows or
+whatnot. (See below on recommended form for how to build
+platform-specifically.) GNU Make supports the following construction:
+
+========================================
+BUILD_EXPERIMENTAL = yes
+
+ifdef BUILD_EXPERIMENTAL
+experimental_stuff = my-experiment.exe
+else
+experimental_stuff =
+endif
+
+all-local: my-sane.exe $(experimental_stuff)
+========================================
+
+'ifdef' means 'if the variable is set to nonempty', so you could have
+
+========================================
+BUILD_EXPERIMENTAL = colorless green ideas sleep furiously
+========================================
+
+and Make would be happy. I hope that the meaning of 'ifndef' should be
+obvious. If you want to only sometimes build a target, the above
+construction is the recommended way to go about it; it's nice to have
+the rules exist in a Makefile even if they aren't invoked.
+
+If you want to see why conditionals aren't nice, take a look at
+library.make or class/corlib/Makefile.
+
+
+
+
+
+* 'Private' directories that shouldn't be built by default? Use DIST_ONLY_SUBDIRS
+
+Several of the MCS class libraries have demo or experimental
+implementations that depend on things not included with MCS (say,
+Gtk#). We don't want to build them by default, because the user might
+not have those dependencies installed, but it's nice to have a
+Makefile for them to be built nicely.
+
+First of all, there's nothing stopping you from writing a Makefile for
+such a directory; just don't put it in the SUBDIRS line of its parent
+directory. That way, you can do all the normal build things like 'make
+all' or 'make clean' in that directory, but people trying to bootstrap
+their system won't run into problems.
+
+At the same time you probably want to include this directory in the
+distribution so that people can use your demo or experimental code if
+they know what they're doing. Hence the variable
+$(DIST_ONLY_SUBDIRS). As you might guess, it's like the SUBDIRS
+variable: it lists subdirectories that a regular shouldn't recurse
+into, but should have their 'make dist' rules invoked.
+
+Say you've written Mono.MyFancyLib.dll and you have
+a demo app using Gtk# called MyFancyDemo. The Makefile rules might
+look like this:
+
+class/Mono.MyFancyLib/Makefile
+========================================
+thisdir = class/Mono.MyFancyLib
+SUBDIRS =
+DIST_ONLY_SUBDIRS = MyFancyDemo
+include ../../rules.make
+
+LIBRARY = Mono.MyFancyLib.dll
+LIB_MCS_FLAGS = /r:System.dll
+TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
+
+include ../../library.make
+========================================
+
+class/Mono.MyFancyLib/MyFancyDemo/Makefile
+========================================
+thisdir = class/Mono.MyFancyLib/MyFancyDemo
+SUBDIRS =
+include ../../../rules.make
+
+PROGRAM = FancyDemo.exe
+LOCAL_MCS_FLAGS = /r:gtk-sharp.dll
+
+include ../../../executable.make
+========================================
+
+
+
+
+
+
+** A few implementation details
+
+The way rules.make does its recursion is very standard; it maps
+{all,install,clean, dist,test} to $@-recursive, which executes that
+rule in each directory in $(SUBDIRS), and then calls $@-local in the
+current directory. So something that gets built in a subdirectory
+cannot rely on something that gets built in its parent directory; so
+far, this hasn't really been a problem, and I hope it won't be. One
+crappy solution would be:
+
+========================================
+thisdir = directory/subdir
+SUBDIRS =
+include ../../rules.make
+
+all-local: myfoo.exe
+
+myfoo.exe: ../libfoo.dll
+ $(CSCOMPILE) ...
+
+../libfoo.dll:
+ cd .. && $(MAKE) libfoo.dll
+========================================
+
+Alternatively, I think I could add support so that you could do this:
+
+========================================
+thisdir = directory
+SUBDIRS = . subdir # <-- look at this
+include ../../rules.make
+
+all-local: libfoo.dll
+
+libfoo.dll:
+ $(CSCOMPILE) ...
+========================================
+
+But that would get into some really nasty shell script so I'd rather
+not have to do that.
+
+Note that even a directory that doesn't, for example, have any tests
+must still define test-local; otherwise 'make test' run from the
+toplevel directory will break.
+
+
+
+
+
+
+** Flags
+
+We want to make it so that the user can specify certain flags to
+always be given to a tool, so there's a general way of implementing
+FLAGS variables:
+
+ * $(foo_FLAGS) remains unset or defaulted to something
+ sensible; the user can provide overrides this way.
+
+ * $(LOCAL_foo_FLAGS) is set in a specific Makefile to
+ provide necessary values.
+
+ * $(USE_foo_FLAGS) is defined to be the combination of
+ $(LOCAL_foo_FLAGS) and $(foo_FLAGS), and it's what is
+ actually passed to $(foo).
+
+$(MCS_FLAGS) and $(CFLAGS) follow this model. If you end up finding
+that another tool is used commonly (hm, jay...), please follow this form.
+
+
+
+
+
+
+** Portability tips
+
+Always use the icky Windows /argument way of passing parameters to the C#
+compiler so that csc can be used.
+
+Always use /r:foo.dll, not /r:foo. Windows requires the former.
+
+Use /r:$(corlib), not /r:corlib. Windows wants mscorlib.dll and Linux
+wants corlib.dll; eventually, the Mono runtime is supposed to accept
+mscorlib.dll too, but in the meantime, use the variable.
+
+If you're writing shell script code as part of a make rule, remember
+that Windows has command-line length limits. So something like
+
+========================================
+for f in $(all_the_sources_to_corlib) ; do ....
+========================================
+
+Is probably going to cause problems. Other than that, you can rely on
+fairly advanced (ie, GNU) behaviors from the standard shell utilities,
+since both Cygwin and Linux will be using them.
+
+
+
+
+
+
+** Misc
+
+$(LIBRARY_FLAGS) would be a good place to add /d:DOT_NET_1_1 or whatever
+it is.
+
+A lot of the weird targets in the old makefiles have been dropped; I
+have a feeling that a lot of them are archaic and not needed anymore.
+
+I'd really like to write a build tool in C#. It would be nice to have
+something really extensible and well-designed and clean. NAnt is,
+IMHO, an apalling abomination and a tragically bad attempt at solving
+the software building problem. Just so you know.
+
+(On the other hand, NUnit is really neat.)
+
+Peter
diff --git a/mcs/build/README.platforms b/mcs/build/README.platforms
new file mode 100644
index 00000000000..a323ae7e418
--- /dev/null
+++ b/mcs/build/README.platforms
@@ -0,0 +1,41 @@
+A platform makefile should define the following variables:
+
+PLATFORM_DEBUG_FLAGS
+ The flags to pass to the C# compiler to generate appropriate
+ debug information
+
+PLATFORM_MCS_FLAGS
+ Flags that are always passed to the C# compiler
+
+PLATFORM_RUNTIME
+ The system runtime for executing CLR programs. Blank on Win32,
+ probably $(RUNTIME) (the Mono runtime) on everything else.
+
+PLATFORM_MAKE_CORLIB_CMP
+ Define it to something nonempty if corlib_cmp.dll should be built
+ on this platform. Only should be done if the platform provides its
+ own non-Mono runtime that we can compare corlibs with.
+
+PLATFORM_TWEAK_CORLIB_SOURCES
+ A command to futz around with the sources to corlib.dll. See linux.make
+ and win32.make for examples. Should be 'cat' unless you know what you're
+ doing.
+
+PLATFORM_CHANGE_SEPARATOR_CMD
+ A command to change filename separators given on stdin. Leave undefined
+ if Unixy filenames will work. See win32.make.
+
+BOOTSTRAP_MCS
+ The C# compiler used to compile mcs/mcs.exe, and possibly other
+ assemblies if the user is doing a standalone build (that is, not
+ a bootstrap).
+
+corlib
+ The name of corlib.dll. corlib.dll for the Mono runtime, mscorlib.dll
+ on Win32.
+
+hidden_prefix, hidden_suffix
+ Prefix and suffix for hidden/temporary files. Unused right now, I think.
+
+platform-check:
+ A target to make sure that we can build on this platform.
diff --git a/mcs/build/config-default.make b/mcs/build/config-default.make
new file mode 100644
index 00000000000..3dde4399ded
--- /dev/null
+++ b/mcs/build/config-default.make
@@ -0,0 +1,30 @@
+# -*- makefile -*-
+#
+# This makefile fragment has (default) configuration
+# settings for building MCS.
+#
+# Instead of editing this file, create config.make
+# and override settings there.
+
+RUNTIME_FLAGS =
+TEST_HARNESS = $(topdir)/nunit20/nunit-console/nunit-console.exe
+MCS_FLAGS = $(PLATFORM_DEBUG_FLAGS) /nowarn:1595 /nowarn:0169 \
+ /nowarn:0109 /nowarn:0067 /nowarn:0649 /nowarn:0679
+LIBRARY_FLAGS = /noconfig
+CFLAGS = -g -O2
+INSTALL = /usr/bin/install
+RUNTIME = mono $(RUNTIME_FLAGS)
+TEST_RUNTIME=MONO_PATH="$(topdir)/class/lib:.:$$MONO_PATH" $(RUNTIME) --debug
+prefix = /usr
+
+# In case you want to add MCS_FLAGS, this lets you not have to
+# keep track of the default value
+
+DEFAULT_MCS_FLAGS := $(MCS_FLAGS)
+
+# You shouldn't need to set these but might on a
+# weird platform.
+
+# CC = cc
+# SHELL = /bin/sh
+# MAKE = gmake
diff --git a/mcs/build/executable.make b/mcs/build/executable.make
new file mode 100644
index 00000000000..48ed195fd94
--- /dev/null
+++ b/mcs/build/executable.make
@@ -0,0 +1,71 @@
+# -*- makefile -*-
+#
+# The rules for building a program.
+
+# I'd rather not create a response file here,
+# but since on Win32 we need to munge the paths
+# anyway, we might as well.
+
+sourcefile = $(PROGRAM).sources
+ifdef PLATFORM_CHANGE_SEPARATOR_CMD
+response = $(depsdir)/$(PROGRAM).response
+else
+response = $(sourcefile)
+endif
+stampfile = $(depsdir)/$(PROGRAM).stamp
+makefrag = $(depsdir)/$(PROGRAM).makefrag
+
+all-local: $(PROGRAM)
+
+install-local:
+ $(MKINSTALLDIRS) $(DESTDIR)$(prefix)/bin
+ $(INSTALL_BIN) $(PROGRAM) $(DESTDIR)$(prefix)/bin
+
+clean-local:
+ -rm -f *.exe $(BUILT_SOURCES) $(CLEAN_FILES) $(stampfile) $(makefrag)
+ifdef PLATFORM_CHANGE_SEPARATOR_CMD
+ -rm -f $(response)
+endif
+
+ifndef HAS_TEST
+test-local: $(PROGRAM)
+
+run-test-local:
+endif
+
+DISTFILES = $(sourcefile) $(EXTRA_DISTFILES)
+
+dist-local: dist-default
+ cat $(sourcefile) |xargs -n 20 \
+ $(SHELL) -c 'for f in $$* ; do \
+ dest=`dirname $(distdir)/$$f` ; \
+ $(MKINSTALLDIRS) $$dest && cp $$f $$dest || exit 1 ; \
+ done' dollar0
+
+# Changing makefile probably means changing the
+# sources, so let's be safe and add a Makefile dep
+
+$(PROGRAM): $(makefrag) $(response) $(stampfile)
+ $(CSCOMPILE) /target:exe /out:$@ $(BUILT_SOURCES) @$(response)
+
+$(makefrag): $(sourcefile)
+ @echo Creating $@ ...
+ @echo "HAVE_MAKEFRAG = yes" >$@.new
+ @echo "$(stampfile): $(BUILT_SOURCES) \\" >>$@.new
+ @cat $< |sed -e 's,\.cs[ \t]*$$,\.cs \\,' >>$@.new
+ @cat $@.new |sed -e '$$s, \\$$,,' >$@
+ @echo -e "\ttouch \$$@" >>$@
+ @rm -rf $@.new
+
+ifdef PLATFORM_CHANGE_SEPARATOR_CMD
+$(response): $(sourcefile)
+ cat $< |$(PLATFORM_CHANGE_SEPARATOR_CMD) >$@
+endif
+
+-include $(makefrag)
+
+ifndef HAVE_MAKEFRAG
+$(stampfile):
+ touch $@
+endif
+
diff --git a/mcs/build/library.make b/mcs/build/library.make
new file mode 100644
index 00000000000..60623bbe096
--- /dev/null
+++ b/mcs/build/library.make
@@ -0,0 +1,134 @@
+# -*- makefile -*-
+#
+# The rules for building our class libraries.
+#
+# The NO_TEST stuff is not too pleasant but whatcha
+# gonna do.
+
+# All the dep files now land in the same directory so we
+# munge in the library name to keep the files from clashing.
+
+sourcefile = $(LIBRARY).sources
+ifdef PLATFORM_CHANGE_SEPARATOR_CMD
+response = $(depsdir)/$(LIBRARY).response
+else
+response = $(sourcefile)
+endif
+makefrag = $(depsdir)/$(LIBRARY).makefrag
+stampfile = $(depsdir)/$(LIBRARY).stamp
+the_lib = $(topdir)/class/lib/$(LIBRARY)
+
+ifndef NO_TEST
+test_lib = $(patsubst %.dll,%_test.dll,$(LIBRARY))
+test_sourcefile = $(test_lib).sources
+test_response = $(depsdir)/$(test_lib).response
+test_makefrag = $(depsdir)/$(test_lib).makefrag
+test_stampfile = $(depsdir)/$(test_lib).stamp
+test_flags = /r:$(the_lib) /r:$(topdir)/class/lib/NUnit.Framework.dll $(TEST_MCS_FLAGS)
+endif
+
+all-local: $(the_lib)
+
+install-local: $(the_lib)
+ $(MKINSTALLDIRS) $(DESTDIR)$(prefix)/lib
+ $(INSTALL_LIB) $(the_lib) $(DESTDIR)$(prefix)/lib
+
+clean-local:
+ -rm -f $(the_lib) $(makefrag) $(test_lib) \
+ $(test_makefrag) $(test_response) \
+ $(stampfile) $(test_stampfile) \
+ TestResult.xml
+ifdef PLATFORM_CHANGE_SEPARATOR_CMD
+ -rm -rf $(response)
+endif
+
+ifndef NO_TEST
+test-local: $(the_lib) $(test_lib)
+
+run-test-local:
+ $(TEST_RUNTIME) $(TEST_HARNESS) $(test_lib)
+
+else
+test-local: $(the_lib)
+
+run-test-local:
+endif
+
+DISTFILES = $(sourcefile) $(test_sourcefile) $(EXTRA_DISTFILES)
+
+# just in case you ever wanted to know how to copy a list of 800
+# files without excessively long commandlines...
+#
+# We need dollar0 because $(SHELL) -c interprets arguments as
+#
+# $(SHELL) -c 'the script' $0 $1 $2 ....
+#
+# Ideally we wouldn't use $(test_response) (it'd be nice to make dist
+# with an unbuilt tree), but the -include lines generate the makefrags
+# anyway, so we might as well use them.
+
+dist-local: dist-default $(test_response)
+ cat $(sourcefile) $(test_response) |xargs -n 20 \
+ $(SHELL) -c 'for f in $$* ; do \
+ dest=`dirname $(distdir)/$$f` ; \
+ $(MKINSTALLDIRS) $$dest && cp $$f $$dest || exit 1 ; \
+ done' dollar0
+
+# Fun with dependency tracking
+
+$(the_lib): $(makefrag) $(stampfile) $(response)
+ $(CSCOMPILE) $(LIBRARY_FLAGS) $(LIB_MCS_FLAGS) /target:library /out:$@ @$(response)
+
+$(makefrag): $(sourcefile)
+ @echo Creating $@ ...
+ @echo "HAVE_MAKEFRAG = yes" >$@.new
+ @echo "$(stampfile): \\" >>$@.new
+ @cat $< |sed -e 's,\.cs[ \t]*$$,\.cs \\,' >>$@.new
+ @cat $@.new |sed -e '$$s, \\$$,,' >$@
+ @echo -e "\ttouch \$$@" >>$@
+ @rm -rf $@.new
+
+ifdef PLATFORM_CHANGE_SEPARATOR_CMD
+$(response): $(sourcefile)
+ cat $< |$(PLATFORM_CHANGE_SEPARATOR_CMD) >$@
+endif
+
+-include $(makefrag)
+
+ifndef HAVE_MAKEFRAG
+$(stampfile):
+ touch $@
+endif
+
+# for now, don't give any /lib flags or set MONO_PATH, since we
+# give a full path to the assembly.
+
+ifndef NO_TEST
+$(test_lib): $(test_makefrag) $(the_lib) $(test_response) $(test_stampfile)
+ $(CSCOMPILE) /target:library /out:$@ $(test_flags) @$(test_response)
+
+$(test_response): $(test_sourcefile)
+ @echo Creating $@ ...
+ifdef PLATFORM_CHANGE_SEPARATOR_CMD
+ @cat $< |sed -e 's,^\(.\),Test/\1,' |$(PLATFORM_CHANGE_SEPARATOR_CMD) >$@
+else
+ @cat $< |sed -e 's,^\(.\),Test/\1,' >$@
+endif
+
+$(test_makefrag): $(test_response)
+ @echo Creating $@ ...
+ @echo "HAVE_TEST_MAKEFRAG = yes" >$@.new
+ @echo "$(test_stampfile): \\" >>$@.new
+ @cat $< |sed -e 's,\.cs[ \t]*$$,\.cs \\,' >>$@.new
+ @cat $@.new |sed -e '$$s, \\$$,,' >$@
+ @echo -e "\ttouch \$$@" >>$@
+ @rm -rf $@.new
+
+-include $(test_makefrag)
+endif
+
+ifndef HAVE_TEST_MAKEFRAG
+$(test_stampfile):
+ touch $@
+endif
+
diff --git a/mcs/build/platforms/linux.make b/mcs/build/platforms/linux.make
new file mode 100644
index 00000000000..7bcd93c6443
--- /dev/null
+++ b/mcs/build/platforms/linux.make
@@ -0,0 +1,44 @@
+# -*- makefile -*-
+#
+# Platform-specific makefile rules. This one's for linux.
+#
+
+PLATFORM_DEBUG_FLAGS = -g
+PLATFORM_MCS_FLAGS =
+PLATFORM_RUNTIME = $(RUNTIME)
+
+BOOTSTRAP_MCS = mcs
+corlib = corlib.dll
+
+# Define this if this ever will work on Linux
+# PLATFORM_MAKE_CORLIB_CMP = yes
+
+# This is for the security permission attribute problem
+# on windows
+PLATFORM_TWEAK_CORLIB_SOURCES = cat
+
+# This is for changing / to \ on windows
+# Don't define it so we don't needlessly copy the sources
+# file. This command is handy for testing:
+#
+# PLATFORM_CHANGE_SEPARATOR_CMD=sed -e 's,/,/./,g'
+
+hidden_prefix = .
+hidden_suffix =
+
+platform-check:
+ @if ! type $(BOOTSTRAP_MCS) >/dev/null 2>&1 ; then \
+ echo "*** You need a C# compiler installed to build MCS." ; \
+ echo "*** Read README.building for information on how to bootstrap" ; \
+ echo "*** a Mono installation." ; \
+ exit 1 ; \
+ fi
+
+
+# I tried this but apparently Make's version strings aren't that
+# ... consistent between releases. Whatever.
+#
+# @if ! $(MAKE) --version |grep '^GNU Make version 3' 1>/dev/null 2>&1 ; then \
+# echo "*** You need to build MCS with GNU make. Try \`gmake'" ; \
+# exit 1 ; \
+# fi
diff --git a/mcs/build/platforms/win32.make b/mcs/build/platforms/win32.make
new file mode 100644
index 00000000000..26ef3cbc682
--- /dev/null
+++ b/mcs/build/platforms/win32.make
@@ -0,0 +1,21 @@
+# -*- makefile -*-
+#
+# Win32 platform-specific makefile rules.
+#
+
+PLATFORM_DEBUG_FLAGS = /debug+ /debug:full
+PLATFORM_MCS_FLAGS = /nologo /optimize
+PLATFORM_RUNTIME =
+
+BOOTSTRAP_MCS = csc.exe
+MCS = $(BOOTSTRAP_MCS)
+corlib = mscorlib.dll
+
+PLATFORM_MAKE_CORLIB_CMP = yes
+PLATFORM_TWEAK_CORLIB_SOURCES=cat - corlib.dll.win32-excludes |sort |uniq -u
+PLATFORM_CHANGE_SEPARATOR_CMD=tr '/' '\\\\'
+
+hidden_prefix =
+hidden_suffix = .tmp
+
+platform-check:
diff --git a/mcs/build/profiles/bootstrap.make b/mcs/build/profiles/bootstrap.make
new file mode 100644
index 00000000000..c7c09a13565
--- /dev/null
+++ b/mcs/build/profiles/bootstrap.make
@@ -0,0 +1,18 @@
+# -*- makefile -*-
+#
+# A bootstrap profile -- builds with the internal MCS, even if
+# we're on Windows.
+
+# Note that we have sort of confusing terminology here; BOOTSTRAP_MCS
+# is what allows us to bootstrap ourselves, but when we are bootstrapping,
+# we use INTERNAL_MCS.
+
+# When bootstrapping, compile against our new assemblies.
+# (MONO_PATH doesn't just affect what assemblies are loaded to
+# run the compiler; /r: flags are by default loaded from whatever's
+# in the MONO_PATH too).
+
+MCS = MONO_PATH="$(topdir)/class/lib:$$MONO_PATH" $(INTERNAL_MCS)
+
+# Causes some build errors
+#PROFILE_MCS_FLAGS = /d:NET_1_1
diff --git a/mcs/build/profiles/default.make b/mcs/build/profiles/default.make
new file mode 100644
index 00000000000..51763f3c3af
--- /dev/null
+++ b/mcs/build/profiles/default.make
@@ -0,0 +1,14 @@
+# -*- Makefile -*-
+#
+# The default profile.
+
+# In this profile we compile everything relative to the already-installed
+# runtime, so we use the bootstrap (external) compiler for everything and
+# don't set MONO_PATH.
+
+MCS = $(BOOTSTRAP_MCS)
+
+# Causes some build errors
+#PROFILE_MCS_FLAGS = /d:NET_1_1
+
+# Exciting, no?
diff --git a/mcs/build/profiles/net_1_0.make b/mcs/build/profiles/net_1_0.make
new file mode 100644
index 00000000000..32c5f1bce87
--- /dev/null
+++ b/mcs/build/profiles/net_1_0.make
@@ -0,0 +1,15 @@
+# -*- Makefile -*-
+#
+# Only build .NET 1.0 classes.
+#
+# If we want to combine this with, say, the bootstrap profile,
+# we should create 'bs-net_1_0.make' which includes both.
+#
+# Ideally you could say 'make PROFILE="bootstrap net_1_0"' but
+# that would be pretty hard to code.
+
+include $(topdir)/build/profiles/default.make
+
+PROFILE_MCS_FLAGS = /d:NET_1_0
+
+# done
diff --git a/mcs/build/rules.make b/mcs/build/rules.make
new file mode 100644
index 00000000000..9d882424827
--- /dev/null
+++ b/mcs/build/rules.make
@@ -0,0 +1,119 @@
+# -*- makefile -*-
+#
+# This is the makefile fragment with default rules
+# for building things in MCS
+#
+# To customize the build, you should edit config.make.
+# If you need to edit this file, that's a bug; email
+# peter@newton.cx about it.
+
+# Some more variables. The leading period in the sed expression prevents
+# thisdir = . from being changed into '..' for the toplevel directory.
+
+dots := $(shell echo $(thisdir) |sed -e 's,[^./][^/]*,..,g')
+topdir := $(dots)
+
+VERSION = 0.25.99
+
+USE_MCS_FLAGS = $(LOCAL_MCS_FLAGS) $(PLATFORM_MCS_FLAGS) $(PROFILE_MCS_FLAGS) $(MCS_FLAGS)
+USE_CFLAGS = $(LOCAL_CFLAGS) $(CFLAGS)
+CSCOMPILE = $(MCS) $(USE_MCS_FLAGS)
+CCOMPILE = $(CC) $(USE_CFLAGS)
+BOOT_COMPILE = $(BOOTSTRAP_MCS) $(USE_MCS_FLAGS)
+INSTALL_DATA = $(INSTALL) -m 644
+INSTALL_BIN = $(INSTALL) -m 755
+INSTALL_LIB = $(INSTALL_DATA)
+MKINSTALLDIRS = $(SHELL) $(topdir)/mkinstalldirs
+INTERNAL_MCS = $(RUNTIME) $(topdir)/mcs/mcs.exe
+
+depsdir = $(topdir)/build/deps
+distdir = $(dots)/$(package)/$(thisdir)
+
+# Make sure these propagate if set manually
+
+export PLATFORM
+export PROFILE
+export MCS
+export MCS_FLAGS
+export CC
+export CFLAGS
+export INSTALL
+export MKINSTALLDIRS
+export TEST_HARNESS
+export BOOTSTRAP_MCS
+export DESTDIR
+
+# Get this so the platform.make platform-check rule doesn't become the
+# default target
+
+default: all
+
+# Get initial configuration. pre-config is so that the builder can
+# override PLATFORM or PROFILE
+
+include $(topdir)/build/config-default.make
+-include $(topdir)/build/pre-config.make
+
+# Default PLATFORM and PROFILE if they're not already defined.
+
+ifndef PLATFORM
+ifeq ($(OS),Windows_NT)
+PLATFORM = win32
+else
+PLATFORM = linux
+endif
+endif
+
+ifndef PROFILE
+PROFILE = default
+endif
+
+# Rest of the configuration
+
+include $(topdir)/build/platforms/$(PLATFORM).make
+include $(topdir)/build/profiles/$(PROFILE).make
+-include $(topdir)/build/config.make
+
+# Simple rules
+
+%-recursive:
+ @for d in $(SUBDIRS) ; do \
+ (cd $$d && $(MAKE) $*) || exit 1 ; \
+ done
+
+# note: dist-local dep, extra subdirs, $* has become $@
+
+dist-recursive: dist-local
+ @for d in $(SUBDIRS) $(DIST_ONLY_SUBDIRS) ; do \
+ (cd $$d && $(MAKE) $@) || exit 1 ; \
+ done
+
+# We do this manually to not have a make[1]: blah message (That is,
+# instead of using a '%: %-recursive %-local' construct.)
+
+all: all-recursive all-local
+
+install: install-recursive install-local
+
+test: test-recursive test-local
+
+run-test: run-test-recursive run-test-local
+
+clean: clean-recursive clean-local
+
+# Can only do this from the top dir
+# ## dist: dist-recursive dist-local
+
+# We invert the test here to not end in an error
+# if ChangeLog doesn't exist.
+#
+# Note that we error out if we try to dist a nonexistant
+# file. Seems reasonable to me.
+
+dist-default:
+ -mkdir $(distdir)
+ test '!' -f ChangeLog || cp ChangeLog $(distdir)
+ for f in Makefile $(DISTFILES) ; do \
+ dest=`dirname $(distdir)/$$f` ; \
+ $(MKINSTALLDIRS) $$dest && cp $$f $$dest || exit 1 ; \
+ done