ref: ddb327c92ebe3f96c5c816ec61996440551de401
dir: /doc/buildsys.txt/
The Myrddin Compiler Build System Aug 2014 Ori Bernstein TABLE OF CONTENTS: 0. DEPENDENCIES 1. USAGE 2. CREATING MAKEFILES 2.1. Example 2.2. Targets 2.3. Variables 3. CONFIGURE SCRIPTS 4. INTERNALS 4.1: Automatic dependency generation 4.2: Automatic dependency generation 4. BUGS 0. DEPENDENCIES: c.mk depends on GNU Make, using it's builtins for a number of variable expansions. On systems where the default make program is not GNU Make, please run 'gmake' or similar. Otherwise, you will end up with obscure failures. A method of making this script portable would be very welcome. Beyond that, all that is needed to run this is a portable POSIX system. 1. USAGE: run 'make' and the default targets will be built. The usual targets are supported. That means: all: Builds all targets. This will build every target specified in the makefile, recurse into subdirectories, and do everything needed. If dependencies are in other directories, it will 'cd' into those directories and call make as needed. target-name: This builds the specified target and it's dependencies. install: This installs the software to the prefix specified in the configuration, or /usr/local if there is nothing more specific specified. If DESTDIR is set, it will install the files to the prefix $(DESTDIR)/$(INST_ROOT), although all paths will still be relative to $(INST_ROOT). This is for packaging, and matches the behavior of automake. uninstall: This uninstalls the software, removing all files installed by 'make install'. clean: This removes all temporary files created by the build process, allowing a fresh build to occur. When a target is not specified, 'all' is assumed. 2. CREATING MAKEFILES: c.mk is only a set of rules to make common actions simple. There is nothing preventing custom make from being added for 2.1: Example c.mk is designed around the convention of having one primary target per directory. This primary target can be either a binary or a library, for the most part, although there is nothing that prevents you from defining your own primary targets. So, let's dissect an example makefile: BIN = mybinary INSTBIN = $(BIN) OBJ = foo.o bar.o baz.o include config.mk include c.mk custom-rule: custom-dep insult-your-momma 2.2: Targets Currently, there are several targets supported by c.mk SUB This target will recurse into the subdirectories listed, building everything in them. BIN This target will build a single binary, and will not install it. It uses $(OBJ) as its input. LIB This target will build a single static library, and will not install it. It uses $(OBJ) as its input. It conflicts with $(BIN) INSTBIN Same as BIN, but installed to $(INST_ROOT)/bin INSTLIB Same as LIB, but installed to $(INST_ROOT)/lib INSTHDR Used for defining headers to install to system include directories. Does not generate headers. Takes multiple arguments and installs them to $(INST_ROOT)/include INSTPKG Used for defining pkgconfig files to install to system pkgconfig directories. Does not generate them from inputs. Takes multiple arguments and installs them to $(INST_ROOT)/lib/pkgconfig. INSTMAN Used for defining manpage files to install to system man directories. Does not generate them from inputs. Takes multiple arguments and installs them to $(INST_ROOT)/lib/pkgconfig. 2.3: Variables: c.mk respects the usual environment variables. If you set CFLAGS, it will compile with those flags. If you set LDFLAGS, it will link with those flags. It also supports a number of extra configuration variables: EXTRA Dependencies that should be built when 'make all' is run. These can be, for example, additional binaries, rules, etc. EXTRADEP Dependencies that should be added when compiling a BIN or LIB target GENHDR Headers that are generated for consumption by C code. CLEAN Files that should be removed when runngng INCS Include paths. These are passed to the C compiler when building C code. DEPS Paths to local dependencies, such as convenience libraries. This is a relative path to a libfoo.a file. All libraries that are depended on in this manner will be automatically built before they are used. The path to them will also be added to the include path if needed, and they will be linked in to binaries that are built. 3. CONFIGURE SCRIPTS: This is not mandatory, although convention requests it. This is simply a shell script that will probe the system, and generate the 'config.mk' file, This can be generated a number of ways. Although Myrddin doesn't currently use it, autoconf is a perfectly viable method of generating a config.mk setup. Myrddin currently uses a simple script that mocks autotools, instead. 4. INTERNALS: c.mk is a relatively simple set of commands. It defines make targets for the various default rules, and uses the variables described above to substitute into them, with fairly traditional structure. It begins by setting the default goal (ie, the target that is built when 'make' is run with no arguments) to 'all', and proceeds to define a few internal variables. 4.1: Automatic dependency generation _DEPSDIR and _DEPS are defined early on. _DEPSDIR is simply a directory named '.deps', which is created before any compilation occurs, and contains the dependency makefile fragments that GCC generates. _DEPS is the list of dependency filename fragments, generated by substituting '.deps/$FILEBASE.d' for every .o file define in $(OBJS) CFLAGS also unconditionally has the required flags for dependency generation added to the compiler command, and later on, the dependencies are included into the makefile if they exist. 4.2: The general target rules are defined. There are many for loops and bits of shell scripting to support them, but the pattern is fairly basic. well-known-target: prerequisites do-commands Some of the commands are fairly long. For example, the install and uninstall targets will loop through a list of files for each of the main target types. is simply '.deps', and is the location where GCC's generated dependency information goes. _DEPS 4. BUGS: - Currently, 'make uninstall' does not remove empty directories that it created. - You can define BIN/INSTBIN, LIB/INSTLIB in a way that does not match. We do not error on this. - Well known targets are defined relatively inflexibly. It should be easier to include modules and have them add on to the base rule set.