aboutsummaryrefslogtreecommitdiff
path: root/documentation/index.xhtml
blob: da5e3de1d27f86592f8692189cb2beec5ee1c41e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">

<!--

file      : documentation/index.xhtml
copyright : Copyright (c) 2004-2012 Code Synthesis Tools CC
license   : GNU FDL v1.2; http://www.codesynthesis.com/licenses/fdl-1.2.txt

-->

<!--
@@ maybe background code?

@@ describe all feature that appear in the example.
-->

<head>

  <title>build/documentation</title>

  <meta name="copyright" content="&copy; 2004-2012 Code Synthesis Tools CC"/>
  <meta name="keywords" content="build,system,make"/>
  <meta name="description" content="build/documentation"/>

  <link rel="stylesheet" type="text/css" href="default.css"/>

</head>

<body>
<div id="content">
<ul class="toc">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#fundamentals">Fundamentals</a></li>
<li><a href="#first_example">First Example</a>
  <ul>
    <li><a href="#invocation">Invocation</a></li>
    <li><a href="#makefiles">Makefiles</a></li>
  </ul>
</li>
<li><a href="#inter_project_dependencies">Inter-Project Dependencies</a></li>
<li><a href="#administrivia">Administrivia</a>
  <ul>
    <li><a href="#license">License</a></li>
    <li><a href="#bootstrapping">Bootstrapping</a></li>
    <li><a href="#versioning">Versioning</a></li>
  </ul>
</li>
</ul>


<h1><a name="introduction">Introduction</a></h1>

<p>I hear you saying: "Yeah, yeah, another marvelous make
replacement with built-in support for various compilers, automatic
dependency scanning, parallel and distributed builds, and XML instead of
makefiles!" On the contrary, <em>build</em> is a software build system
that is implemented on top of GNU make. It defines extensible framework for
translators, delegates most of its tasks to existing tools, and uses GNU
make syntax for makefiles. <em>Build</em> was designed with the following
tasks in mind:</p>

<ul class="multiline">
  <li>configuration</li>
  <li>building</li>
  <li>testing</li>
  <li>installation</li>
</ul>

<p>As distribution of software in source code is being replaced by
precompiled package distributions, greater emphasis was placed on
development-time conveniences. Some of the features of <em>build</em>
include:</p>

<ul class="multiline">
  <li>position-independent makefiles</li>

  <li>non-recursive multi-makefile include-based structure</li>

  <li>leaf makefiles are full-fledged GNU makefiles, not just
      variable definitions</li>

  <li>complete dependency graph</li>

  <li>inter-project dependency tracking</li>
</ul>

<p>To understand leaf makefiles in this manual you will need basic
knowledge of how <code>make</code> works. However, inside, <em>build</em>
uses some of the more advanced features of GNU make including</p>

<ul class="multiline">
<li>order-only prerequisites</li>
<li>pattern and target-specific variables</li>
<li><code>$(call )</code> and <code>$(eval )</code></li>
<li>different flavors of <code>include</code> directive</li>
</ul>

<p>If you find usage of some of the <code>make</code> techniques obscure
in this text you can always consult with the
<a href="http://www.gnu.org/software/make/manual/make.html">GNU make
manual</a>.</p>


<h1><a name="fundamentals">Fundamentals</a></h1>

<p><em>Build</em> defines a framework in terms of which user makefiles
are written. Below is the list of fundamental concepts.</p>

<dl class="multiline">
<dt>Project</dt>
<dd>is a separately distributable collection of source files. A more
intuitive way of defining a project would be to say it's  what you
normally assign a version number to (e.g., <code>libhello-0.0.1</code>)
and package as a tar ball (e.g., <code>libhello-0.0.1.tar.gz</code>).
A reasonably complex project usually has a hierarchy of sub-directories
under its root directory.</dd>

<dt>Component</dt>
<dd>is part of a project for which you would normally write a
makefile. For example our <code>libhello</code> could consist of
two components: the library itself and a test driver.</dd>

<dt>Source root</dt>
<dd>is a root directory of a project. For example, if we unpack our
<code>libhello-0.0.1.tar.gz</code> to <code>/tmp</code> and end up with
a directory <code>/tmp/libhello-0.0.1</code> then that would be this
project's <em>source root</em>.</dd>

<dt>Source base</dt>
<dd>is a directory of a component in a project. Continuing our example,
if our <code>libhello</code> project had a subdirectory <code>test</code>
then the <em>source base</em> of the <code>test</code> component would be
<code>/tmp/libhello-0.0.1/test</code>. By definition, any <em>source base</em>
is a sub-directory of a <em>source root</em> for any particular project.</dd>

<dt>Out root</dt>
<dd>is a root directory of a project's build (or output) hierarchy. This
directory signifies where generated files for the project will be placed.
For example, if we decide to build <code>libhello</code> in
<code>/tmp/libhello-i686-pc-linux-gnu</code> then that would be one of the
possible <em>out roots</em>.</dd>

<dt>Out base</dt>
<dd>is a build (or output) directory of a component in a project.
If we continue our example, the <em>out base</em> for the <code>test</code>
component would be <code>/tmp/libhello-i686-pc-linux-gnu/test</code>.</dd>
</dl>

<p>The <em>build</em> runtime defines four <code>make</code> variables that
correspond to the last four definitions:</p>

<pre class="make">
src_root
src_base
out_root
out_base
</pre>

<p>Below is an example of how you could use some of them.</p>

<pre class="make">
driver := $(out_base)/driver

$(driver): $(out_base)/driver.o $(out_root)/libhello/libhello.so
</pre>

<p>Additionally, the <em>build</em> framework defines three more
variables:</p>

<pre class="make">
bld_root
scf_root := $(src_root)/build
dcf_root := $(out_root)/build
</pre>

<p><code>bld_root</code> is a root directory of the <em>build</em> runtime.
Normally you would use it to include one of the <em>build</em>'s files.</p>

<p><code>scf_root</code> stands for static configuration root and
points to a directory where project's static configuration is kept.
<code>dcf_root</code> stands for dynamic configuration root and
points to a directory where project's dynamic configuration is kept.
We will talk more about those two variables later.</p>

<p>Also note that having <code>src_root</code> the same as
<code>out_root</code> is perfectly valid and indicates that we
are building in a source directory.</p>

<h1><a name="first_example">First Example</a></h1>

<p>Now we are ready to examine our first simple example. We
will skip one-file C-based "hello world", however, because it
is not very practical and there is not much room for improvement.
Rather we will start from a <code>libhello</code> library, a test
driver for it and a <code>hello</code> program that uses the library.
To make our example even more realistic the <code>libhello</code>
library and the <code>hello</code> program are two separate projects.
And, did I mention, they are written in C++. See
<code>examples/cxx/hello</code>.</p>

<h2><a name="invocation">Invocation</a></h2>

<p>Let's first get some user experience without looking into makefiles.
Suppose we unpacked <em>build</em> source into <code>/tmp/build-0.1.12</code>.
First let's try to build <code>libhello</code>:</p>

<pre class="term">
$ cd /tmp/build-0.1.12/examples/cxx/hello/libhello
$ make


configuring 'libhello'



Please select the C++ compiler you would like to use:

(1) GNU C++ (g++)
(2) Intel C++ (icc)

[1]: 1

Would you like the C++ compiler to optimize generated code?

[y]: y

Would you like the C++ compiler to generate debug information?

[y]: y


configuring 'libhello'



Please select the default library type:

(1) archive
(2) shared object

[2]: 2


configuring 'libhello'



Please enter the g++ binary you would like to use, for example 'g++-3.4',
'/usr/local/bin/g++' or 'distcc g++'. You can use path auto-completion.

[g++]: g++

Please select the optimization level you would like to use:

(1) -O1 [Tries to reduce code size and execution time, without
         performing any optimizations that take a great deal of
         compilation time.]
(2) -O2 [Performs nearly all supported optimizations that do not
         involve a space-speed tradeoff.]
(3) -O3 [Optimize even more.]
(4) -Os [Optimize for size.]

[2]: 2
c++ /tmp/build-0.1.12/examples/cxx/hello/libhello/libhello/hello.cxx
ld  /tmp/build-0.1.12/examples/cxx/hello/libhello/libhello/hello.l
c++ /tmp/build-0.1.12/examples/cxx/hello/libhello/test/driver.cxx
ld  /tmp/build-0.1.12/examples/cxx/hello/libhello/test/driver
</pre>

<p>Here we were presented with a bunch of configuration questions.
If you have <code>g++</code> in your default path you can just keep
hitting enter to select defaults. If you would like to see real commands
that are being executed (useful when something goes wrong) you can
say <code>make verbose=1</code>.</p>

<p>From the messages above we can deduce that we have built the
<code>libhello</code> library (<code>hello.l</code>) and the test driver
for it (<code>test/driver</code>). So far so good. Now let's try to build
the <code>hello</code> program:</p>

<pre class="term">
$ cd /tmp/build-0.1.12/examples/cxx/hello/hello
$ make
</pre>

<p>Again you will be asked a bunch of questions you have already seen,
except these two:</p>

<pre class="term">
Configuring external dependency on 'libhello' for 'hello driver'.


Would you like to configure dependency on the installed
version as opposed to the development build?

[y]: n

Please enter the out_root for 'libhello'.

[]: ../libhello

Please enter the src_root for 'libhello'.

[]: ../libhello
</pre>

<p>The <code>hello</code> program depends on <code>libhello</code>. Since
they are distributed as separate projects <code>hello</code> needs to
know where to look for <code>libhello</code>. That's why user intervention
is required. The first question is whether we would like to use an installed
version of <code>libhello</code> as opposed to the not installed build.
Since we haven't installed <code>libhello</code> the answer is
<code>no</code>. The next two questions determine where the
<code>out_root</code> of the build and the <code>src_root</code> of the source
code are. Since we built <code>libhello</code> in its source directory both
become <code>/tmp/build-0.1.12/examples/cxx/hello/libhello</code> or
<code>../libhello</code> if we are in
<code>/tmp/build-0.1.12/examples/cxx/hello/hello</code>. After answering
those questions you will see something like this:</p>

<pre class="term">
c++ /tmp/build-0.1.12/examples/cxx/hello/hello/hello.cxx
ld  /tmp/build-0.1.12/examples/cxx/hello/hello/hello
</pre>

<p>And that's it.</p>

<p>One of the nice features of <em>build</em> is that you can have several
builds in separate directories all from the same source base. Suppose we
would like to build an <code>-O3</code>-optimized statically-linked version
of <code>hello</code> without debug information:</p>

<pre class="term">
$ mkdir /tmp/hello-i686-pc-linux-gnu
$ cd /tmp/hello-i686-pc-linux-gnu
$ make -f ../build-0.1.12/examples/cxx/hello/hello/makefile


configuring 'hello driver'



Please select the C++ compiler you would like to use:

(1) GNU C++ (g++)
(2) Intel C++ (icc)

[1]: 1

Would you like the C++ compiler to optimize generated code?

[y]: y

Would you like the C++ compiler to generate debug information?

[y]: n


Configuring external dependency on 'libhello' for 'hello driver'.



Would you like to configure dependency on the installed
version as opposed to the development build?

[y]: n

Please enter the out_root for 'libhello'.

[]: /tmp/libhello-i686-pc-linux-gnu

Please enter the src_root for 'libhello'.

[]: ../build-0.1.12/examples/cxx/hello/libhello


configuring 'hello driver'



Please enter the g++ binary you would like to use, for example 'g++-3.4',
'/usr/local/bin/g++' or 'distcc g++'. You can use path auto-completion.

[g++]: g++

Please select the optimization level you would like to use:

(1) -O1 [Tries to reduce code size and execution time, without
         performing any optimizations that take a great deal of
         compilation time.]
(2) -O2 [Performs nearly all supported optimizations that do not
         involve a space-speed tradeoff.]
(3) -O3 [Optimize even more.]
(4) -Os [Optimize for size.]

[2]: 3


configuring 'libhello'



Please select the C++ compiler you would like to use:

(1) GNU C++ (g++)
(2) Intel C++ (icc)

[1]: 1

Would you like the C++ compiler to optimize generated code?

[y]: y

Would you like the C++ compiler to generate debug information?

[y]: n


configuring 'libhello'



Please select the default library type:

(1) archive
(2) shared object

[2]: 1


configuring 'libhello'



Please enter the g++ binary you would like to use, for example 'g++-3.4',
'/usr/local/bin/g++' or 'distcc g++'. You can use path auto-completion.

[g++]: g++

Please select the optimization level you would like to use:

(1) -O1 [Tries to reduce code size and execution time, without
         performing any optimizations that take a great deal of
         compilation time.]
(2) -O2 [Performs nearly all supported optimizations that do not
         involve a space-speed tradeoff.]
(3) -O3 [Optimize even more.]
(4) -Os [Optimize for size.]

[2]: 3
c++ /tmp/build-0.1.12/examples/cxx/hello/hello/hello.cxx
c++ /tmp/build-0.1.12/examples/cxx/hello/libhello/libhello/hello.cxx
ar  /tmp/libhello-i686-pc-linux-gnu/libhello/hello.l
ld  /tmp/hello-i686-pc-linux-gnu/hello
</pre>

<h2><a name="makefiles">Makefiles</a></h2>

<p>Now let's take a look at the makefiles. We will start from the
makefile for <code>libhello</code> (<code>hello/libhello/libhello/makefile</code>).
Note, that I removed support for <code>install</code> target for now.</p>

<pre class="make">
include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make

cxx_tun   := hello.cxx
cxx_obj   := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o))
cxx_od    := $(cxx_obj:.o=.o.d)

hello.l             := $(out_base)/hello.l
hello.l.cpp-options := $(out_base)/hello.l.cpp-options

clean     := $(out_base)/.clean


# Build.
#
$(hello.l): $(cxx_obj)

$(cxx_obj): $(hello.l.cpp-options)

$(hello.l.cpp-options): value := -I$(src_root)

$(call -include,$(cxx_od))


# Clean.
#
.PHONY: $(clean)

$(clean): $(hello.l).clean \
          $(addsuffix .clean,$(cxx_obj)) \
          $(hello.l.cpp-options).clean


# Aliases.
#
ifdef %interactive%

.PHONY: clean

clean: $(clean)

endif


# How to.
#
$(call include,$(bld_root)/cxx/o-l.make)
$(call include,$(bld_root)/cxx/cxx-o.make)
</pre>

<p>Let's examine this file line-by-line:</p>

<pre class="make">
include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
</pre>

<p>Every leaf makefile (i.e., one written to build a component) starts from a
line that looks like this. Its sole purpose is to bootstrap the build system.
In our case <code>$(dir $(lastword ...))</code> will expand to something
like</p>

<pre class="make">
include .../hello/libhello/libhello/../build/bootstrap.make
</pre>

<p>Let's take a look at <code>libhello/build/bootstrap.make</code>:</p>

<pre class="make">
project_name := libhello
include $(dir $(lastword $(MAKEFILE_LIST))).../build/bootstrap.make
</pre>

<p>The first line just initializes <code>project_name</code> with the name
of the project. The second line includes the real <code>bootstrap.make</code>.
See <a href="#bootstrap">Bootstrapping</a> section for more information on
various ways of bootstrapping the <em>build</em> runtime.</p>

<p>What does <code>bootstrap.make</code> do? Besides other things (which are
explained as we encounter them) it sets all those <code>*_root</code> and
<code>*_base</code> variables.</p>

<p>Let's go back to our <code>libhello/makefile</code>. The first line
should be clear by now so let's move on:</p>

<pre class="make">
cxx_tun   := hello.cxx
cxx_obj   := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o))
cxx_od    := $(cxx_obj:.o=.o.d)
</pre>

<p>This should be pretty straightforward: <code>cxx_tun</code> contains
a list of translation units, <code>cxx_obj</code> contains a list of
object files that will be produced from those translation units, and
<code>cxx_od</code> contains a list of automatically generated dependency
files for those translation units. After expansion these variables could
contain the following values (note, in this example <code>out_root</code>
is the same as <code>src_root</code>):</p>

<pre class="make">
cxx_tun   := hello.cxx
cxx_obj   := .../hello/libhello/libhello/hello.o
cxx_od    := .../hello/libhello/libhello/hello.o.d
</pre>

<p>Next chunk:</p>

<pre class="make">
hello.l             := $(out_base)/hello.l
hello.l.cpp-options := $(out_base)/hello.l.cpp-options

clean     := $(out_base)/.clean
</pre>

<p><code>hello.l</code> and <code>clean</code> are two variables that
store names of targets. You are probably wondering what the heck
is <code>hello.l</code>? This is a library abstraction the build system
provides to deal (besides other things) with archives/shared objects
uniformly. A user who builds your project can specify what type of
library they want without any additional effort from you. I encourage
you to take a look inside <code>hello.l</code>.</p>

<p><code>hello.l.cpp-options</code> is a bit trickier.
<code>$(out_base)/hello.l.cpp-options</code> keeps C preprocessor options
that are required to compile library files as well as any piece of code
that uses it. Hopefully, it will become clear once you see the rest of
the makefile.</p>

<p>Let's move on:</p>

<pre class="make">
# Build.
#
$(hello.l): $(cxx_obj)

$(cxx_obj): $(hello.l.cpp-options)

$(hello.l.cpp-options): value := -I$(src_root)

$(call -include,$(cxx_od))
</pre>

<p>The first line tells us that <code>hello.l</code> is built from object
files listed in <code>cxx_obj</code>. The second line establishes dependency
of object files on C preprocessor options - in order to build an object file
we will need C++ source file and C preprocessor options - quite logical. The
third line sets target-specific variable <code>value</code> for
<code>hello.l.cpp-options</code>: that's how <code>hello.l.cpp-options</code>
gets its content. You may be wondering why do we need to add this
<code>-I$(src_root)</code>. The first line of <code>hello.cxx
</code> should clear things up:</p>

<pre class="cxx">
#include "libhello/hello.hxx"
</pre>

<p>And finally the fourth line includes auto-generated dependency
information for each object file. You can think of
<code>$(call -include )</code> as being equivalent to <code>-include</code>
directive for now.</p>


<p>Next chunk:</p>

<pre class="make">
.PHONY: $(clean)

$(clean): $(hello.l).clean \
          $(addsuffix .clean,$(cxx_obj)) \
          $(hello.l.cpp-options).clean
</pre>

<p>Let's concentrate on the last line. There we are essentially saying that
cleaning <code>libhello</code> consists of cleaning the library, object
files and C preprocessor options. How does this work? It is done using
pattern rules. Part of the build system that defines how to build say
<code>%.l</code> also defines how to clean after it: <code>%.l.clean</code>.
You may want to look into <code>build/cxx/gnu/o-l.make</code> for details.</p>

<p>Moving on:</p>

<pre class="make">
# Aliases.
#
ifdef %interactive%

.PHONY: clean

clean: $(clean)

endif
</pre>

<p>In this part we are creating a short alias (<code>clean</code>)
for its long equivalent (<code>$(out_base)/.clean</code>). <code>
%interactive%</code> is a <em>system variable</em> defined by
the framework. It is initialized only if current makefile is
used in interactive mode as opposed to being included.</p>

<p>And finally:</p>

<pre class="make">
# How to.
#
$(call include,$(bld_root)/cxx/o-l.make)
$(call include,$(bld_root)/cxx/cxx-o.make)
</pre>

<p>In this makefile fragment we are including parts of the build
system that actually know <em>how to build</em>. As you might have
noticed, all the code that we have examined up until now was dealing
with <em>what to build</em>. <code>o-l.make</code> defines a pattern
rule to build libraries from object files. <code>cxx-o.make</code>
defines a pattern rule to build object files from C++ translation units.</p>

<p>And this concludes our examination of the makefile for
<code>libhello</code>. Next is the test driver(
<code>hello/libhello/test/makefile</code>):</p>

<pre class="make">
include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make

cxx_tun := driver.cxx
cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o))
cxx_od  := $(cxx_obj:.o=.o.d)

hello.l             := $(out_root)/libhello/hello.l
hello.l.cpp-options := $(out_root)/libhello/hello.l.cpp-options

driver  := $(out_base)/driver.e
clean   := $(out_base)/.clean
test    := $(out_base)/.test


# Build.
#
$(driver): $(cxx_obj) $(hello.l)

$(cxx_obj): $(hello.l.cpp-options)

$(call -include,$(cxx_od))


# Test.
#
.PHONY: $(test)

$(test): $(driver)
	$&lt;


# Clean.
#
.PHONY: $(clean)

$(clean): $(driver).clean $(addsuffix .clean,$(cxx_obj))


# Aliases.
#
ifdef %interactive%

.PHONY: clean test

test: $(test)
clean: $(clean)

endif


# How to.
#
$(call include,$(bld_root)/cxx/o-e.make)
$(call include,$(bld_root)/cxx/cxx-o.make)


# Load build information.
#
$(call load,$(src_root)/libhello/makefile)
</pre>

<p>Do you see anything unknown or strange in this makefile? I hope you don't.
Just to re-iterate, I will remove everything we definitely saw and leave
only what's new:</p>

<pre class="make">
hello.l             := $(out_root)/libhello/hello.l
hello.l.cpp-options := $(out_root)/libhello/hello.l.cpp-options


# Build.
#
$(driver): $(cxx_obj) $(hello.l)

$(cxx_obj): $(hello.l.cpp-options)


# Load build information.
#
$(call load,$(src_root)/libhello/makefile)
</pre>

<p>All of what's left deals in one way or the other with linking
to <code>libhello</code>. The first two lines define variables that
hold paths to the library and C preprocessor options (since we are in
the same project we know what those paths are relative to
<code>out_root</code>/<code>src_root</code>). The third line declares that
driver consists of object files and should be linked with
<code>libhello</code>. The next line says that we need C preprocessor options
to build object files, just like we did for <code>libhello</code>. And finally
the last line: what does the <code>load</code> function do? The
<code>load</code> function loads rules and dependency information from the
makefile specified. Note that it doesn't make variable definitions from that
makefile available (or, even worse, override ones we set) - only dependencies
and rules. The major benefit of doing this is in having complete dependency
information along with the rules in case something gets out of date. If, for
example, we change something in <code>libhello</code> and then execute
<code>make</code> in <code>test</code>, <code>make</code> will be able to
detect that <code>libhello</code> is out of date and will re-build it before
building the test driver.</p>

<p>Now let's take a look at the makefile from the <code>hello</code> program
(<code>hello/hello/makefile</code>). Remember that it is a separate project
(I removed support for <code>install</code> target again):</p>


<pre class="make">
include $(dir $(lastword $(MAKEFILE_LIST)))build/bootstrap.make

cxx_tun   := hello.cxx
cxx_obj   := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o))
cxx_od    := $(cxx_obj:.o=.o.d)

hello.e   := $(out_base)/hello.e
clean     := $(out_base)/.clean

# Secure default target.
#
$(hello.e):


# Import information about libhello.
#
$(call import,libhello,l: hello.l,cpp-options: hello.l.cpp-options)


# Build.
#
$(hello.e): $(cxx_obj) $(hello.l)

$(cxx_obj): $(hello.l.cpp-options)

$(call -include,$(cxx_od))


# Clean.
#
.PHONY: $(clean)

$(clean): $(hello.e).clean $(addsuffix .clean,$(cxx_obj))


# Aliases.
#
ifdef %interactive%

.PHONY: clean

clean: $(clean)

endif


# How to.
#
$(call include,$(bld_root)/cxx/o-e.make)
$(call include,$(bld_root)/cxx/cxx-o.make)
</pre>

<p>Again I will remove all the parts that we are familiar with leaving
only what's new:</p>

<pre class="make">
# Secure default target.
#
$(hello.e):


# Import information about libhello.
#
$(call import,libhello,l: hello.l,cpp-options: hello.l.cpp-options)
</pre>

<p>Let's see what's going on here. I will start from the call to
the <code>import</code> function. It is similar to the <code>load</code>
function with a few exceptions. First of all, since we are importing
build information from a separate project we don't know where to look
for its parts; this will require dynamic configuration. Secondly, we
have no way to figure out where <code>hello.l</code> and
<code>hello.l.cpp-options</code> are. Thus we have
<code>`l: hello.l'</code> and <code>`cpp-options: hello.l.cpp-options'</code>
which essentially means "initialize variable <code>hello.l</code> with
the library path and variable <code>hello.l.cpp-options</code> with
the C preprocessor options file path".</p>

<p>One side effect of the call to <code>import</code> function is the
potential loss of the default target. Thus, the first line.</p>

<p>The inter-project dependency importing architecture is probably
the most complicated part of the build system. It will be described
in a separate section.</p>

<p>This concludes our step-by-step examination. It was not trivial
but neither is building real software.</p>

<h1><a name="inter_project_dependencies">Inter-Project Dependencies</a></h1>

<p>To be completed.</p>


<h1><a name="administrivia">Administrivia</a></h1>


<h2><a name="license">License</a></h2>

<p>The <em>build</em> runtime (makefiles, scripts, etc.) is distributed under
the terms of the <a href="http://www.codesynthesis.com/licenses/gpl-2.txt">GNU General
Public License, version 2</a>. <em>Build</em> documentation is distributed
under the terms of the <a href="http://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU
Free Documentation License, version 1.2</a>.</p>

<p>In particular, this means that any makefile, script, etc., that
includes, calls, or otherwise links to the <em>build</em> runtime must
be covered by a GPL-compatible license, should you decide to distribute
them.</p>


<h2><a name="bootstrapping">Bootstrapping</a></h2>

<p>There are two ways to use the build system: your project can embed
all necessary files or you can require the <em>build</em> runtime to be
installed. The first approach allows you to make your project self-content,
modulo other external dependencies it might have. The disadvantage of this
approach manifests itself when your project participates in a build with
inter-project dependencies established: your project and the rest of the
build could use different (and potentially incompatible) versions of the
runtime. There is no such problem with the second approach.</p>

<p>My advice is to go with the installed <em>build</em> unless you have
a compelling reason to do otherwise.</p>

<p>When you go with the embedded runtime you can copy all necessary files
to your project's <code>build/</code> directory. When you use external
<em>build</em> your <code>build/bootstrap.make</code> might look something
like this:</p>

<pre class="make">
project_name := libhello
include build-0.1/bootstrap.make
</pre>

<p>How will <code>make</code> find <code>build-0.1/bootstrap.make</code>?
There are two ways this can happen: you have the runtime installed (e.g.,
into <code>/usr/local/include</code>) where <code>make</code> will look
for it by default or you can tell <code>make</code> where to look using
<code>-I</code> option in the command line or by setting
<code>MAKEFLAGS</code> environment variable.</p>

<h2><a name="versioning">Versioning</a></h2>

<p><em>Build</em> uses a three-digit versioning scheme: <code>X.Y.Z</code>.
<code>X</code> is a generation number; it is incremented when a completely
new design is implemented. <code>Y</code> is an interface version; two
<em>build</em> runtimes with different <code>Y</code> have incompatible
interfaces even though the ideology is the same (if ideology changes
<code>X</code> will most likely be incremented). Additionally, odd
<code>Y</code> indicates that it's a development release (similar to
the linux kernel). Finally, <code>Z</code> signifies a release number.
Releases with the same <code>X.Y</code> have the same interface.</p>

<p>To allow co-existence of several versions of <em>build</em> on the
same system, the <code>X.Y</code> pair is made part of the path (e.g.,
<code>/usr/include/build-0.1</code>) thus when you bootstrap the runtime
(in a project-specific <code>bootstrap.make</code>) you specify interface
version:</p>

<pre class="make">
include build-0.1/bootstrap.make
</pre>
</div>


<div id="docinfo">
<p>Copyright &copy; 2004-2012 <a href="http://www.codesynthesis.com">Code Synthesis Tools CC</a>.</p>

<div class="terms">
Permission is granted to copy, distribute and/or modify this document under
the terms of the <a href="http://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free
Documentation License, version 1.2</a>; with no Invariant Sections, no
Front-Cover Texts and no Back-Cover Texts.
</div>
</div>

</body>
</html>