1 | ********************************************************************************
|
---|
2 |
|
---|
3 | The Modular Building System (MoBuS)
|
---|
4 |
|
---|
5 | ********************************************************************************
|
---|
6 |
|
---|
7 |
|
---|
8 | The goal of the build system
|
---|
9 | ----------------------------
|
---|
10 |
|
---|
11 | MoBuS was projected with several goals in mind:
|
---|
12 |
|
---|
13 | - Simplicity of use. Most makefile magic should go in a few relatively
|
---|
14 | complex central makefiles, simplifying the 'end-user' makefiles.
|
---|
15 | In fact, the build system is simple enough for use without even
|
---|
16 | looking into these docs.
|
---|
17 |
|
---|
18 | - Universality. This makefile system can be easily used in any projects,
|
---|
19 | just by copying root makefiles and creating a few .smak files.
|
---|
20 |
|
---|
21 | - Flexibility. Simplicity should not make impossible to write complex
|
---|
22 | building rules, especially since our primary goal is the OS/2 C runtime,
|
---|
23 | which is a very complex thing per se.
|
---|
24 |
|
---|
25 | - Modularity. New building modules should be added and old removed without
|
---|
26 | even having to touch the root makefiles. The build system should adapt
|
---|
27 | automatically to every change.
|
---|
28 |
|
---|
29 | - Multi-option. The ability to build same file with several sets of
|
---|
30 | options (e.g. -Zmt and -pg), which implies a separate output directory for
|
---|
31 | every flavour of output files.
|
---|
32 |
|
---|
33 | - Portability. This is a secondary target, though the build subsystem can
|
---|
34 | be easily used in other operating systems (a few modifications still have
|
---|
35 | to be made first, e.g. including a platform-specific .smak file which
|
---|
36 | would set up every platform-specific aspect).
|
---|
37 |
|
---|
38 |
|
---|
39 | Glossary of terms used in MoBuS
|
---|
40 | -------------------------------
|
---|
41 |
|
---|
42 | target - a particular executable, library and so on.
|
---|
43 |
|
---|
44 | module - a set of targets, unified by a common functionality
|
---|
45 | (example: targets emxomf.exe, emxomfar.exe, emxomfld.exe,
|
---|
46 | emxaout.exe, listomf.exe are parts of module emxomf).
|
---|
47 |
|
---|
48 | persistent variable - a make variable that does not change its value
|
---|
49 | radically (e.g. some persistent variables can be appended to but never
|
---|
50 | assigned a totally different value). For example CFLAGS is a persistent
|
---|
51 | variable; submakefiles could append something to CFLAGS (which is a bad
|
---|
52 | idea anyways since it will unpredictably affect all modules) but this
|
---|
53 | doesn't change its contents radically.
|
---|
54 |
|
---|
55 | local variable - a temporary variable used in some section of makefile
|
---|
56 | and then can be reused for anything other. For easier reading such
|
---|
57 | variables are prefixed by '.', e.g. ".LOCAL" is a local variable,
|
---|
58 | while "LOCAL" is a persistent variable. When you reference local
|
---|
59 | variables it is highly advised to use the ':=' assignment rather
|
---|
60 | than '=' since when using ':=' the assigned value is expanded
|
---|
61 | immediately.
|
---|
62 |
|
---|
63 | builder - a special submakefile that defines all the rules required
|
---|
64 | to build some target. Their name starts with 'mk', for example mkexe.smak
|
---|
65 | prepares everything needed to build a .exe target and so on.
|
---|
66 |
|
---|
67 |
|
---|
68 | Using MoBuS
|
---|
69 | -----------
|
---|
70 |
|
---|
71 | Every time you start 'make', MoBuS searches all subdirectories for files
|
---|
72 | ending with '.smak' (smak stands for 'Sub-Makefile': I have chosen .smak
|
---|
73 | instead of .mak because EM already used .mak extension for his makefiles
|
---|
74 | and they would conflict with MoBuS).
|
---|
75 |
|
---|
76 | Every submakefile defines a number of special variables that control the
|
---|
77 | build process for a specific target. After they are given values, you usually
|
---|
78 | include one of the builders (we'll list them later) that prepares
|
---|
79 | everything required for the actual building. Most of these variables are
|
---|
80 | cleared to avoid their value to be incidentally passed to another submakefile
|
---|
81 | (which is almost certainly not what you want). If you don't want this to happen,
|
---|
82 | you can assign any value to the special variable .TKEEP. Here is the full list
|
---|
83 | of variables that control the build process:
|
---|
84 |
|
---|
85 | .INSDIR - (optional) directory inside the installation tree for targets.
|
---|
86 | For example, it could be 'bin/' (without quotes), or 'lib/st/' and so on.
|
---|
87 | This variable is NOT cleared after the inclusion of builders since
|
---|
88 | you may want many targets to be placed in the same install directory,
|
---|
89 | and you would have to redefine .INSDIR before every target.
|
---|
90 |
|
---|
91 | .MODULE - The name of current module. As explained above, a module can consist
|
---|
92 | of many submakefiles, and is a minimal build unit.
|
---|
93 |
|
---|
94 | .MDESC - (optional) module description. This is displayed when you type
|
---|
95 | 'make help' in the module list section.
|
---|
96 |
|
---|
97 | .MDEP - (optional) module dependencies. This is useful if current module
|
---|
98 | requires another module to be built first (e.g. a library). It usually
|
---|
99 | contains the name of another module (e.g. .MDEP := os2).
|
---|
100 |
|
---|
101 | .TARGET - The name of target (e.g. executable or library file name without dir).
|
---|
102 | For example: .TARGET := myfile.exe
|
---|
103 |
|
---|
104 | .TKIND - (optional) The kind of target. It can consist of up to three
|
---|
105 | components, the first one defines the object file format (omf or aout,
|
---|
106 | if not defined defaults to omf), the second can be 'prof' to build in
|
---|
107 | profiling mode.
|
---|
108 | Example: .TKIND := omf prof
|
---|
109 |
|
---|
110 | .TKVAR - (optional) The variant of target. This is handy if one need to build
|
---|
111 | the same sources several times with different flags.
|
---|
112 | Exampel: .TKVAR := tcpipv4
|
---|
113 |
|
---|
114 | .TDEP - Dependencies for target (not built from a source file). For example,
|
---|
115 | this could be a library built in another module, or a pre-compiled library.
|
---|
116 | A special sequence @O@ in $(.TDEP) is replaced with the base directory for
|
---|
117 | object files (for example, out/dbg/aout-st-prof/).
|
---|
118 |
|
---|
119 | .TSRC - The list of source files for this target. They should never be
|
---|
120 | absolute paths, since object file names are created by prefixing source
|
---|
121 | file directory with output directory (e.g. src/emxbind/emxbind.c will be
|
---|
122 | compiled to $(OUT)src/emxbind/emxbind.o).
|
---|
123 |
|
---|
124 | .TCF - The C compiler flags for C files listed in .TSRC.
|
---|
125 | .TCF.srcfile - You can define some specific C compiler flags for just one
|
---|
126 | source file (for example .TCF.src/emx/ld/ld.c=-D__SOMETHING)
|
---|
127 |
|
---|
128 | .TSF - Assembler flags for all .s files listed in .TSRC
|
---|
129 | .TSF{.srcfile} - Assembler (.s) flags for GAS for a specific source file.
|
---|
130 |
|
---|
131 | .TAF - Assembler (MASM or ML) flags for all .asm files listed in .TSRC
|
---|
132 | .TAF{.srcfile} - Assembler flags for a specific .asm file listed in .TSRC.
|
---|
133 |
|
---|
134 | .TLDF - Target-specific linker flags (for linked targets such as .exe
|
---|
135 | and .dll files).
|
---|
136 |
|
---|
137 | .TKEEP - If defined, all .XXX variables will be not undefined. This can be
|
---|
138 | used if you want to share some of the .XXX variables between several targets
|
---|
139 | (for example .TSRC). WARNING: Take care they accidentaly to not be passed
|
---|
140 | to another submakefile!
|
---|
141 |
|
---|
142 | After you assign values to above liste variables, you can include one of the
|
---|
143 | following builders:
|
---|
144 |
|
---|
145 | mkexe.smak - this builder treats .TARGET as a executable. It defines all
|
---|
146 | rules required for building all object files and then linking them together
|
---|
147 | to form a executable.
|
---|
148 |
|
---|
149 | mklib.smak - this builder creates a library. It defines all rules required
|
---|
150 | for building all object files and then runs the librarian which binds all
|
---|
151 | object files together in a single library. Besides, if the file format is
|
---|
152 | a.out, it also defines a target called '$(.MODULE)@omf' (e.g. for module
|
---|
153 | zzz it also defines a module called zzz@omf) which will build the OMF
|
---|
154 | library from its a.out counterpart by using emxomf.
|
---|
155 |
|
---|
156 | Here is a simple example of a submakefile that will build a simple helloworld
|
---|
157 | executable:
|
---|
158 |
|
---|
159 | --------8<--------8<--------8<--------8<--------8<--------
|
---|
160 | # $Id: build.txt 885 2003-12-08 05:42:10Z bird $
|
---|
161 |
|
---|
162 | .MODULE := helloworld
|
---|
163 | .MDESC := Build a helloworld executable
|
---|
164 | .INSDIR := bin/
|
---|
165 |
|
---|
166 | .TARGET := helloworld.exe
|
---|
167 | .TSRC := $(wildcard src/helloworld/*.c)
|
---|
168 | include mkexe.smak
|
---|
169 | --------8<--------8<--------8<--------8<--------8<--------
|
---|
170 |
|
---|
171 |
|
---|
172 | Understanding build system
|
---|
173 | --------------------------
|
---|
174 |
|
---|
175 | First of all, it would be nice to have handy the GNU Make manual before
|
---|
176 | starting to look into the makefiles. They use complex expressions, and it
|
---|
177 | would be hard to understand them without knowing how GNU Make works.
|
---|
178 |
|
---|
179 | The core of the build system are: the root Makefile and several .smak files
|
---|
180 | The root makefile does the following:
|
---|
181 |
|
---|
182 | - Defines the build environment (tools, flags and so on)
|
---|
183 | - Searches for all submakefiles (.smak files) and includes them.
|
---|
184 | - Defines the rule for displaying a help (when you run make without
|
---|
185 | arguments).
|
---|
186 | - Defines the rule for re-building the 'build rules file'. The later
|
---|
187 | is a collection of rules of the traditional form:
|
---|
188 |
|
---|
189 | sometarget: somesource
|
---|
190 | commands-to-execute
|
---|
191 |
|
---|
192 | and is placed in a auto-built .smak files in the output directory.
|
---|
193 | - Defines the rule for auto-creating output directories. The
|
---|
194 | submakefiles appends the output directories they need to the
|
---|
195 | variable TARGDIRS.
|
---|
196 | - Defines the install: target which should create a complete
|
---|
197 | distribution tree.
|
---|
198 |
|
---|
199 | The base directory for output files is assigned to the variable OUT.
|
---|
200 | In general, directory names through the makefiles have a forward slash
|
---|
201 | appended (first, for easy visual separation of directory names and second,
|
---|
202 | for simpler usage, e.g. $(OUT)myfile.o rather than $(OUT)/myfile.o).
|
---|
203 |
|
---|
204 | Every target can be of a specific 'kind', e.g. to require a specific
|
---|
205 | pre-defined set of compiler flags. When compiling multiple kinds of object
|
---|
206 | files from a single source file they are put under different output directories
|
---|
207 | (e.g. single-threaded OMF object files go into $(OUT)/omf-st/ directory while
|
---|
208 | multi-threaded a.out object files with profiling go into $(OUT)/aout-prof/
|
---|
209 | directory). This way, you can have several targets that are built from the
|
---|
210 | same source files with different compilation options.
|
---|