WIP [library.make] Make resource usage declarative in the class libraries (#3159)
[mono.git] / mcs / build / README.makefiles
index fedda941b0073e12dd828845f8f99ea6b12ef093..f5b95a5a32e011e5a092d80d945a1136cbf634ff 100644 (file)
@@ -11,8 +11,7 @@ build system needs to let us do, specifically:
       * Make distributions easily
       * Provide a framework for testing
       * Build platform-independently whenever possible
-
-
+      * Generate, update, and build monodoc documentation.
 
 
 
@@ -23,7 +22,7 @@ A general makefile looks like this:
 ========================================
 thisdir = class/Mono.My.Library
 SUBDIRS =
-include ../../rules.make
+include ../../build/rules.make
 
 all-local:
        do some stuff
@@ -40,24 +39,29 @@ test-local: my_test_program.exe
 run-test-local:
        $(RUNTIME) my_test_program.exe
 
+run-test-ondotnet-local:
+       $(RUNTIME) my_test_program.exe
+
 DISTFILES = myfile.txt my_test_source.cs
 
 dist-local: dist-default
 
+doc-update-local:
+
 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.
+the standard make rules, and provides rules for eight standard targets:
+all, install, test, run-test, clean, dist, and doc-update.
 
 "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:
+The eight 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
@@ -75,13 +79,21 @@ 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.
 
+       * 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.
+
        * clean-local removes built files; 'make clean' should leave
-only files that go into a distribution tarball
+only files that go into a distribution tarball. (But it is not necessarily
+true that all files that go into a tarball need to be left after a make clean.)
 
        * 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.
 
+       * doc-update-local should generate or update monodoc documentation,
+if appropriate.  This is usually only appropriate for libraries.  It's
+defined as a standard target so that it can easily be run recursively
+across all libraries within the module.
+
 
 
 
@@ -91,8 +103,12 @@ target 'dist-default'. See ** 'make dist' below.
 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'.
+whatnot; MCS should be able to build out of the box. We try to keep
+platform detection and feature testing (ie, for HP/UX echo) inside
+the makefiles; right now, there's no configuration script, and it'd
+be nice to keep it that way. (I am told that some people build on
+both Windows and Linux in the same tree, which would be impossible to
+do if we cached platform-related configury values.)
 
 That being said, it's very convenient for developers to be able to
 customize their builds to suit their needs. To allow this, the
@@ -100,11 +116,11 @@ 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
+`rules.make' optionally includes `$(topdir)/build/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
+defined in `$(topdir)/build/platforms/$(PLATFORM).make', where
+$(PLATFORM) is detected in config-default.make. (Currently, the only
 choices are linux.make and win32.make.)
 
 The best way to learn what the configuration variables are is to read
@@ -216,7 +232,7 @@ carefully it can be extremely useful.
 PROGRAM = myprogram.exe
 LOCAL_MCS_FLAGS = /r:System.Xml.dll
 
-include ../executable.make
+include ../build/executable.make
 ========================================
 
 executable.make builds a program in the current directory. Its name is
@@ -237,7 +253,7 @@ test, set the variable HAS_TEST:
 PROGRAM = myprogram.exe
 LOCAL_MCS_FLAGS = /r:System.Xml.dll
 HAS_TEST = yes
-include ../executable.make
+include ../build/executable.make
 
 test-local: mytester.exe
 
@@ -248,6 +264,23 @@ mytester.exe: mytester.cs
        $(CSCOMPILE) /target:exe /out:$@ mytester.cs
 ========================================
 
+If your program has NUnit tests, set the variable HAS_NUNIT_TEST:
+
+========================================
+PROGRAM = myprogram.exe
+LOCAL_MCS_FLAGS = /r:System.Xml.dll
+HAS_NUNIT_TEST = yes
+include ../build/executable.make
+========================================
+
+HAS_NUNIT_TEST tests follow library.make NUnit test conventions: 
+the files should be in a subdirectory called Test/, and if
+your program is called myprogram.exe, they should be listed in
+myprogram_test.dll.sources. The names in that files should *not* have
+the Test/ prefix. 'make test' will build myprogram_test_$(PROFILE).dll 
+in the current directory, automatically supplying the flags to 
+reference the original program and NUnit.Framework.dll. 
+
 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:
@@ -258,7 +291,7 @@ LOCAL_MCS_FLAGS = /r:System.Xml.dll
 BUILT_SOURCES = parser.cs
 CLEAN_FILES = y.output
 
-include ../executable.make
+include ../build/executable.make
 
 parser.cs: parser.jay
        $(topdir)/jay/jay $< > $@
@@ -282,7 +315,7 @@ LIBRARY = Mono.MyLib.dll
 LIB_MCS_FLAGS = /unsafe
 TEST_MCS_FLAGS = /r:System.Xml.dll
 
-include ../../library.make
+include ../../build/library.make
 ========================================
 
 Where you library is called $(LIBRARY); it will be put into
@@ -312,7 +345,7 @@ LIBRARY = Mono.MyLib.dll
 LIB_MCS_FLAGS = /unsafe
 NO_TEST = yes
 
-include ../../library.make
+include ../../build/library.make
 ========================================
 
 and feel ashamed. Every good library has a test suite!
@@ -355,6 +388,14 @@ 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.
 
+library.make also automatically supports generating and updating 
+monodoc documentation.  Documentation is stored within the 
+Documentation directory (a sibling to the Test directory), and is 
+generated/updated whenever the doc-update target is executed.  
+Assembling of the documentation so that the monodoc browser can
+display the documentation is handled separately within the mcs/docs
+all-local target; see mcs/docs/Makefile for details.
+
 
 
 
@@ -372,7 +413,8 @@ 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.
 
-
+$(TEST_RUNTIME) is the runtime to use when running tests. Right now it's
+just "mono --debug".
 
 
 
@@ -394,6 +436,29 @@ To give it flags, set $(LOCAL_CFLAGS). As with compiling C#, the
 variable $(CFLAGS) will automatically be included on the command line.
 
 
+* Compiling resources with resgen
+
+If you have a resource that should be compiled with resgen and
+included in your assembly, you can use the RESOURCES_DEFS variable.
+This variable can contain lists of pairs that are separated by comma
+to represent the resource ID as embedded in the assembly followed by
+the file name, like this:
+
+RESOURCE_DEFS = Messages,TextResources.resx Errors,ErrorList.txt
+
+
+* Documentation-related needs? Use $(MDOC)
+
+$(MDOC) is a front-end to the monodoc documentation system, supporting
+documentation generation, updating, importing from Microsoft XML
+Documentation and ECMA documentation formats, assembling documentation
+for use within the monodoc documentation browser, and exporting
+documentation to various other output formats such as static HTML.
+
+It is currently only used for library.make's doc-update-local target
+and for assembling documentation within $topdir/docs.
+
+
 
 
 
@@ -423,7 +488,7 @@ consistently.
 
 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
+they exist. This is almost always all that you need, so ideally your
 make dist support should only be:
 
 ========================================
@@ -552,71 +617,81 @@ class/Mono.MyFancyLib/Makefile
 thisdir = class/Mono.MyFancyLib
 SUBDIRS =
 DIST_ONLY_SUBDIRS = MyFancyDemo
-include ../../rules.make
+include ../../build/rules.make
 
 LIBRARY = Mono.MyFancyLib.dll
 LIB_MCS_FLAGS = /r:System.dll
 TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
 
-include ../../library.make
+include ../../build/library.make
 ========================================
 
 class/Mono.MyFancyLib/MyFancyDemo/Makefile
 ========================================
 thisdir = class/Mono.MyFancyLib/MyFancyDemo
 SUBDIRS =
-include ../../../rules.make
+include ../../../build/rules.make
 
 PROGRAM = FancyDemo.exe
 LOCAL_MCS_FLAGS = /r:gtk-sharp.dll
 
-include ../../../executable.make
+include ../../../build/executable.make
 ========================================
 
 
 
 
+* Special recursion needs?
 
+By default, rules.make defines the all, install, clean, etc. targets
+to look something like this:
 
-** A few implementation details
+   all: all-recursive
+       $(MAKE) all-local
 
-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:
+Sometimes that doesn't cut it; say for example you want to check for
+something before doing a lengthy recursive build (see
+$(topdir)/Makefile) or you have a something like this
 
-========================================
-thisdir = directory/subdir
-SUBDIRS = 
-include ../../rules.make
+       class/MyLibrary:
+               Build MyLibrary.dll
+       class/MyLibrary/Test:
+               Build TestMyLibrary.exe
 
-all-local: myfoo.exe
+'make clean test' will fail here, because the build will happen in
+the Test subdirectory first, so there will be no MyLibrary.dll to link
+against. (Unless you write a nasty evil relative path rule which is
+strongly discouraged.)
 
-myfoo.exe: ../libfoo.dll
-       $(CSCOMPILE) ...
+Anyway, to solve this problem you can do
 
-../libfoo.dll:
-       cd .. && $(MAKE) libfoo.dll
 ========================================
+thisdir = class/MyLibrary
+SUBDIRS = Test
+include ../../build/rules.make
 
-Alternatively, I think I could add support so that you could do this:
+# Normally, make runs 'all-recursive' first, and then 'all-local'
+# With this, we ensure that 'all-local' is executed first.
+all-recursive: all-local
 
+test-recursive: test-local
+...
 ========================================
-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.
+
+
+** 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. If this is a problem,
+see the previous section.  Note that the recursive rule for 'dist' is
+different; it makes dist-recursive in subdirectories, so you at least
+have to define that rule.
 
 Note that even a directory that doesn't, for example, have any tests
 must still define test-local; otherwise 'make test' run from the
@@ -627,7 +702,7 @@ toplevel directory will break.
 
 
 
-** Flags
+** Flags for Tools
 
 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
@@ -639,9 +714,14 @@ FLAGS variables:
        * $(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).
+       * $(PLATFORM_foo_FLAGS) is set in the platform configuration
+         to provide platform-specific values.
+
+       * $(PROFILE_foo_FLAGS) is set in the profile configuration
+         to provide profile-specific values.
+
+       * $(USE_foo_FLAGS) is defined to be the combination of all of
+         the above, 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.
@@ -658,20 +738,26 @@ 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.
+Use /r:$(corlib), not /r:corlib.
 
 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 ....
+mytool $(all_the_sources_to_corlib)
+========================================
+
+Is probably going to cause problems. As I understand it, 
+
+========================================
+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.
+is ok, since the shell itself doesn't have those limitations. Other
+than that, you should still try to write fairly portable shell
+script. Linux and Cygwin both use the GNU utilities, but there's at
+least one hardy soul trying to build Mono on HP/UX, and no doubt there
+will be ports to more Unices as time goes on.
 
 
 
@@ -680,8 +766,17 @@ 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.
+We still don't use /d:NET_1_1 ; it causes some build problems right
+now.
+
+There's a hack in class/System.Data/Makefile to work around a very
+strange crash in the runtime with some custom attribute stuff. It'd be
+nice to fix it.
+
+Also, there's a /lib:$(prefix)/lib in the System.dll Makefile, which
+is for some reason necessary if System.Xml.dll hasn't been built yet.
+(Well, it's necessary because of the /r:System.Xml.dll, but that
+should be in the search path, it seems.)
 
 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.