# Aros/Developer/BuildSystem

* Navbar for the Aros wikibook
* Aros User
* Aros User Docs
* Aros User FAQs
* Aros User Applications
* Aros User DOS Shell
* Aros/User/AmigaLegacy
* Aros Dev Docs
* Aros Developer Docs
* Porting Software from AmigaOS/SDL
* For Zune Beginners
* Zune .MUI Classes
* For SDL Beginners
* Aros Developer BuildSystem
* Specific platforms
* Aros x86 Complete System HCL
* Aros x86 Audio/Video Support
* Aros x86 Network Support
* Aros Intel AMD x86 Installing
* Aros Storage Support IDE SATA etc
* Aros Poseidon USB Support
* x86-64 Support
* Motorola 68k Amiga Support
* Linux and FreeBSD Support
* Windows Mingw and MacOSX Support
* Android Support
* Arm Raspberry Pi Support
* PPC Power Architecture
* misc
* Aros Public License

#### Overview

AROS uses several custom development tools in its build-system to aid developers by providing an easy means to generate custom makefiles for amigaos like components.
The most important ones are:
* MetaMake: A make supervisor program. It can keep track of targets available in makefiles available in subdirectories a certain root directory. A more in depth explanation is given below.
* GenMF: (generate makefile) A macro language for makefiles. It allows to combine several make rules into one macro which can simplify writing makefiles.
* Several AROS specific tools that will be explained more when appropriate during the rest of this documentation.

#### MetaMake
##### Introduction

MetaMake is a special version of make which allows the build-system to recursively build "targets" in the various directories of a project, or even another project.
The name of the makefile's used is defined in the MetaMake config file and defaults to makefile for AROS – so we shall use this name to donate MetaMake Makefiles from here on in.
MetaMake searches directory tree's for mmakefiles – and, for each it finds, process's the metatargets.
You can also specify a program which converts "source" mmakefiles (aptly named mmakefile.src) into proper mmakefile's before MetaMake will be invoked on the created mmakefile.

###### MetaTargets

MetaMake uses normal makefile syntax but gives a special meaning to a comment line that start with #MM. This line is used to define so called metatargets.
There exist three ways of defining a metatarget in a makefile:

###### Virtual MetaTargets
##### How MetaMake works

MetaMake is run with a metatarget to be built specified on the command line.
MetaMake will first build up a tree of all the mmakefiles present in a directory and all subdirectories (typically from the aros source base directory) – and autogenerate them where applicable. While doing this it will process the mmakefiles and build a tree of all the defined metatargets and their dependencies.
Next it will build all the dependencies (metaprerequisites) needed for the specified metatarget – and finally the metatarget itself.
metaprerequisite are metatarget's in their own rite – and are processed in the same fashion so that dependancies they have are also fulfilled.
For each metatarget, a walk through of all the directories is done – and in every mmakefile where Real MetaTarget's are defined, make is called with the name of the target as a "make target".

###### Exported variables

When MetaMake calls normal make, it also defines two variables...

###### Autogenerating mmakefile's

Another feature of MetaMake is automatic generation of mmakefile's from a source mmakefile's.
When the directory tree is scanned for mmakefiles, ones with a .src suffix that are newer then any present mmakefile are processed using a specified script that regenerate's the mmakefile from the source mmakefile. The called script is defined in the configuration file.

##### Examples

The next few examples are taken from the AROS project.

###### Example 1: normal dependencies

This example says that in this makefile a contrib-regina-module is present that has to be build but the before building this metatarget first the metatargets setup, linklibs, ... has to be build; e.g. that the includes linklibs etc. have to be present before that this module can be build.

###### Example 2: metatarget consisting of submetatargets

Here actually is said that the contrib-freetype metatarget consists of building linklib, graph, fonts and demos of freetype. If some extra work needs to be done in the makefile where this metatarget the definition can start with '#MM ' and a normal make target 'contrib-freetype' has to be present in the makefile.
Also the use of the line continuation for the metatarget definition is shown here.

###### Example 3: Quick building of a target

When a user executes MetaMake with workbench-utilities as an argument, make will be called in all the directories where the metaprerequisites are present in the makefile. This can become quite annoying when debugging programs. When now the second metatarget workbench-utilities-quick is defined as shown above only that target will be build in this directory. Of course the user has then to be sure that the metatargets on which workbench-utilities depend are up-to-date.

##### Usage and configuration files

Usage: mmake [options] [metatargets]
To build mmake, just compile mmake.c. It doesn't need any other files.
mmake looks for a config file mmake.config or .mmake.config in the current directory for a file in the environment variable $MMAKE_CONFIG or a file .mmake.config in the directory $HOME.
This file can contain the following things:
    This must be the first character in a line and begins a comment.
    Comments are completely ignored my mmake (as are empty lines).

###### text="[<name>]"

    This begins a config section for the project name. You can build
    targets for this project by saying name.target.

###### maketool <tool options...>

    Specifies the name of the tool to build a target. The default is
    make "TOP=$(TOP)" "CURDIR=$(CURDIR)".

###### top <dir>

    Specifies the root directory for a project. You will later find
    this config option in the variable $(TOP). The default is the
    current directory.

###### defaultmakefilename <filename>

    Specifies the basename for makefiles in your project. Basename means
    that mmake will consider other files which have this stem and an
    extension, too. See the items to generate makefiles for details.
    The default is Makefile.

###### defaulttarget <target>

    The name of the default target which mmake will try to make if you
    call it with the name of the project alone. The default is all.

###### genmakefilescript <cmdline...>

    mmake will check for files with the basename as specified in
    defaultmakefilename with the extension .src. If such a file is found,
    the following conditions are checked: Whether this file is newer than
    the makefile, whether the makefile doesn't exist and whether the file
    genmakefiledeps is newer than the makefile. If any of these is true,
    mmake will call this script the name of the source file as an extra
    option and the stdout of this script will be redirected to
    defaultmakefilename. If this is missing, mmake will not try to
    regenerate makefiles.

###### genmakefiledeps <path>

    This is the name of a file which is considered when mmake tries to
    decide whether a makefile must be regenerated. Currently, only one
    such file can be specified.

###### globalvarfile <path>

    This is a file which contains more variables in the normal make(1)
    syntax. mmake doesn't know about any special things like line
    continuation, so be careful not to use such variables later (but
    they don't do any harm if they exist in the file. You should just
    not use them anywhere in mmake).

###### add <path>

    Adds a nonstandard makefile to the list of makefiles for this
    project. mmake will apply the standard rules to it as if the
    defaultmakefilename was like this filename.

###### ignoredir <path>

    Will tell mmake to ignore directories with this name. Try ignore
    CVS if you use CVS to manage your projects' sources.
    Any option which is not recognised will be added to the list of known variables (ie. foo bar will create a variable $(foo) which is expanded to bar).
Example
Here is an example:
A metatarget look like so: project.target. Example: AROS.setup. If nothing is specified, mmake will make the default target of the first project in the config file. If the project is specified but no target, mmake will make the default target of this project.

#### GenMF
##### Introduction

Genmf uses two files for generating a mmakefile. First is the macro definition file and finally the source mmakefile where these macro's can be used.
In general the % character is used as the special character for genmf source makefiles.
After ./configure i run the make command and that halts with an error from within the genmf.py script that is cannot find some file. the files that are fed to the genmf.py script seem to be lines in the /tmp/genmfxxxx file. the problem is that the lines are not created right. so when the lines are fed to the genmf.py script it cannot handle it.
Metamake creates tmpfiles:
Metamake actually calls genmf.py to generate the genmf file. It is located in bin/$(arch)-$(cpu)/tools
MetaMake uses time stamps to find out if a mmakefile has changed and needs to be reparsed. For mmakefiles with dynamic targets we would have to avoid that time stamp comparison.
This is I think only the case if the metarules would change depending on an external config file without that the mmakefile itself changes.
But this reminds me another feature I had in mind for mmake. I would make it possible to have real files as prerequisites of metatargets. This is to avoid that make is called unnecessary in directories. I would introduce a special character to indicate if a metatarget depends on a file, let's take @ and have the following rule
This would indicate that for this mmakefile metatarget 'bar' only has to be build if file foo changes. So if mmake wants to build metatarget 'bar' if would only call make if file foo in the same directory as the mmakefile has changed.
This feature would also be able to indicate if the metarules have to be rebuild, I would allocate the special __MM__ metatarget for it. By default always the implicit metarule would be there:
But people could add config files is needed:
Does MetaMake really do variable substitution? Yes, have a look in the var.c file.
The generated mmakefile for Demos/Galaxy still has #MM- demo-galaxy : demo-galaxy-$(AROS_TARGET_CPU) and I think the substitution is done later by Gnu/Make.
No, for gmake it is just a comment line; it does not know anything about mmake. And it also the opposite case; mmake does not know anything about gmake it just all the lines starting with #MM. So the next thing does not what you think it does in a gmake file:
mmake will see both lines as just ignores the if statement ! It will complain if it does not know target. That is one of the main reasons I proposed the above feature.
The main feature of mmake is that is allows for modular directory structure you can add or delete directories in the build tree and metamake will automatically update the metarules and the build itself to the new situation. For example it would allow to checkout only a few subdirectories of the ports directory if one wants to work on one of the programs there.

##### Macro definition

A macro definition has the following syntax:
macroname is the name of the macro. option1, option2, ... are the arguments for the macro. These options can be used in the body of this template by typing %(option1). This will be replaced be the value of option1.
The macro can be followed by a default value. If no default value is specified an empty string is taken. Normally no space are allowed in the default value of an argument. If this is needed this can be done by surrounding the value with double quotes (").
Also two switches can be given:

##### Macro instantiation

The instantiation of the macro is done by using the '%' character followed by the name of the macro to instantiate (without a round brackets around it):
Two ways are possible to specify value for arguments to a macro:
When giving values to arguments also double quotes need to be used if one wants to include spaces in the values of the arguments.
Macro instantiation may be used inside the body of a macro, even macro's that will only be defined later on in the macro definition file. Examples
FIXME (whole rules to be shown as well as action to be used in make rules)

## AROS Build-System usage
#### AROS Build-System configuration

Before the build-system can be invoked via make – you will need to run "./configure" to set up the environment for your chosen target platform
i.e.
./configure --target=pc-i386
This causes the configure script to perform the following operations ...

#### AROS MetaMake configuration file

[add the default settings for mmake]

#### Default AROS MetaMake MetaTargets

AROS uses a set of base metatargets to perform all the steps needed to build the tools and components not only used to compile aros but also that make up aros itself

##### AROS Build MetaMake MetaTargets

[list standard metatargets used during the build process]

##### Special AROS MetaMake MetaTargets
#### Default AROS mmakefile Variables

The following variables are defined for use in mmakefile's.

#### AROS mmakefile.src High-Level Macros

Note : In the definition of the genmf rules sometimes mmake variables are used as default variables for an argument (e.g. dflags=%(cflags)). This is not really possible in the definition file but is done by using text that has the same effect.
Building programs
There are two macro's for building programs. One macro %build_progs that will compile every input file to a separate executable and one macro %build_prog that will compile and link all the input files into one executable.

##### %build_progs

This macro will compile and link every input file to a separate executable and has the following definition:
With the following arguments:

###### mmake=/A

    This is the name of the metatarget that will build the programs.

###### files=/A

    The basenames of the C source files that will be compiled and
    linked to executables. For every name present in this list an
    executable with the same name will be generated.

###### objdir=$(GENDIR)/$(CURDIR)

    The directory where the compiled object files will be put.

###### targetdir=$(AROSDIR)/$(CURDIR)

    The directory where the executables will be placed.

###### cflags=$(CFLAGS)

    The flags to add when compiling the .c files. By default the
    standard AROS cflags (the $(CFLAGS) make variables are taken.
    This also means that some flags can be added by assigning these
    to the USER_CFLAGS and USER_INCLUDES make variables before
    using this macro.

###### dflags=%(cflags)

    The flags to add when doing the dependency check. Default is
    the same as the cflags.

###### ldflags=$(LDFLAGS)

    The flags to use when linking the executables. By default the
    standard AROS link flags will be used.

###### uselibs=

    A list of static libraries to add when linking the executables.
    This is the name of the library without the lib prefix or the .a
    suffix and without the -l prefix for the use in the flags
    for the C compiler.
    By default no libraries are used when linking the executables.

###### usehostlibs=

    A list of static libraries of the host to add when linking the
    executables. This is the name of the library without the lib prefix
    or the .a suffix and without the -l prefix for the use in the flags
    for the C compiler.
    By default no libraries are used when linking the executables.
    usestartup=yes
    Use the standard startup code for the executables. By default this
    is yes and this is also what one wants most of the time. Only disable
    this if you know what you are doing.

###### detach=no

    Wether the executables will run detached. Defaults to no.

##### %build_prog

This macro will compile and link the input files to an executable and has the following definition:
With the following arguments:

##### %build_linklib

Building static linklibraries
Building link libraries is straight forward. A list of files will be compiled or assembled and collected in a link library into a specified target directory.
The definition of the macro is as follows:
With the meaning of the arguments as follows:

##### %build_module

Building modules consists of two parts. First is a macro to use in mmakefile.src files. Another is a configuration file that describes the contents of the module.

###### The mmakefile.src macro

This is the definition header of the build_module macro:
Here is a list of the arguments for this macro:

###### The module configuration file

The module configuration file is subdived in several sections. A section is defined with the following lines:
The interpretation of the lines between the ##begin and ##end statement is different for every section. The following sections are defined:

##### %build_module_macro

Building modules (the legacy way)
Before the %build_module macro was developed already a lot of code was written. There a mixture of macro's was usedin the mmakefile and they were quite complicated. To clean up these mmakefiles without needing to rewrite too much of the code itself a second genmf macro was created to build modules that were written using the older methodology. This macro is called build_module_macro. For writing new modules people should consider this macro as deprecated and only use this macro when the %build_module doesn't support the module yet they want to create.

###### The mmakefile.src macro

This is the definition header of the build_module_macro macro:
Here is a list of the arguments for this macro:

###### The module configuration file

For the build_module_macro two files are used. First is the module configuration file (modname.conf or lib.conf) and second is the headers.tmpl file.
The modules config file is file with a number of lines with the following syntax:

###### The header.tmpl file

Contrary to the %build_module macro for %build_module_macro the C header information is not included in the configuration file but an additional files is used with the name headers.tmpl. This file has different section where each of the sections will be copied in a certain include file that is generated when the module is build. A section has a structure as follows:
With sectionname one of the following choices:

##### %build_archspecific

Compiling arch and/or CPU specific files
In the previous paragraph the method was explained how a module can be build with the AROS genmf macro's. Sometimes one wants to replace certain files in a module with an implementation only valid for a certain arch or a certain CPU. The macro definition
Arch specific files are handled by the macro called %build_archspecific and it has the following header:
And the explanation of the argument to this macro:

##### %rule_archalias

Code shared by different ports
A second macro called %rule_archalias allows to create a virtual architecture. And code for that virtual architecture is shared between several architectures. Most likely this is used for code that uses an API that is shared between several architecture but not all of them.
The macro has the following header:
    %define rule_archalias mainmmake=/A arch=/A alias=/A
With the following arguments
    mainmmake=/A
       The mmake of the module from which one wants to replace files, or
       which to add additional files to.
    arch=/A
       The arch one wants to make alias from.
    alias=/A
       The arch one wants to alias to.
Examples
1. This is an extract from the file config/linex/exec/mmakefile.src that replaces the main init.c file from exec with a linux specialized one:
2. For the dos.library some arch specific files are grouped together in the unix arch. The following lines are present in the several mmakefiles to make this possible
In config/linux/mmakefile.src:
In config/freebsd/mmakefile.src:
And finally in config/unix/dos/mmakefile.src:

#### AROS mmakefile.src Low-Level Macros
### Libraries

A simple library that uses a custom suffix (.wxt), and returns TRUE in its init function, however the Open code never gets called – and openlibrary fails? (the init function does get called though..) With a conf file with no ##functionlist section I get the error: In readref: Could not open (null)
Genmodule tries to read a ref file when no ##functionlist section is available. After adding a dummy function to the conf file it worked for me. Take care: haven't added any flags which avoids creating of header files and such. How to deal with library base pointers in plug-ins when you call library functions.
use only one function -> called to make the "plugin" register all its hooks with wanderer. Iterate through the plugin directory, and for each file ending ".wxt", create an internal plugin structure in which i store the pointer to the libbase of the OpenLibrary'd plugin. After enumerating the plugins, iterate the list of plugin structs and call the single library function which causes them to all register with wanderer. had been using some of the struct library fields (lib_Node.ln_Name was the culprit).
We should remove the dos.c, intuition.c, etc. files with hardcoded version numbers from autoinit and replace them with -ldos -lintuition inside gcc specs file. This would avoid starting programs on older versions of libraries. If an older version suffice some __xxx_version global can be defined in the program code to enable this. We could also provide based on the info you described below exec_v33 exec_v45 link libraries that would also make sure no function of a newer version is used. A very clean solution to get the desired effect.
-noarosc mentions checking the spec file to find out about it but there is nothing in the specs file related. This was added to disabled automatic linking of arosc to all libraries. It was used in the build_library macro – check V0. Automatic linking of arosc.library which had per task context to other libraries which had global context was a very bad thing. "C standard library" objects belonging to global context library were allocated on opening task context. When the task exited and global context library not, global context library was using "freed" memory.
A note to any of you wanting to upgrade to Ubuntu 12.10, or any distribution that uses gcc 4.7. There is an issue (bug? misfeature?) in gcc 4.7 where the '-specs /path/to/spec/override' is processed *after* gcc checks that it has been passed valid arguments. This causes gcc to fail with the error:
gcc-4.7: error: unrecognized command line option "-noarosc"
when it is used to link programs for the x86 and x86_64 targets if you are using the native host's compiler (for example, when compiling for linux-x86_64 hosted). Please use gcc-4.6 ("export CC=gcc-4.6") for hosted builds until further notice (still valid as of March 2013).

#### Per task

There are other things for which arosc.library needs to be per task based: autoclosing of open files and autofreeing of malloced memory when a programs exits; a per task errno and environ variable that can be changed by calling library functions.
regina.library does also do that by linking with arosc_rel. It needs some more documentation to make it usable by other people. You can grep aroscbase inside the regina source code to see where it is used. regina.library and arosc.library are per task libraries. Each time regina.library is opened it also opens arosc.library and it then gets the same libbase as the program that uses regina.library.
By linking with arosc_rel and defining aroscbase_offset arosc.library functions called from regina.library will be called with the arosc libbase stored in it's own libbase, and the latter is different for each task that has opened regina.library.
The AROS_IMPORT_ASM_SYM of aroscbase in the startup section of regina.conf assures that the arosc.library init functions are called even if the programs that uses regina.library does not use an arosc.library function itself and normally would not auto-open it.
Problem is that both bz2 and z library use stdio functions. The arosc.library uses the POSIX file descriptors which are of type int to refer to files. The same file descriptor will point to different files in different tasks. That's why arosc.library is a pertask library. FILE * pointer internally have a file descriptor stored that then links to the file.
Now bz2 and z are using also stdio functions and thus also they need a different view for the file descriptors depending in which program the functions are called from. That's why bz2 and z become also pertask libraries.
it breaks POSIX compatibility to use a type other than int for file descriptors. Would a better solution be to assign a globally unique int to each file descriptor, and thus avoid the need to make arosc.library a per-task library? far simpler solution – all DOS FileHandles and FileLocks are allocated from MEMF_31BIT. Then, we can be assured that their BPTRs fit into an int.
you will most likely kill the 64-bit darwin hosted target. AFAIR it has 0 (zero) bytes of memf_31bit memory available.
Must modules which are using pertask libraries be implemented itself as pertask library? Is it a bug or feature that I get now the error about missing symbolsets handling. You will now see more verbose errors for missing symbol sets, for example:
By linking with jpeg and arosc, instead of jpeg_rel and arosc_rel, it was pulling in the PROGRAM_ENTRIES symbolset for arosc initialization. Since jpeg.datatype is a library, not a program, the PROGRAM_ENTRIES was not being called, and some expected initialization was therefore missing.
It is the ctype changes that is causing the problem. This code now uses ADD2INIT macro to add something to initialization of the library. As you don't handle these init set in your code it gives an error. You can for now use -larosc.static -larosc or implement init set handling yourself.
The move to ctype handling is that in the future we may want to have locale handling in the C library so toupper/tolower may be different for different locales. This was not possible with the ctype stuff in the link lib. Ideally in the source code sqlite3-aros.c would be replaced with sqlite3.conf and genmodule would be called from makefile-new
* strongly* recommend that you *not* use %build_module_simple for pertask/peropener libraries for now. There is a PILE of crap that genmodule needs to do *just*exactly*right* to get them to work, and that pile is still in flux at the moment.
Use %build_module, and add additional initialization with the ADD2* family of macros.
If you insist on %build_module_simple, you will need to link explicitly with libautoinit.
To handle per-task stuff manually:
You can get the task-specific data in one of your routines, using GetTaskStorageSlot.
if you're not using the stackcall API, that's the general gist of it.
would recommend that you use the static libraries until the pertask/peropener features have stabilized a bit more. You can always go back to dynamic linking to pertask/peropen libs later.
You should be able to use arosc.library without needing to be pertask. Things gets more complicated if code in library uses file handles, malloc, errno or similar things.
Is the PROGRAM_ENTRIES symbolset correct for arosc initialization then, or should it be in the INIT set? If so move the arosc_startup.c to the INIT set.
Think about datatypes. Zune (muimaster.library) caches datatype objects. Task A may be the one triggering NewDtObject. Task B may be the one triggering DisposeDTObject.
NewDTObject does OpenLibrary of say png.datatype. DisposeDTObjec does CloseLibrary of say png.datatype.
If png.datatype usees some pertask z.library that's a problem, isn't it? As png.datatype is not per opener and is linked with arosc there should only be a problem when png.datatype is expunged from memory not when opened or closed. It will also use the arosc.library context from the task that calls the Init function vector of png.datatype and it will only be closed when the Expunge vector is called.

#### relbase

* library.conf: relbase FooBase -> rellib foo
* rellib working for standard and peropener/pertask libraries
* <proto/foo.h> automatically will use <proto/foo_rel.h> if 'rellib foo' is used in the libraries .conf
* "uselibs" doesn't need to manually specify rellib libraries
arosc_rel.a is meant to be used from shared libraries not from normal programs. Auto-opening of it is also not finished, manual work is needed ATM.
z_au, png_au, bz2_au, jpeg_au, and expat_au now use the relbase subsytem. The manual init-aros.c stub is no longer needed. Currently, to use relative libraries in your module, you must:
* Enable 'options pertaskbase' in your library's .conf
* Add 'relbase FooBase' to your library's .conf for each relative library you need.
* Make sure to use the '<proto/foo_rel.h>' headers instead of '<proto/foo.h>'
* Link with 'uselibs=foo_rel'
can't find a valid way to implement peropener libraries with 'stack' functions without a real ELF dynamic linker (ie ld-linux.so). The inherent problem is determining the where the 'current' library base is when a stack function is called.
(In the following examples, assume stack.library is a peropener library, and StackFunc is a stack style function in that library. plugin.library uses stack.library)
Example 1 – Other libraries doing weird things behind your back
Ok, to fix that issue, let's suppose we use a stub wrapper that sets the taskslot to the (global) library base. This was no problem with old implementation. StackBase was passed in the scratch register StackFunc each time it was called. This base was then used.
Example 2 – Local vs Global bases
Hmm. Ok, that behavior is going to be a little weird to explain to developers. I don't see the need to support local bases.
Example 3 – Callback handlers
Function pointers to functions in a peropener library may be a problem but is it needed ?
All in all, until we have either
* a *real* ELF shared library subsystem
or
* real use case for peropener libraries. C split arosstdc.library is peropener base. Reasoning is that you
may sometimes want to do malloc in a library that is not freed when the Task that happened to call function is exiting. Let's say picture caching library that uses ported code which internally uses malloc. If you have a pertask library the malloc will allocate memory on the Task that currently is calling the library and this memory will disappear when this task quits (should do free prior exit). Before your change the caching library could just link with libarosstdc.a (and not libarosstdc_rel.a) and it worked.
idea could be to either link(*) or unlink(**) the malloc to a given task, depending on from where it is called (within library or not). No, the whole point is to have the malloced memory _not_ to be attached to a task so a cached image can be used from different tasks even if the first task already died.

#### static

call the static link library for the static version for the few shared libraries that need it different, like libz_static.a Ideally all code should just work with the shared library version.
usestartup=no and the '-noarosc' LDFLAG both imply arosc.static (it doesn't hurt to link it, and if you really want arosc.library, that will preempt arosc.static)
Again this will make -lz not link with the shared library stubs. IMO uselibs=z should use shared library by default.
if there's a dynamic version of a library, it should always be used: static linking of libraries should be discouraged for all the usual reasons, e.g. the danger of embedding old bugs (not just security holes), bloat etc. Don't see the need for a -static option (or any other way to choose between static and dynamic libraries).

### Makedepend

AROS build system generates for each .c file a .d file where the includes are listed. The .c is recompiled when any of the includes changes. Remember that AROS is an OS in development so we often do/did changes to the core header files. If this makedepend was not done programs would not be rebuilt if changes are made to AROS libraries or other core code. OK, so it's basically creating the dependencies of the .o

### mmakefile

We do get an error from it, so something is in fact going wrong. But what is?
Probably a hacky mmakefile so that include file is not found during makedepend but is found during compilation or maybe a wrong dependency so it is not guaranteed that the include file is there during makedepend. And I do think it would be better if the build would stop when such an error occurs.

### configuration files

We are talking about configuration files for modules like this: rom/graphics/graphics.conf.
I have been thinking about similar things, but first I would like to convert our proprietary .conf format to xml. Manually writing file parsings is so passe :)
Uhh.. I have no objection to using a 'standard' parser, but I have to vote no on XML *in specific*.
JSON or YAML (summaries of both are on Wikipedia) are available would be better choices, since they are much more human readable, but semantically equivalent to XML.
I agree that xml is not the easiest format to edit in a text editor and is quite bloated. From the other side it has ubiquitous in scripting and programming language and in text editors and IDEs. I also like that the validity of a xml file can be checked through a schema file and that it also can be a guide for the editor. There are also tools to easily convert xml files based on this schema etc. It does not matter what format it is in but it should take as much coding away from the (genmodule) programmer.
Another improvement over XML could be the inclusion of literal code. Currently some literal code snippets are included in .conf file and in XML they would need some character encoding. How is this for JSON or YAML ?
YAML supports UniCode internally. I don't know how well that could be ported to AROS though since it seems AROS doesn't have UniCode support yet. JSON is based on JavaScript notation and YAML 1.2 can import JSON files as it implemented itself as a complete super-set of JSON. YAML's only 1.2 implementation is in C++ using CMake as a build script creator. If we use the C implementation of libYaml, it's only YAML 1.1 compliant and loses the backward compatibility to JSON.
Any data languages can be checked against a scheme; it's mostly a matter of writing out the schemes to check against. You can but my questions if the tools exists. From the second link you provided: "There are a couple of downsides to YAML: there are not a lot of tools available for it and it’s also not very easy to validate (I am not aware of anything similar to a DTD or a schema)". I find validation/syntax checking as important as human readability. Syntax checking is in the parsing in all four cases. The validation the XML can do is whether it conforms to the parsing and whether it conforms to a specific scheme. YAML and JSON are specifically intended for structured data, en I guess my example is too, so the equivalent XML scheme would check whether the content was correctly structured for structured data. The other three don't need that as anything they parse is by definition structured data.
All four have the same solution: They are all essentially tree builders, and you can walk the tree to see if each node conforms to your content scheme. The object is to use a defined schema/DTD for the files that are describing a library. Text editors that understand schemas can then let you only add fields that are valid by the schema. So this schema let everyone validate a XML if it is a valid XML library description file; they can use standard tools for that.
AFAICS JSON and YAML parsers only validate if the input file is a valid JSON/YAML file, not that it is a valid JSON/YAML library description file. AFAICS no such tools exist for these file formats.

### ETask Task Storage

Location of the TaskStorage slots
It was important to me that the address of the ETask does not change. For example, it would be pretty bad if code like this broke:
Also, I wanted to minimize the number of places that need to be modified if the TaskStorage location needed to be moved (again).
et_TaskStorage is automatically resized by Exec/SetTaskStorageSlot as needed, and a new ETask's et_TaskStorage is cloned from its parent, if the parent was also an ETask with et_TaskStorage. What I wanted to say here is that some overhead may be acceptable for SetTaskStorageSlot if properly documented. E.g. to not call the function in time critical paths.
You clone Parent TaskStorage when creating a subtask as before. This may be acceptable if it is documented that a slot allocated in the parent may not be valid in child if it is allocated in parent after the child has been created. For other use cases think it acceptable to have to be sure that in a Task first a SetStorageSlot has to be done before getting the value.

### Auto generation of oop.library

updated genmodule to be capable of generating interface headers from the foo.conf of a root class, and have tested it by updating graphics.hidd to use the autogenerated headers.
Hopefully this will encourage more people to use the oop.library subsystem, by making it easier to create the necessary headers and stubs for an oop.library class interface.
Note that this is still *completely optional*, but is encouraged.
Plans to extend this to generating Objective C interfaces in the future, as well as autoinit and relbase functionality.
This allows a class interface to be defined, and will create a header file in $(AROS_INCLUDES)/interface/My_Foo.h, where 'My_Foo' is the interface's "interfacename". In the future, this could be extended to generate C++ pure virtual class headers, or Objective C protocol headers.
The header comes complete with aMy_Foo_* attribute enums, pMy_Foo_* messages, moMy_Foo method offsets, and the full assortment of interface stubs.
To define a class interface, add to the .conf file of your base class:

### Documentation

It would be nice if we could just upload to diff (maybe as zip file) and then the patching is automatically done.
If you have a local copy of the whole website, you can update only the file(s) that are changed with a rsync-type script (maybe rsync itself works for the purpose).

### Misc

* Make sure your target depends on both deps and objs emumiga-library: $(CXX_DEPS) $(CXX_OBJS)
The AROS build system
arch/common is for drivers where it is difficult to say to which CPU and/or arch they belong: for example a graphics driver using the PCI API could as well run inside hosted linux as on PPC native.
Then it's arch-independent code and it should be in fact outside of arch. Currently they are in workbench/devs/drivers. Can be discussed, but looks like it's just a matter of being used up to a particular location. At least no one changed this.
Even if it's not specific to a particular platform, the code in arch/common is hardware dependent, whereas the code in rom/ and workbench/ is supposed to be non-hardware-specific. This has been discussed before when you moved other components (e.g. ata.device) from arch/common to rom/devs. IIRC you accepted that that move was inappropriate in retrospect (but didn't undo it).
Having said that, arch/all-pc might be a good place for components shared between i386-pc and x86_64-pc such as the timer HIDD. On further inspection it seems that most drivers are already in workbench/hidds.

#### Introduction

AROS build system is based around GNU toolchain. This means we use gcc as our compiler, and the build system needs a POSIX environment to run.
Currently AROS has been successfully build using the following environments:
* Linux, various architectures and distributions. This has been, for a long time, a primary development platform. Most of our nightly builds are running under Linux.
* MacOS X (more technically known as Darwin).
* Cygwin, running Windows.
* MinGW/MSYS, running Windows (both 32-bit and 64-bit version of MinGW was tested).
From these two Windows environments, MinGW is the preferred one, because of significantly faster (compared to Cygwin) operation. There's, however, a known problem: if you want to build native port, GRUB2 can't be built. Its own build system fails is currently incompatible with MinGW, and will fail. You can work around it if you use—with-bootloader=none argument when configuring AROS. This will disable building the primary bootloader. You can perfectly live with that if you already have GRUB installed.
Running on a host whose binary format is different from ELF (i. e. Darwin and Windows), requires you to use native AROS-targeted crosstoolchain. It can be built together with AROS, however using a standalone preinstalled toolchain significantly shortens the build time and saves up your drive space. A pretty good set of prebuilt toolchains for Darwin and Windows can be obtained from AROS Archives.
Cross-compiling a hosted version of AROS requires you, additionally, to have the second crosstoolchain, targeted to what will be your host. For example if you're building Windows-hosted AROS under Linux, you'll need Windows-targeted crosstoolchain. Because of this, building a hosted version is best to be done on the same system it will run on.
In the past, configure found e.g. i386-elf-gcc etc. on the path during a cross-compile without passing special options. I'd like to retain that capability. That *should* still work if you pass in—disable-crosstools.
Remember, --enable-crosstools is the default now – and it would be silly to use the external crosstools is AROS is just going to build its own anyway.
For the kernel tools though, yes, I definitely agree. Let me know if you have a system where the kernel tool type isn't detected properly.
Making use of threaded builds (make -j X)? if not it might be worth using. Please don't; vps is a virtual machine also running some web sites. I don't want to fully starve the rest that is running on that machine. I appreciate what you are saying – but without info on the virtualised hardware cant really comment. How many "cores" does the vm have? if it has >2, don't see why adding an additional thread (make -j 2) should cause any noticeable difference to the web services it also hosts?
26 February 2012, configure has been restructured, to generate three sets of *_*_{cc,as,objdump,...} definitions.
If we are building crosstools:
orig_target_* - AROS built toolchain (in bin/{host}/tools/crosstools/....)
aros_kernel_* - External toolchain, if—with-kernel-tool-prefix, or the architecture configure it as such
aros_target_* - AROS target tools (in bin/{host}/tools/${target_tool_prefix}-*
If we are *not* building crosstools: (--disable-crosstools, or—with-crosstools=...)
aros_kernel_* - External toolchain (required, and configure should be checking for it!)
orig_target_* - Points to aros_kernel_*
aros_target_* - AROS target tools (in bin/{host}/tools/${target_tool_prefix}-*
modified collect-aros to mark ABIv1 ELF files with EI_OSABI of 15 (AROS) instead of 0 (generic Unix). For now, I'm going to hold off on the change to refuse to load ABIv0 files (with EI_OSABI of 0) until I can get some more testing done (since dos/internalloadseg_elf.c is reused in a few places).
A separate change to have ABIv0 refuse to load ABIv1 applications will need to be made. The patch to have ABIv1 refuse to load ABIv0 applications will come in the near future.

### Custom tools

Always use the 'tools/crosstools' compiler to build contrib/gnu/gcc. AFAIK this was the previous solution, using TARGET_CC override in mmakefile...
the host toolchain should only be used for compiling the tools (genmodule, elf2hunk, etc), and for the bootstrap (ie AROSBootstrap on linux-hosted and grub2 for pc-*). To be exact, the 'kernel' compiler is used for compiling GRUB2, and probably AROSBootstrap too. This is important when cross-compiling.
How about we invert the sense of --enable-crosstools? We make it '--disable-crosstools', and crosstools=yes is on by default? That way we can support new arch bringup (if we don't have working crosstools yet), but 'most people' won have to deal with the issues of, say, having C compiled with (host) gcc 4.6.1, but C++ compiled with (crosstools) gcc 4.2
There's "loadkick" gdb command now which does this auomatically. Btw, don't use add-symbol-file. Use "loadseg <address>".
You need to run as you have a stale config.
In the end I would like to get rid of the mmakefile parsing by mmake. What I would like to put in place is that mmake calls the command: 'make -f mmakefile __MM__' and it parses the output of that command. The mmakefile would the be full of statements like:
This could be generated by genmf macros or gmake functions.
I think this approach would give some advantages:
Would like to express the following 'build all libraries I depend on' concept in Metamake:
At the moment it not possible as mmake is a static scanner and does not support loops or function like $(addsuffix ...). Look in the AROS dev maillist for a thread called 'mmake RFC' (in Aug 2010) describing my idea. If you look at the svn log of tools/MetaMake there is r34165 'Started to write a function which calls the _MM_ target in a mmakefile. ...'
Can see this breaking because it wont know which "parent" metatarget(s) to invoke to build the prerequisites based on the object files / binaries alone, unless you add a dependancy on the (relevant) metatarget for every binary produced. i.e it would be like doing "make <prerequisites-metatarget>-quick" for the prerequisite. Yes, each module target would get an extra linklib-modulename target. (not linklib-kernel-dos, just linklib-dos, for example).
mmake at the moment only knows about metatargets and metadependencies. It does not handle real files or knows when something is old or new. Therefore it always has to try all metadependencies and make will find out if it is up to date or needs to be rebuilt. This can be changed to also let mmake dependencies on real files (e.g. the .c files for a shared library); remember when something was last build and check if files have changed. But this won't be a small change. IS there some way we can pass info about the file types in the "files=" parameter, so that the macros can automatically pass the files to the necessary utility macros?
IMO uselibs= should only be needed when non-standard libraries are used. In my ABI V1 I even made a patch to remove all standard libs from the uselibs= statement. I do plan to submit this again sometime in the future. And there should not be a need to add these libs to uselibs=. linklibs that are standardly linked should be build by the linklibs-core metatarget. %build_module takes care of the linklinbs-core dependency. Currently a lot of linklibs are not dependent of this metatarger because a lot of the standard libs autoopened by libautoinit.a. TBH, I also find it a bit weird. Standard libraries don't need -lXXX, because they "link" via proto files, right?
They are (currently) only used for the linklibs-<foo> dependency autogeneration. Was under the impression you wanted to move all the per-library autoinit code back to the specific libraries? Yes to avoid the current mismatch between versions in libautoinit and libxxx.a.
for %build_prog and some others so it might seem logical to add another cppfiles But then we might need to add dfiles, modfiles or pfiles for the D language, Modula-2 and Pascal as well in the future so your idea about adding it all to the files parameter in one way or another seems to be more future proof to me.
Personally, I'd prefer to let make.tmpl figure it all out from the extensions, even though it'd be a large changeset to fix all the FILES=lines.
By the way: what are the 'standard libraries'? That is to be discussed. I would include almost all libs in our workbench/libs and rom/ directories unless there is a good reason not to use it as a standard linklib. mesa will always require -lGL to be passed because AROSMesaGetProcAddress is only present in linklib. Also nobody will write code #include <proto/mesa.h>. All code will have #include <GL/gl.h>
working on minimal-version autoopening, to enhance binary compatibility with m68k and PPC AOS flavors. To be clear I like the feature you are implementing, I don't like it that programmers have to specify a long list of libs to uselibs= all the time.
Does this give the programmer a way to specify that he'll need more than the minimum for a function? For example, one aspect of a function may have been buggy/unimplemented in the first version. If that aspect is used, a version is needed that supports it properly.
Yes, in the library.conf file, you would use:
foo.conf
Then, if you use FooSet, you'll get version 34 of the library, but if your code never calls FooSet, you'll only OpenLibrary version 33.
OpenLibrary requiring version 34 in one case and 37 in the other, depending on whether I needed that specific NULL-handling aspect of FooSet. How will this work with otherwise automatic determination of minimum versions?
Uh... You'll have the handle library loading yourself, then:

##### Syntax of the makefile

Where do I need to make the changes to add 'contrib' to the amiga-m68k build process? You need to study scripts in /AROS/scripts/nightly/pkg and get some knowledge from them. Neil can probably give you better explanation. Contrib