From bd5f729b9ae40fb267300f32e38ca5830620dcfa Mon Sep 17 00:00:00 2001 From: Christopher Currie Date: Thu, 5 Feb 2004 19:51:14 +0000 Subject: [PATCH] Re-organized boostbook files: * Moved XML sources to src * Added reference.css from Reece Dunn to html dir * Added images from boost/doc/html so that local builds look ok [SVN r22175] --- v2/doc/Jamfile.v2 | 2 +- v2/doc/html/images/blank.png | Bin 0 -> 374 bytes v2/doc/html/images/caution.png | Bin 0 -> 1250 bytes v2/doc/html/images/draft.png | Bin 0 -> 17454 bytes v2/doc/html/images/home.png | Bin 0 -> 1156 bytes v2/doc/html/images/important.png | Bin 0 -> 722 bytes v2/doc/html/images/next.png | Bin 0 -> 1150 bytes v2/doc/html/images/note.png | Bin 0 -> 490 bytes v2/doc/html/images/prev.png | Bin 0 -> 1132 bytes v2/doc/html/images/tip.png | Bin 0 -> 449 bytes v2/doc/html/images/toc-blank.png | Bin 0 -> 318 bytes v2/doc/html/images/toc-minus.png | Bin 0 -> 259 bytes v2/doc/html/images/toc-plus.png | Bin 0 -> 264 bytes v2/doc/html/images/up.png | Bin 0 -> 1111 bytes v2/doc/html/images/warning.png | Bin 0 -> 1241 bytes v2/doc/html/reference.css | 76 + v2/doc/src/advanced.xml | 831 ++++++++ v2/doc/src/architecture.xml | 434 ++++ v2/doc/src/catalog.xml | 9 + v2/doc/src/extending.xml | 128 ++ v2/doc/src/faq.xml | 82 + v2/doc/src/howto.xml | 33 + v2/doc/src/install.xml | 111 ++ v2/doc/src/recipes.xml | 35 + v2/doc/src/reference.xml | 1037 ++++++++++ v2/doc/src/tutorial.xml | 516 +++++ v2/doc/src/userman.xml | 23 + v2/doc/userman.xml | 3189 ------------------------------ 28 files changed, 3316 insertions(+), 3190 deletions(-) create mode 100644 v2/doc/html/images/blank.png create mode 100644 v2/doc/html/images/caution.png create mode 100644 v2/doc/html/images/draft.png create mode 100644 v2/doc/html/images/home.png create mode 100644 v2/doc/html/images/important.png create mode 100644 v2/doc/html/images/next.png create mode 100644 v2/doc/html/images/note.png create mode 100644 v2/doc/html/images/prev.png create mode 100644 v2/doc/html/images/tip.png create mode 100644 v2/doc/html/images/toc-blank.png create mode 100644 v2/doc/html/images/toc-minus.png create mode 100644 v2/doc/html/images/toc-plus.png create mode 100644 v2/doc/html/images/up.png create mode 100644 v2/doc/html/images/warning.png create mode 100644 v2/doc/html/reference.css create mode 100644 v2/doc/src/advanced.xml create mode 100644 v2/doc/src/architecture.xml create mode 100644 v2/doc/src/catalog.xml create mode 100644 v2/doc/src/extending.xml create mode 100644 v2/doc/src/faq.xml create mode 100644 v2/doc/src/howto.xml create mode 100644 v2/doc/src/install.xml create mode 100644 v2/doc/src/recipes.xml create mode 100644 v2/doc/src/reference.xml create mode 100644 v2/doc/src/tutorial.xml create mode 100644 v2/doc/src/userman.xml delete mode 100644 v2/doc/userman.xml diff --git a/v2/doc/Jamfile.v2 b/v2/doc/Jamfile.v2 index 16c9efe48..43adbdacf 100644 --- a/v2/doc/Jamfile.v2 +++ b/v2/doc/Jamfile.v2 @@ -1,3 +1,3 @@ project tools/build/v2/doc ; -boostbook userman : userman.xml ; +boostbook userman : src/userman.xml ; diff --git a/v2/doc/html/images/blank.png b/v2/doc/html/images/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..764bf4f0c3bb4a09960b04b6fa9c9024bca703bc GIT binary patch literal 374 zcmeAS@N?(olHy`uVBq!ia0y~yU}ykg4kiW$2A`O3a~K#HSkfJR9T^xl_H+M9WMyDr z)b(_645^s&_M)R8g96V1g9H1Y`?|@Qa8+HmHda4(nQ?zM!!?FAj1kNm*b;aTNHv%; cj9>w=gf!;AOne?`3=9kmp00i_>zopr0Be8NW(e>Jab;j&;NV~o5MYpy zU{F+KFf?Rva$<;zVn|MA$j)XcE@r5%W@u?)XlW_#>0#*UDemd%nKFf8%9P?MQ>y38 zVVEwkZjIWyHF@jSt$X(}?A@Du?i|Cp zbLXyIW4Lzh+_h`h?%iX!chB(NJdh*`E$$X&!4}4&+z{J`|sZwzJC|^ z{$1kxcf;@BzyJTw@c+NS|Nj#IN5NBISn~R-X--a%afBxQ|J!3zMjr_SU zk_iHr)f*lf{$5^Qz}I)@3FlWvw(w~u=1P@VsTP+$RNGvxbHL-(%M6nc6`{zlU zjGQJeveps+!&Jb&mD)L@hA} z1_tL6*NBqf{Irtt#G+IN2MuLS&)mfHRNut(%;anZ6Fnn63k6F{eFF=914D)6qRirw zN{8Ia;*!i{z0_j8l+uFyyb`_S{M?DV6n8K%Fld2|%S_KpEGaEYWk@zRFt#waFg8d` zG)YZPF-fe)lBATd3a!N{b-$VA&f+n^|#(~yCI Ofx*+&&t;ucLK6T%G-N*j literal 0 HcmV?d00001 diff --git a/v2/doc/html/images/draft.png b/v2/doc/html/images/draft.png new file mode 100644 index 0000000000000000000000000000000000000000..0084708c9b8287c51efa6b40b8d492854191455e GIT binary patch literal 17454 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 YsPxZ;53A2HFfcH9y85}Sb4q9e0Fi|iga7~l literal 0 HcmV?d00001 diff --git a/v2/doc/html/images/home.png b/v2/doc/html/images/home.png new file mode 100644 index 0000000000000000000000000000000000000000..cbb711de712dcf06597a3a8a3d95f6fefda1f245 GIT binary patch literal 1156 zcmeAS@N?(olHy`uVBq!ia0y~yU{GdYVBqIqW?*25%xqI*U|?nl@Ck7h=n+utQPiBG zX*kEwX^xZEQm^E-$;Eq%TlTi}9P62KZpzYgOSj(JdhFh@bI;FRdw=cu`{(b!zyCi9 zMnhm&guthFOWYY47#Neh-CY9n1_tL6*NBqf{Irtt#G+IN z2MuLS&)mfHRNut(%;anZ6Fnn63k6F{eFF=914D)6qRirwN{8Ia;*!i{z0_j8l+uFy zyb`_S{M?DV6n8K%Fld2|%S_KpEGaEYWiT`~F*Y_zO|vvfN;EYxGBP$XPBJkxGD|Tt yFg8uIG<@^^Wdj2P10P6NKw^3-gRyCap{cfkwt-Nc+b0GF1_n=8KbLh*2~7Y2ymC_j literal 0 HcmV?d00001 diff --git a/v2/doc/html/images/important.png b/v2/doc/html/images/important.png new file mode 100644 index 0000000000000000000000000000000000000000..12c90f607a1b27ddde0a7d922ae255e8c90e883e GIT binary patch literal 722 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4rT@hhU+WOo?>8NcoN_f;wr$vARr(hAt9lu zscC6x>EvV>6{VS+EaBwj6ciMco$ZvI98_E!l$@NLot<4>UER|o(bHqOcQ41TYc{y!?kM?_wFg)yJvXsp5^oB z9Pi&Vyniq7|3Ab3{~Z7S3p{_W`TV)z`}cpO z$(;G%_wGG* z?AW<;=dNA5cJJQ3=g*(NfB*jb_wWDz|6hCQ@I3|w2F4_BcNgdM3%p4T42R|DNig) zWpL0?*7VFxOi%SqOwUZtRxr^s(z8&owA44S&^IttNG{4OE~#|Ltt>9dOx8;+)=McZ z$j>X$OU}=oxJz*d0|SE=*tpE}yu^~yqEv=t literal 0 HcmV?d00001 diff --git a/v2/doc/html/images/next.png b/v2/doc/html/images/next.png new file mode 100644 index 0000000000000000000000000000000000000000..45835bf89ac0eca3ad69c4d8397cd5edad2f8782 GIT binary patch literal 1150 zcmeAS@N?(olHy`uVBq!ia0y~yU{GdYVBqIqW?*25%xqI*U|?nl@Ck8cXkifO5m4+= z)SRMeILFXwj+56?ub{O-$!n9dw`RBOZRt7IGv(ZrrRSEey|#Aiy{*UY9Xt2@+_m@D zp1*(o{`>p?qhK@yhH?lPE>3vJz`($m*?YcQgLhV#D`pm6?j@g zAH{6mrq)*dKRi~1ZS~z7^NkdpisZ{3nd{~kXewWAFnhP&XYmW8&$~Chm~zy`VQSvD zpiO6bmL3%j^j6gt{9fvvI$I*+&fRvNNJrbRZld&ay>7ht(d60IjWbqMuGcxfX8)h-!d5wIS0j#Zdc(lL;9TMwQ4*Y=R#Ki= zl*-_sp{(hdo0y*Jo0y)NoULG@XQXGLU}>puV4-hdsE}NgSzJ=-kXu3NAIrA4U>Ny$kDMnuv&t)U99M06BF~bt=lC3t1z!y3OU-_; z>3=1k>J3(3i_72APIz-IDqpqc+E%+vGv;(%KfZ!%@4A+C&xmZ75-RagX8L}A{%x+r zX<~gz))PX{awr=ezabJ<%O$qq%HpE?3}IarYhrI#g}e)4`)(-lYr?KO{@fm?UzpsD z&F7x?_G;CcbIZ>^o0GCAMe@{JfwtZgS9s0dn=t$|`IrrC3yU6#%a-U6G$wZz0 z>m`@($9HNPdGJ4#pEvb;3eT@>Ck6%v=MvY5lHmNblJdl&R0anPWlhiA#Pn3(#PrPM zYy}fNBRvZROG|wN3w;Aah2)~l;*v^-+{)sT%w)aPV!f2og8aM^z2yAdiMtecFfcG^ zfsM;d&r2*RElOoDPD(L1F;6y4H8Hg?FgGwTOER!DNJ%kHHBU4$OExhPxjgw70|Nse jNLN5&dMbmFNrjP#wt==mQ8cF^C=xwg{an^LB{Ts5w*0vf literal 0 HcmV?d00001 diff --git a/v2/doc/html/images/prev.png b/v2/doc/html/images/prev.png new file mode 100644 index 0000000000000000000000000000000000000000..cf24654f8a9d6826bf5ee3f6b640d0b34f44d2ed GIT binary patch literal 1132 zcmeAS@N?(olHy`uVBq!ia0y~yU{GdYVBqIqW?*25%xqI*U|?nl@Ck8cXkifO5m4+= z)SRMeILFXwj+56?ub{O-*;})V_ZGM8ZRt7IGv(ZrrRSEey|(t)y<_K|pS$+{+Vl6% z-+zDqe-w;{zz`3CJ#UVzVqjokO!9VjVd!9$^cz3Lk2v~yID?2 zg{d0-`=76x`sl!sZQK^qBdRuuEdLPmbUTkt>9osNWqU z&qBe{Qs2Nr-@s5IxhS)^q|za`vbZEOSueF%FQv2~Kd(eDIX`#eF2x-T3=CRe<1*9p z5=%;pQW*@=EX)%V(+rXfOj3DJ87yAgr${wU6ATeb^ycE^w7cIp z?_W?xU6%d(bb~@Shbi-aG=ETBbm~(ogOmrW&bwBIxdt+K+A3yD;V_t}R>0LF5GN)x zed{W(mq$!1ciVpPy1}W+9bm)Xrgda~bSbG?a3DdjluYV+O9SdLnMpASqX+9EZY3c7C@7#N&OTq83NAIrA4U>si~GJ7Ut&0mS)MRMrP)TsYwQg=9VeOrfC+2Nk)mu rLdL(;85kJ&K)M1F(^DCYOe>5`v<1B4~iR4S3j3^P6tl1hi%%HopDWWCg4y_C{| z{JavqiARt`YJFJnVhX)qGzOMplv!L->5yAl zT#}irms+fsQd*FoSE84kpF44v;tmD|1}(60ndy0nC8b5F42emG<`xDZ$;L?r7Ky3J=GDKJX@I;2(iM=Hp2}coT4AYeplx7Y_5oxZgQu&X%Q~lo FCIGT9P(J_w literal 0 HcmV?d00001 diff --git a/v2/doc/html/images/up.png b/v2/doc/html/images/up.png new file mode 100644 index 0000000000000000000000000000000000000000..07634de26b325b09b6686543e3743ec58426e64b GIT binary patch literal 1111 zcmeAS@N?(olHy`uVBq!ia0y~yU{GdYVBqIqW?*25%xqI*U|?nl@Ck8cXkifO5m4+= z)SRMeILFXwj#Kj5t uv3Zg~HqRCY1_lN`kgkBl^i&38(+WdVZ3Arsp*puuASq8*KbLh*2~7YD7FD$X literal 0 HcmV?d00001 diff --git a/v2/doc/html/images/warning.png b/v2/doc/html/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..1c33db8f34a8b42b373179b46a2d8d8a10e061a9 GIT binary patch literal 1241 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4rT@hhU+WOo?>8NW(e>JaphoO5CF?5GB9W| zFc>m0I59AIF)#!%FhnshWHT@nGcZ&$Ftji*^e`|?VPKe2T|Fl#Xiikroa*YO3=B&x zEth(EEp2I8I%UezrAyZ`FswB+TsvjTRtAQxnwndCdbZA)vvujxty{P5WnkF5cJ1D+ zTaPg?91{>YCLwX`*s*gA4Ce#{&Phm|)6~4iz;I1d^V+p*_ZS%N-Mjakf#JEL;`8Uv z-!m}0=iqq%{{43bhVS3M|7T$MKMF=efJz}yVEuRs0|NtNlDE4HLkFv@2Ll7c3r`ov zkcwNmlWOyu3izvS7ejxP>R-!INP5f(XN|IS^C^Iyp?`SUk1vQO?s(K&l| zi|Nkt0@~*ymDp65*E-HED6u(s{Mfrxmah{JrgAMTIq)Du?nC5nnYTRgThA|azEdIl zD^uvV>~q(b?>`Fd;xnAbe7so1I$-&keKN}|vNNOCvX<~g{)wp7{&hR__v^cBU*Gq* zV3YS!cBPWsl#eNWc|~nAXWMOB8tQWBuXo=4>}cytyX_5F^Az{bVJ>7~U~n#RjVKAu zPb(=;EJ|f?&`{R&%uP&B^-WCAOwLv?(KFJsP_VSrH?Yt*FjPn`$}BFabjYnNF3C*R zOD)z*DJ{s)E742N&z-nSaR&nfgBIAh%=Em(lG377hGY|?B=Z!b6jL*k#Ka_13kwTN zLrZf@a|7cv1EVApQ-8txlNlHo_&~Y>64O%|j7%zwOtcNO4T_>U4H+017(8A5T-G@y GGywozG)2h( literal 0 HcmV?d00001 diff --git a/v2/doc/html/reference.css b/v2/doc/html/reference.css new file mode 100644 index 000000000..33ef65625 --- /dev/null +++ b/v2/doc/html/reference.css @@ -0,0 +1,76 @@ +th +{ + font-weight: bold; + text-align: center; +} + +.title +{ + font-weight: bold; + font-size: 2pc; + font-family: Times New Roman; + margin-bottom: 1pc; + text-align: center; +} + +.toc +{ + margin-left: 5%; + margin-right: 5%; + margin-bottom: 0pc; + width: 50%; +} + +.programlisting +{ + margin-left: 3pc; + width: 50%; +} + +.computeroutput +{ + font-family: Lucida Console; + font-size: 80%; +} + +.table +{ + text-align: center; + margin-bottom: 1pc; +} + +@media screen +{ + a{ color: blue; } + + th, .title + { + background-color: lightskyblue; + } + + .section-title + { + background-color: #EEE; + } + + .programlisting + { + background-color: #EED; + border: 0.1em ridge cyan; + padding: 1pc; + } + + .toc + { + border: 0.2em ridge lightcoral; + padding: 0.5pc; + background-color: #DDD; + } +} + +@media print +{ + a{ color: black; } +} + + diff --git a/v2/doc/src/advanced.xml b/v2/doc/src/advanced.xml new file mode 100644 index 000000000..d47216681 --- /dev/null +++ b/v2/doc/src/advanced.xml @@ -0,0 +1,831 @@ + + + + + Advanced + + This section will document + mostly high-level view of Boost.Build, mentioning appropriate + modules and rules. The on-line help system must be used to obtain + low-level documentation (see the help option). + +
+ Overview + + The most fundemental entity in Boost.Build is main + target. This is object that user want to construct from + sources and keep up to date with regard to those sources. Typical + examples of main targets are executable files and libraries. + + Main targets are grouped in projects. Their main + purpose is organization: related targets placed in one project, + can then be built together, or share some definitions. + + Main targets and projects are created as the result of reading + one or several Jamfiles. Each Jamfile is a file written in + Boost.Jam interpreted language, and typically contains calls to + functions provided by Boost.Build, which create main targets of + needed type, declare project attributes and access other + projects. The full list of functions provided by Boost.Build is + described below. + Of course, user can create his own functions, or it can directly + access Boost.Build internals from Jamfile, if builtin facilities are + not sufficient. + + Each main target, or project can be built in a number of ways, + say with optimization or without. We'll call such entities + "metatargets". To make Boost.Build produce any real targets, user + issues build request, + which specifies metatargets to be built, and properties to be + used. + + The properties are just (name,value) pairs that + describe various aspects of constructed objects, for example: + +<optimization>full <inlining>off + + + Given the built request, Boost.Build figures out the targets + needed for requested metatargets with requested properties, how + they can be created, and whether exising files can be reused. It + finally issues command to create needed files, automatically + converting properties into appropricate command line options. + +
+ +
+ Your first project and roadmap + + Creating your first project requires three steps: + + + Create an empty file called "Jamfile" + + + + Create an empty file called "project-root.jam" + + + + + Either set your BOOST_BUILD_PATH environment + variant to Boost.Build root, or create a "boost-build.jam" file + with the following content: + + +boost-build /path/to/boost.build ; + + + + + + + After that, you can run the "bjam" command in the directory + where you've created the files. Surely, it won't do anything, but + it will run without error, at least. Your next steps might + be: + + + + + Adding new main targets to the "Jamfile" file. The basic + syntax for declaring a main target is described below, and all builtin functions for + declaring main targets are listed. + + + + + + Creating subprojects. Create a directory, put new Jamfile + there, and move some main targets to that Jamfile, or declare + new ones. The projects + reference will help with this part. + + + + + + Customizing Boost.Build for your needs. You might have + additional tools you want to run, or just want different + extension for some file. The extender manual is waiting for + you. + + + + +
+ +
+ Main targets + + + Main target is a user-defined named + entity which can be build, for example a named executable file. + Declaring a main target is usually done using one of main target functions. + The user can also declare custom main target + function. + + Most main targets rules in Boost.Build use similiar + syntax: + + +function-name main-target-name + : sources + : requirements + : default-build + : usage-requirements + ; + + + + + + "main-target-name" is the name used to request the target + on command line and to use it from other main targets. Main + target name may contain alphanumeric characters and symbols '-' + and '_'; + + + + + + "sources" is the list of source files and other main + targets that must be combined. If source file is specified + using relative path, it's considered to be relative to the + source directory of the project where the path is used. See the + project rule + for information how to change source directory. + + + + + + "requirements" is the list of properties that must always + be present when this main target is built. + + + + + + "default-build" is the list of properties that will be used + unless some other value of the same feature is already + specified. + + + + + + "usage-requirements" is the list of properties that will be + propagated to all main targets that use this one, i.e. to all + dependedents. + + + + + Some main target rules have shorter list of parameters, and + you should consult their documentation for details. + + Building of the same main target can differ greatly from + platform to platform. For example, you might have different list + of sources for different compilers. Therefore it is possible to + invoke main target rules several times for a single main target. + For example: + + +exe a : a_gcc.cpp : <toolset>gcc ; +exe a : a.cpp ; + + + + Each call to the 'exe' rule defines a new main target + alternative for the main target a. + In this case, the first alternative will be used for the + gcc toolset, while the second alternative will + be used in other cases. See below for + details. + + + Sometime a main target is really needed only by some other + main target. E.g. a rule that declared test-suite uses a main + target that represent test, but those main targets are rarely + needed by themself. + + It possible to declare target inline, i.e. the "sources" + parameter may include call to other main rules. For example: + + +exe hello : hello.cpp + [ obj helpers : helpers.cpp : <optimization>off ] ; + + + +Will cause "helpers.cpp" to be always compiled without +optimization. It's possible to request main targets declared +inline, but since they are considered local, they are renamed to +"parent-main-target_name..main-target-name". In the example above, +to build only helpers, one should run "bjam hello..helpers". + + +
+ +
+ Projects + + Boost.Build considers every software it build as organized + into projects — modules which declare targets. + Projects are organized in a hierarchical structure, so each + project may have a single parent project and a number of + subprojects. + + Most often, projects are created as result of loading + Jamfile — files which are specially meant to + describe projects. Boost.Build will implicitly load Jamfile in + the invocation directory, and all Jamfiles referred by the first + one, creating the hierarchy of projects. + + The exact name of file that describes project is configurable. + By default, it's Jamfile, but can be changed by setting + global variables JAMFILE, for example in + boost-build.jam file. The value of the variable is a + list of regex patterns that are used when searching for Jamfile + in a directory. + + Every Boost.Build modules can decide to act as project and be + able to declare targets. For example, the + site-config.jam module can declare libraries + available on a given host, as described here. + + There are three things that can be put in Jamfile: + declarations of main targets, calls to a number of predefined + rules, and arbitrary user code. The predefined rules are listed + below: + + + + <tgroup cols="2"> + <thead> + <row> + <entry>Rule</entry> + + <entry>Semantic</entry> + </row> + </thead> + + <tbody> + <row> + <entry><link linkend= + "bbv2.advanced.projects.attributes.projectrule">project</link> + </entry> + + <entry>Define project attributes.</entry> + </row> + + <row> + <entry><link linkend= + "bbv2.advanced.projects.relationships.useprojectrule">use-project</link></entry> + + <entry>Make another project known.</entry> + </row> + + <row> + <entry><link linkend= + "bbv2.advanced.projects.relationships.buildprojectrule">build-project</link></entry> + + <entry>Build another project when this one is built.</entry> + </row> + + <row> + <entry><link linkend= + "bbv2.reference.buildprocess.explict">explicit</link></entry> + + <entry>States that the target should be built only by explicit + request.</entry> + </row> + + <row> + <entry>glob</entry> + + <entry>Takes a list of wildcards, and returns the list of files + which match any of the wildcards.</entry> + </row> + </tbody> + </tgroup> + </table> + + <para>Each project is also associated with <emphasis>project root</emphasis>. + That's a root for a tree of projects, which specifies some global + properties.</para> + + <section id="bbv2.advanced.projects.root"> + <title>Project root + + + Project root for a projects is the nearest parent directory + which contains a file called + project-root.jam. That file defines + certain properties which apply to all projects under project + root. It can: + + + + + configure toolsets, via call to toolset.using + + + + + + refer to other projects, via the use-project + rule + + + + + + declare constants, via the constant and + path-constant rules. + + + + + + + To facilitate declaration of simple projects, Jamfile and + project-root can be merged together. To achieve this effect, the + project root file should call the project rule. The + semantic is precisely the same as if the call was made in + Jamfile, except that project-root.jam will start serve as + Jamfile. The Jamfile in the directory of project-root.jam will be + ignored, and project-root.jam will be able to declare main + targets as usual. + + + +
+ Project attributes + + For each project, there are several attributes. + + Project id is a short way to denote a project, as + opposed to the Jamfile's pathname. It is a hierarchical path, + unrelated to filesystem, such as "boost/thread". Target references make use of project ids to + specify a target. + + Source location specifies the directory where sources + for the project are located. + + Project requirements are requirements that apply to + all the targets in the projects as well as all subprojects. + + Default build is the build request that should be + used when no build request is specified explicitly. + + + The default values for those attributes are + given in the table below. In order to affect them, Jamfile may + call the project rule. The rule has this + syntax: + + +project id : <attributes> ; + + + +Here, attributes is a sequence of (attribute-name, +attribute-value) pairs. The list of attribute names along with its +handling is also shown in the table below. For example, it it +possible to write: + + + +project tennis + : requirements <threading>multi + : default-build release + ; + + +
+ + <tgroup cols="4"> + <thead> + <row> + <entry>Attribute</entry> + + <entry>Name for the 'project' rule</entry> + + <entry>Default value</entry> + + <entry>Handling by the 'project' rule</entry> + </row> + </thead> + + <tbody> + + <row> + <entry>Project id</entry> + + <entry>none</entry> + + <entry>none</entry> + + <entry>Assigned from the first parameter of the 'project' rule. + It is assumed to denote absolute project id.</entry> + </row> + + <row> + <entry>Source location</entry> + + <entry><literal>source-location</literal></entry> + + <entry>The location of jamfile for the project</entry> + + <entry>Sets to the passed value</entry> + </row> + + <row> + <entry>Requirements</entry> + + <entry><literal>requirements</literal></entry> + + <entry>The parent's requirements</entry> + + <entry>The parent's requirements are refined with the passed + requirement and the result is used as the project + requirements.</entry> + </row> + + <row> + <entry>Default build</entry> + + <entry><literal>default-build</literal></entry> + + <entry>none</entry> + + <entry>Sets to the passed value</entry> + </row> + + <row> + <entry>Build directory</entry> + + <entry><literal>build-dir</literal></entry> + + <entry>If parent has a build dir set, the value of it, joined + with the relative path from parent to the current project. + Otherwise, empty</entry> + + <entry>Sets to the passed value, interpreted as relative to the + project's location.</entry> + </row> + </tbody> + </tgroup> + </table> + </section> + + <section id="bbv2.advanced.projects.relationships"> + <title>Project relationship + + There are three kinds of project relationships. + + First is parent-child. This relationship is established + implicitly: parent directories of a project are searched, and the + first found Jamfile is assumed to define the parent project. The + parent-child relationship affects only attribute values for the + child project. + + + Second is build relationship. Some + project may request to recursively build other projects. Those + project need not be child projects. The build-project + rule is used for that: + + build-project src ; + + + + The third kind is the 'use' + relationship. In means that one project uses targets from + another. It is possible to just refer to target in other projects + using target id. However, if target id uses project id, it is + required that the project id is known. The + use-project + rule is employed to guarantee that. + + + +use-project ( id : location ) + + + +It loads the project at the specified location, which makes +its project id available in the project which invokes the rule. It +is required that the id parameter passed to the +use-project rule be equal to the id that the loaded +project declared. At this moment, the id paremeter +should be absolute project id. + + + + +
+ Target identifiers and references + + Target identifier is used to denote a + target. The syntax is: + + +target-id -> (project-id | target-name | file-name ) + | (project-id | directory-name) "//" target-name +project-id -> path +target-name -> path +file-name -> path +directory-name -> path + + + +This grammar allows some elements to be recognized as either + + + + + project id (at this point, all project ids start with slash). + + + + + + name of target declared in current Jamfile (note that target + names may include slash). + + + + + + a regular file, denoted by absolute name or name relative to + project's sources location. + + + + + To determine the real meaning a check is made if project-id + by the specified name exists, and then if main target of that + name exists. For example, valid target ids might be: + + +a -- target in current project +lib/b.cpp -- regular file +/boost/thread -- project "/boost/thread" +/home/ghost/build/lr_library//parser -- target in specific project + + + + + Rationale:Target is separated from project by special + separator (not just slash), because: + + + + + It emphasises that projects and targets are different things. + + + + + + It allows to have main target names with slashes. + + + + + + + + Target reference is used to + specify a source target, and may additionally specify desired + properties for that target. It has this syntax: + + +target-reference -> target-id [ "/" requested-properties ] +requested-properties -> property-path + + + +For example, + + +exe compiler : compiler.cpp libs/cmdline/<optimization>space ; + + +would cause the version of cmdline library, +optimized for space, to be linked in even if the +compiler executable is build with optimization for +speed. + +
+
+ Builtin facilities + +
+ Main targets + + + exe + + + + Creates a regular executable file. Sources must be either + object files or libraries, and sources of different types + will be converted to accepted types automatically. + + + + + lib + + + Creates a library file. Depending on the value of + <link> feature the library will be either static or + shared. Like with "exe", sources will be converted either to + objects or libraries. + + The handling of libraries in sources depends on whether + linking is static or shared. For shared linking, libraries + will be linked in. For static linking the library sources + will not be linked in, since it's not possible, and will be + passed on. Other main target which depend on this one will + see those libraries and link to it. Therefore, putting + library in sources of other library works in all cases. + + + alias + + + + Builds all the source targets and returns them unmodified. + Please run "bjam --help alias" for more details. + + + + stage + + + + Copies a number of targets to a single directory. The + primary purpose is installing binaries. Please run "bjam --help + stage" for more details. + + + + unit-test (from module "testing") + + + + Creates an executable file and runs it. Build won't succeed + unless the executable runs successfully. The rule is usefull + for creating test program which should be rerun whenever any + dependency changes. + + + + +
+ +
+ Features + + + variant + + + + The feature which combines several low-level features in + order to make building most common variants simple. + + + Allowed values: debug, release, + profile + + The value debug expands to + + +<optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on + + + The value release expands to + + +<optimization>speed <debug-symbols>off <inlining>full <runtime-debugging>off + + + The value profile expands to the same as + release, plus: + + +<profiling>on <debug-symbols>on + + + Rationale: Runtime debugging is on in debug build + so suit expectations of people used various IDEs. It's + assumed other folks don't have any specific expectation in + this point. + + + link + + + + Feature which controls how libraries are built. + + + Allowed values: shared, + static + + + library + + + + For exe and lib main targets, the <library>X feature + is equvivalent to putting X in the list of sources. The feature + is sometimes more convenient: you can put <library>X in + the requirements for a project and it will be linked to all + executables. + + + + + use + + + + Causes the target referenced by the value of this feature + to be constructed and adds it's usage requirements to build + properties. The constructed targets are not used in any other + way. The primary use case is when you use some library and want + it's usage requirements (such as include paths) to be applied, + but don't want to link to the library. + + + + + dll-path + + + + Specify a path where dynamic libraries should be found at + where executable or shared library is run. This feature + directly affects binaries with the gcc compiler, allowing them + to pick specific libraries, and ignoring all environment + settings. On other toolsets, the binary still requires proper + environment settings to be run. However, Boost.Build tools + which run executables will notice dll-path settings and create + this environment automatically. + + + + hardcode-dll-paths + + + + Controls automatic generation of dll-path properties. + + + Allowed values: off, on When this + property is on, usage requirements for each library will + include additional dll-path propertry, with the path the the + generated library file. This allows to run executables + without placing all the dependent libraries to a single + location. + + + +
+
+ + diff --git a/v2/doc/src/architecture.xml b/v2/doc/src/architecture.xml new file mode 100644 index 000000000..79bde6fed --- /dev/null +++ b/v2/doc/src/architecture.xml @@ -0,0 +1,434 @@ + + + + + Boost.Build v2 architecture + + + This document is work-in progress. Don't expect much from it + yet. + + +
+ Targets + + There are two user-visible kinds of targets in Boost.Build. + First are "abstract" — they correspond to things declared + by user, for example, projects and executable files. The primary + thing about abstract target is that it's possible to request them + to be build with a particular values of some properties. Each + combination of properties may possible yield different set of + real file, so abstract target do not have a direct correspondence + with files. + + File targets, on the contary, are associated with concrete + files. Dependency graphs for abstract targets with specific + properties are constructed from file targets. User has no was to + create file targets, however it can specify rules that detect + file type for sources, and also rules for transforming between + file targets of different types. That information is used in + constructing dependency graph, as desribed in the "next section". + [ link? ] Note:File targets are not + the same as targets in Jam sense; the latter are created from + file targets at the latest possible moment. Note:"File + target" is a proposed name for what we call virtual targets. It + it more understandable by users, but has one problem: virtual + targets can potentially be "phony", and not correspond to any + file. + +
+ Dependency scanning + + Dependency scanning is the process of finding implicit + dependencies, like "#include" statements in C++. The requirements + for right dependency scanning mechanism are: + + + + + Support for different scanning algorithms. C++ and XML have + quite different syntax for includes and rules for looking up + included files. + + + + + + Ability to scan the same file several times. For example, + single C++ file can be compiled with different include + paths. + + + + + + Proper detection of dependencies on generated files. + + + + + + Proper detection of dependencies from generated file. + + + + +
+ Support for different scanning algorithms + + Different scanning algorithm are encapsulated by objects + called "scanners". Please see the documentation for "scanner" + module for more details. + +
+ +
+ Ability to scan the same file several times + + As said above, it's possible to compile a C++ file twice, with + different include paths. Therefore, include dependencies for + those compilations can be different. The problem is that bjam + does not allow several scans of the same target. + + The solution in Boost.Build is straigtforward. When a virtual + target is converted to bjam target (via + virtual-target.actualize method), we specify the scanner + object to be used. The actualize method will create different + bjam targets for different scanners. + + All targets with specific scanner are made dependent on target + without scanner, which target is always created. This is done in + case the target is updated. The updating action will be + associated with target without scanner, but if sources for that + action are touched, all targets — with scanner and without + should be considered outdated. + + For example, assume that "a.cpp" is compiled by two compilers + with different include path. It's also copied into some install + location. In turn, it's produced from "a.verbatim". The + dependency graph will look like: + + +a.o (<toolset>gcc) <--(compile)-- a.cpp (scanner1) ----+ +a.o (<toolset>msvc) <--(compile)-- a.cpp (scanner2) ----| +a.cpp (installed copy) <--(copy) ----------------------- a.cpp (no scanner) + ^ + | + a.verbose --------------------------------+ + + +
+
+ Proper detection of dependencies on generated files. + + This requirement breaks down to the following ones. + + + + + If when compiling "a.cpp" there's include of "a.h", the + "dir" directory is in include path, and a target called "a.h" + will be generated to "dir", then bjam should discover the + include, and create "a.h" before compiling "a.cpp". + + + + + + Since almost always Boost.Build generates targets to a + "bin" directory, it should be supported as well. I.e. in the + scanario above, Jamfile in "dir" might create a main target, + which generates "a.h". The file will be generated to "dir/bin" + directory, but we still have to recornize the dependency. + + + + + The first requirement means that when determining what "a.h" + means, when found in "a.cpp", we have to iterate over all + directories in include paths, checking for each one: + + + + + If there's file "a.h" in that directory, or + + + + + + If there's a target called "a.h", which will be generated + to that directory. + + + + + Classic Jam has built-in facilities for point (1) above, but + that's not enough. It's hard to implement the right semantic + without builtin support. For example, we could try to check if + there's targer called "a.h" somewhere in dependency graph, and + add a dependency to it. The problem is that without search in + include path, the semantic may be incorrect. For example, one can + have an action which generated some "dummy" header, for system + which don't have the native one. Naturally, we don't want to + depend on that generated header on platforms where native one is + included. + + There are two design choices for builtin support. Suppose we + have files a.cpp and b.cpp, and each one includes header.h, + generated by some action. Dependency graph created by classic jam + would look like: + + +a.cpp -----> <scanner1>header.h [search path: d1, d2, d3] + + + <d2>header.h --------> header.y + [generated in d2] + +b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4] + + + +In this case, Jam thinks all header.h target are not +realated. The right dependency graph might be: + + +a.cpp ---- + \ + \ + >----> <d2>header.h --------> header.y + / [generated in d2] + / +b.cpp ---- + + +or + + +a.cpp -----> <scanner1>header.h [search path: d1, d2, d3] + | + (includes) + V + <d2>header.h --------> header.y + [generated in d2] + ^ + (includes) + | +b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4] + + + + +The first alternative was used for some time. The problem +however is: what include paths should be used when scanning +header.h? The second alternative was suggested by Matt Armstrong. +It has similiar effect: add targets which depend on +<scanner1>header.h will also depend on <d2>header.h. +But now we have two different target with two different scanners, +and those targets can be scanned independently. The problem of +first alternative is avoided, so the second alternative is +implemented now. + + + The second sub-requirements is that targets generated to "bin" + directory are handled as well. Boost.Build implements + semi-automatic approach. When compiling C++ files the process + is: + + + + + The main target to which compiled file belongs is found. + + + + + + All other main targets that the found one depends on are + found. Those include main target which are used as sources, or + present as values of "dependency" features. + + + + + + All directories where files belonging to those main target + will be generated are added to the include path. + + + + + After this is done, dependencies are found by the approach + explained previously. + + Note that if a target uses generated headers from other main + target, that main target should be explicitly specified as + dependency property. It would be better to lift this requirement, + but it seems not very problematic in practice. + + For target types other than C++, adding of include paths must + be implemented anew. + +
+
+ Proper detection of dependencies from generated files + + Suppose file "a.cpp" includes "a.h" and both are generated by + some action. Note that classic jam has two stages. In first stage + dependency graph graph is build and actions which should be run + are determined. In second stage the actions are executed. + Initially, neither file exists, so the include is not found. As + the result, jam might attempt to compile a.cpp before creating + a.h, and compilation will fail. + + The solution in Boost.Jam is to perform additional dependency + scans after targets are updated. This break separation between + build stages in jam — which some people consider a good + thing — but I'm not aware of any better solution. + + In order to understand the rest of this section, you better + read some details about jam dependency scanning, available + + at this link. + + Whenever a target is updated, Boost.Jam rescans it for + includes. Consider this graph, created before any actions are + run. + + +A -------> C ----> C.pro + / +B --/ C-includes ---> D + + + +Both A and B have dependency on C and C-includes (the latter +dependency is not shown). Say during building we've tried to create +A, then tried to create C and successfully created C. + + + In that case, the set of includes in C might well have + changed. We do not bother to detect precisely which includes were + added or removed. Instead we create another internal node + C-includes-2. Then we determine what actions should be run to + update the target. In fact this mean that we perform logic of + first stage while already executing stage. + + After actions for C-includes-2 are determined, we add + C-includes-2 to the list of A's dependents, and stage 2 proceeds + as usual. Unfortunately, we can't do the same with target B, + since when it's not visited, C target does not know B depends on + it. So, we add a flag to C which tells and it was rescanned. When + visiting B target, the flag is notices and C-includes-2 will be + added to the list of B's dependencies. + + Note also that internal nodes are sometimes updated too. + Consider this dependency graph: + + +a.o ---> a.cpp + a.cpp-includes --> a.h (scanned) + a.h-includes ------> a.h (generated) + | + | + a.pro <-------------------------------------------+ + + + Here, out handling of generated headers come into play. Say + that a.h exists but is out of date with respect to "a.pro", then + "a.h (generated)" and "a.h-includes" will be marking for + updating, but "a.h (scanned)" won't be marked. We have to rescan + "a.h" file after it's created, but since "a.h (generated)" has no + scanner associated with it, it's only possible to rescan "a.h" + after "a.h-includes" target was updated. + + Tbe above consideration lead to decision that we'll rescan a + target whenever it's updated, no matter if this target is + internal or not. + + + + The remainder of this document is not indended to be read at + all. This will be rearranged in future. + + + +
+ File targets + + + As described above, file targets corresponds + to files that Boost.Build manages. User's may be concerned about + file targets in three ways: when declaring file target types, + when declaring transformations between types, and when + determining where file target will be placed. File targets can + also be connected with actions, that determine how the target is + created. Both file targets and actions are implemented in the + virtual-target module. + + +
+ Types + + A file target can be given a file, which determines + what transformations can be applied to the file. The + type.register rule declares new types. File type can + also be assigned a scanner, which is used to find implicit + dependencies. See "dependency scanning" [ link? ] below. +
+
+ +
+ Target paths + + To distinguish targets build with different properties, they + are put in different directories. Rules for determining target + paths are given below: + + + + + All targets are placed under directory corresponding to the + project where they are defined. + + + + + + Each non free, non incidental property cause an additional + element to be added to the target path. That element has the + form <feature-name>-<feature-value> for + ordinary features and <feature-value> for + implicit ones. [Note about composite features]. + + + + + + If the set of free, non incidental properties is different + from the set of free, non incidental properties for the project + in which the main target that uses the target is defined, a + part of the form main_target-<name> is added to + the target path. Note:It would be nice to completely + track free features also, but this appears to be complex and + not extremely needed. + + + + + For example, we might have these paths: + + +debug/optimization-off +debug/main-target-a + + +
+
+
+
+
+ diff --git a/v2/doc/src/catalog.xml b/v2/doc/src/catalog.xml new file mode 100644 index 000000000..26e16145d --- /dev/null +++ b/v2/doc/src/catalog.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/v2/doc/src/extending.xml b/v2/doc/src/extending.xml new file mode 100644 index 000000000..eff223486 --- /dev/null +++ b/v2/doc/src/extending.xml @@ -0,0 +1,128 @@ + + + + + Extender Manual + +
+ Introduction + + This document explains how to extend Boost.Build to accomodate + your local requirements. Let's start with quite simple, but + realistic example. + + Say you're writing an application which generates C++ code. If + you ever did this, you know that it's not nice. Embedding large + portions of C++ code in string literals is very awkward. A much + better solution is: + + + + + Write the template of the code to be generated, leaving + placeholders at the points which will change + + + + + + Access the template in your application and replace + placeholders with appropriate text. + + + + + Write the result. + + + + It's quite easy to archive. You write special verbatim files, + which are just C++, except that the very first line of the file + gives a name of variable that should be generated. A simple tool + is created which takes verbatim file and creates a cpp file with + a single char* variable, which name is taken from the first line + of verbatim file, and which value is properly quoted content of + the verbatim file. + + Let's see what Boost.Build can do. + + First off, Boost.Build has no idea about "verbatim files". So, + you must register a new type. The following code does it: + + +import type ; +type.register VERBATIM : verbatim ; + + + The first parameter to 'type.register' gives the name of + declared type. By convention, it's uppercase. The second + parameter is suffix for this type. So, if Boost.Build sees + "code.verbatim" in the list of sources, it knows that it's of + type VERBATIM. + + Lastly, you need a tool to convert verbatim files to C++. Say + you've sketched such a tool in Python. Then, you have to inform + Boost.Build about the tool. The Boost.Build concept which + represents a tool is generator. + + First, you say that generator 'inline-file' is able to convert + VERBATIM type into C++: + + +import generators ; +generators.register-standard verbatim.inline-file : VERBATIM : CPP ; + + + Second, you must specify the commands to be run to actually + perform convertion: + + +actions inline-file +{ + "./inline-file.py" $(<) $(>) +} + + + + Now, we're ready to tie it all together. Put all the code + above in file "verbatim.jam", add "import verbatim ;" to + "project-root.jam", and it's possible to write the following in + Jamfile: + + +exe codegen : codegen.cpp class_template.verbatim usage.verbatim ; + + + +The verbatim files will be automatically converted into C++ +and linked it. + + + The complete code is available in example/customization + directory. + +
+
+ Target types + +
+ +
+ Tools + +
+ +
+ Main target rules + +
+ +
+ Scanners + +
+
diff --git a/v2/doc/src/faq.xml b/v2/doc/src/faq.xml new file mode 100644 index 000000000..5d7c5a1ca --- /dev/null +++ b/v2/doc/src/faq.xml @@ -0,0 +1,82 @@ + + + + + Frequently Asked Questions + +
+ + I'm getting "Duplicate name of actual target" error. What + does it mean? + + + + The most likely case is that you're trying to + compile the same file twice, with almost the same, + but differing properties. For example: + + +exe a : a.cpp : <include>/usr/local/include ; +exe b : a.cpp ; + + + + + + The above snippet requires two different compilations + of 'a.cpp', which differ only in 'include' property. + Since the 'include' property is free, Boost.Build + can't generate two ojects files into different directories. + On the other hand, it's dangerous to compile the file only + once -- maybe you really want to compile with different + includes. + + + + To solve this issue, you need to decide if file should + be compiled once or twice. + + + + Two compile file only once, make sure that properties + are the same: + + +exe a : a.cpp : <include>/usr/local/include ; +exe b : a.cpp : <include>/usr/local/include ; + + + + If changing the properties is not desirable, for example + if 'a' and 'b' target have other sources which need + specific properties, separate 'a.cpp' into it's own target: + + +obj a_obj : a.cpp : <include>/usr/local/include ; +exe a : a_obj ; + + + + To compile file twice, you can make the object file local + to the main target: + + + exe a : [ obj a_obj : a.cpp ] : <include>/usr/local/include ; + exe b : [ obj a_obj : a.cpp ] ; + + + + + + A good question is why Boost.Build can't use some of the above + approaches automatically. The problem is that such magic would + require additional implementation complexities and would only + help in half of the cases, while in other half we'd be silently + doing the wrong thing. It's simpler and safe to ask user to + clarify his intention in such cases. + + +
+ +
diff --git a/v2/doc/src/howto.xml b/v2/doc/src/howto.xml new file mode 100644 index 000000000..dcb44670f --- /dev/null +++ b/v2/doc/src/howto.xml @@ -0,0 +1,33 @@ + + + + + How to use this document + + + If you've just found out about Boost.Build V2 and want to know + if it will work for you, start with . You can continue with the . When you're ready to try Boost.Build + in practice, go to . + + + + If you are about to use Boost.Build on your project, or already + using it and have a problem, look at . + + + + If you're trying to build a project which uses Boost.Build, + look at and then read about + . + + + + Finally, if nothing applies to you, write to our mailing list, + telling what information you'd like to know. + + + diff --git a/v2/doc/src/install.xml b/v2/doc/src/install.xml new file mode 100644 index 000000000..d164a5907 --- /dev/null +++ b/v2/doc/src/install.xml @@ -0,0 +1,111 @@ + + + + + Installation + + + Assuming you're installing Boost.Build from released source + distribution, the following steps are needed. All paths are + given relatively to Boost.Build root directory, which is the + directory with the document you are reading. + + + + + + Go to "jam_src" directory and build Boost.Jam. Two convenient + scripts are provided, "build.sh" (for Unix systems) and + "build.bat" (for Windows). Run the appropriate one and + Boost.Jam will be built to directory + bin.{platform_name}.. The Boost.Jam documentation has + more details in case you need them. + + + + + + Place the Boost.Jam binary, called "bjam" or "bjam.exe", + somewhere in your PATH. Go to the root + directory of Boost.Build and run "bjam --version". You should + get + + Boost.Build V2 (Milestone N) + + (where N is the version you've downloaded). + + + + + + Configure toolsets to use. Open the + user-config.jam file and follow + instructions there to specify what compiles/libraries you + have and where they are located. + + + + + + You should now be able to go to + example/hello, and run + bjam there. A simple application will be + built. You can also play with other projects in + example. + + + + + + + If you use Boost distribution, or Boost CVS, the Boost.Build + root is located at $boost_root/tools/build/v2 + and the installation steps are the same. However, don't skip + the bjam rebuilding step, even if you have a previous version. + CVS version of Boost.Build requires CVS version of Boost.Jam. + + + + When starting a new project which uses Boost.Build, you need + to make sure that build system can be found. There are two + ways. + + + + + + Set enviromnetal variable BOOST_BUILD_PATH + to the absolute path to Boost.Build installation directory. + + + + + + Create, at the top of your project, a file called + boost-build.jam, with a single line: + + +boost-build /path/to/boost.build ; + + + + + + + If you're trying to use Boost.Build V2 on Boost itself, please + note that when building Boost, V1 is used by default. You'd have + to add command line option to all "bjam" + invocations. + + diff --git a/v2/doc/src/recipes.xml b/v2/doc/src/recipes.xml new file mode 100644 index 000000000..33aa1df6a --- /dev/null +++ b/v2/doc/src/recipes.xml @@ -0,0 +1,35 @@ + + + + + Boost Build System V2 recipes + +
+ Targets in site-config.jam + + It is desirable to declare standard libraries available on a + given system. Putting target declaration in Jamfile is not really + good, since locations of the libraries can vary. The solution is + to put the following to site-config.jam. + + +import project ; +project.initialize $(__name__) ; +project site-config ; +lib zlib : : <name>z ; + + + The second line allows this module to act as project. The + third line gives id to this project — it really has no location + and cannot be used otherwise. The fourth line just declares a + target. Now, one can write + + +exe hello : hello.cpp /site-config//zlib ; + + + in any Jamfile. + +
+
diff --git a/v2/doc/src/reference.xml b/v2/doc/src/reference.xml new file mode 100644 index 000000000..400cdbac5 --- /dev/null +++ b/v2/doc/src/reference.xml @@ -0,0 +1,1037 @@ + + + + + Detailed reference + +
+ Features and properties + +
+ Definitions + + A feature is a normalized (toolset-independent) + aspect of a build configuration, such as whether inlining is + enabled. Feature names may not contain the '>' + character. + + + + Each feature in a build configuration has one or more + associated values. Feature values for non-free features + may not contain the '<', ':', or + '=' characters. Feature values for free features may not + contain the '<' character. + + A property is a (feature,value) pair, expressed as + <feature>value. + + A subfeature is a feature which only exists in the + presence of its parent feature, and whose identity can be derived + (in the context of its parent) from its value. A subfeature's + parent can never be another subfeature. Thus, features and their + subfeatures form a two-level hierarchy. + + A value-string for a feature F is a string of + the form + value-subvalue1-subvalue2...-subvalueN, where + value is a legal value for F and + subvalue1...subvalueN are legal values of some + of F's subfeatures. For example, the properties + <toolset>gcc <toolset-version>3.0.1 can be + expressed more conscisely using a value-string, as + <toolset>gcc-3.0.1. + + A property set is a set of properties (i.e. a + collection without dublicates), for instance: + <toolset>gcc <runtime-link>static. + + A property path is a property set whose elements have + been joined into a single string separated by slashes. A property + path representation of the previous example would be + <toolset>gcc/<runtime-link>static. + + A build specification is a property set which fully + describes the set of features used to build a target. + +
+
+ Property Validity + + + For free + features, all values are valid. For all other features, + the valid values are explicitly specified, and the build + system will report an error for the use of an invalid + feature-value. Subproperty validity may be restricted so + that certain values are valid only in the presence of + certain other subproperties. For example, it is possible + to specify that the <gcc-target>mingw + property is only valid in the presence of + <gcc-version>2.95.2. + + +
+
+ Feature Attributes + + Each feature has a collection of zero or more of the following + attributes. Feature attributes are low-level descriptions of how + the build system should interpret a feature's values when they + appear in a build request. We also refer to the attributes of + properties, so that a incidental property, for example, is + one whose feature is has the incidental attribute. + + + + incidental + + Incidental features are assumed not to affect build + products at all. As a consequence, the build system may use + the same file for targets whose build specification differs + only in incidental features. A feature which controls a + compiler's warning level is one example of a likely + incidental feature. + + Non-incidental features are assumed to affect build + products, so the files for targets whose build specification + differs in non-incidental features are placed in different + directories as described in "target paths" below. [ where? ] + + + + + + + propagated + + + Features of this kind are + propagated to dependencies. That is, if a main target is built using a + propagated + property, the build systems attempts to use the same property + when building any of its dependencies as part of that main + target. For instance, when an optimized exectuable is + requested, one usually wants it to be linked with optimized + libraries. Thus, the <optimization> feature is + propagated. + + + + + + free + + + Most features have a finite set of allowed values, and can + only take on a single value from that set in a given build + specification. Free features, on the other hand, can have + several values at a time and each value can be an arbitrary + string. For example, it is possible to have several + preprocessor symbols defined simultaneously: + + +<define>NDEBUG=1 <define>HAS_CONFIG_H=1 + + + + + + optional + + An optional feature is a feature which is not required to + appear in a build specification. Every non-optional non-free + feature has a default value which is used when a value for + the feature is not otherwise specified, either in a target's + requirements or in the user's build request. [A feature's + default value is given by the first value listed in the + feature's declaration. -- move this elsewhere - dwa] + + + + symmetric + + A symmetric feature's default value is not automatically + included in build variants. Normally + a feature only generates a subvariant directory when its + value differs from the value specified by the build variant, + leading to an assymmetric subvariant directory structure for + certain values of the feature. A symmetric feature, when + relevant to the toolset, always generates a corresponding + subvariant directory. + + + + path + + The value of a path feature specifies a path. The path is + treated as relative to the directory of Jamfile where path + feature is used and is translated appropriately by the build + system when the build is invoked from a different + directory + + + + implicit + + Values of implicit features alone identify the feature. + For example, a user is not required to write + "<toolset>gcc", but can simply write "gcc". Implicit + feature names also don't appear in variant paths, although + the values do. Thus: bin/gcc/... as opposed to + bin/toolset-gcc/.... There should typically be only a few + such features, to avoid possible name clashes. + + + + composite + + Composite features actually correspond to groups of + properties. For example, a build variant is a composite + feature. When generating targets from a set of build + properties, composite features are recursively expanded and + added to the build property set, so rules can find + them if neccessary. Non-composite non-free features override + components of composite features in a build property set. + + + + link-incompatible + + See below. + + + + dependency + + The value of dependency feature if a target reference. + When used for building of a main target, the value of + dependency feature is treated as additional dependency. + + For example, dependency features allow to state that + library A depends on library B. As the result, whenever an + application will link to A, it will also link to B. + Specifying B as dependency of A is different from adding B to + the sources of A. + + + + Features which are neither free nor incidental are called + base features. + + TODO: document active features.. + +
+
+ Feature Declaration + + The low-level feature declaration interface is the + feature rule from the + feature module: + + +rule feature ( name : allowed-values * : attributes * ) + + + A feature's allowed-values may be extended wit The build +system will provide high-level rules which define features in terms +of valid and useful combinations of attributes. + + +
+
+ +
+ Build Variants + + +A build variant, or (simply variant) is a special kind of composite + feature which automatically incorporates the default values of + features that . Typically you'll want at least two separate + variants: one for debugging, and one for your release code. [ + Volodya says: "Yea, we'd need to mention that it's a composite + feature and describe how they are declared, in pacticular that + default values of non-optional features are incorporated into + build variant automagically. Also, do we wan't some variant + inheritance/extension/templates. I don't remember how it works in + V1, so can't document this for V2.". Will clean up soon -DWA ] + + +
+ Link compatible and incompatible properties + + When the build system tries to generate a target (such as + library dependency) matching a given build request, it may find + that an exact match isn't possible — for example, the + target may impose additonal build requirements. We need to + determine whether a buildable version of that target can actually + be used. + + The build request can originate in many ways: it may come + directly from the user's command-line, from a dependency of a + main target upon a library, or from a dependency of a target upon + an executable used to build that target, for example. For each + way, there are different rules whether we can use a given + subvariant or not. The current rules are described below. + + Two property sets are called link-compatible when + targets with those property sets can be used interchangably. In + turn, two property sets are link compatible when there's no + link-incompatible feature which has different values in those + property sets. + + When building of a main target is requested from a command + line or some project, link-compatibility is not considered. When + building is requested by other main target, via sources or + dependency properties, the requested and actual property sets + must be link-compatible, otherwise a warning is produced. + + Rationale:Link-compatibility is not considered when + main target is requested by a project, because it causes problems + in practice. For example, some parts of a project might be + single-threaded, while others — multi-threaded. They are + not link-compatible, but they are not linked, either. So, there's + no need to issue error or warning. The errors used to be + generated, and only caused problems. + +
+
+ Definition of property refinement + + When a target with certain properties is requested, and that + target requires some set of properties, it is needed to find the + set of properties to use for building. This process is called + property refinement and is performed by these rules + + + + + If original properties and required properties are not + link-compatible, refinement fails. + + + + + + Each property in the required set is added to the original + property set + + + + + + If the original property set includes property with a different + value of non free feature, that property is removed. + + + +
+ +
+ Conditional properties + + Sometime it's desirable to apply certain requirements only for + specific combination of other properties. For example, one of + compilers that you use issues a poinless warning that you want to + suppress by passing a command line option to it. You would not + want to pass that option to other compilers. Condititional + properties allow to do that. Their systax is: + + +property ( "," property ) * ":" property + + + +For example, the problem above would be solved by: + + +exe hello : hello.cpp : <toolset>yfc:<cxxflags>-disable-pointless-warning ; + + + +
+
+ +
+ Initialization + + bjam's first job upon startup is to load the Jam code which + implements the build system. To do this, it searches for a file + called "boost-build.jam", first in the invocation directory, then + in its parent and so forth up to the filesystem root, and finally + in the directories specified by the environment variable + BOOST_BUILD_PATH. When found, the file is interpreted, and should + specify the build system location by calling the boost-build + rule: + + +rule boost-build ( location ? ) + + + +If location is a relative path, it is treated as relative to +the directory of boost-build.jam. The directory specified by +location and directories in BOOST_BUILD_PATH are then searched for +a file called bootstrap.jam which is interpreted and is expected to +bootstrap the build system. This arrangement allows the build +system to work without any command-line or environment variable +settings. For example, if the build system files were located in a +directory "build-system/" at your project root, you might place a +boost-build.jam at the project root containing: + + +boost-build build-system ; + + +In this case, running bjam anywhere in the project tree will +automatically find the build system. + + The default "bootstrap.jam", after loading some standard + definitions, loads two files, which can be provided/customised by + user: "site-config.jam" and "user-config.jam". + + Locations where those files a search are summarized below: + +
+ Search paths for configuration files + + + + + + + + site-config.jam + + user-config.jam + + + + + + + Linux + + + /etc + $HOME + $BOOST_BUILD_PATH + + + + $HOME + $BOOST_BUILD_PATH + + + + + Windows + + + $SystemRoot + $HOME + $BOOST_BUILD_PATH + + + + $HOME + $BOOST_BUILD_PATH + + + + +
+ + +Boost.Build comes with default versions of those files, + which can serve as templates for customized versions. + + +
+
+ Command line + + The command line may contain: + + + Jam options, + + Boost.Build options, + + Command line arguments + + +
+ Command line arguments + + + Command line arguments specify targets and build + request using the following rules. + + + + + + An argument which does not contain slashes or the "=" + symbol is either a value of an implicit feature, or target to + be built. It is taken to be value of a feature if appropriate + feature exists. Otherwise, it is considered a target id. Special target name "clean" + has the same effect as "--clean" option. + + + + + + An argument with either slashes or the "=" symbol specifies + a number of build + request + elements. In the simplest form, it's just a set of properties, + separated by slashes, which become a single build request + element, for example: + + +borland/<runtime-link>static + + +More complex form is used to save typing. For example, +instead of + + +borland/runtime-link=static borland/runtime-link=dynamic + + +one can use + + +borland/runtime-link=static,dynamic + + +Exactly, the conversion from argument to build request +elements is performed by (1) splitting the argument at each slash, +(2) converting each split part into a set of properties and (3) +taking all possible combination of the property sets. Each split +part should have the either the form + + +feature-name=feature-value1[","feature-valueN]* + + +or, in case of implict feature + + +feature-value1[","feature-valueN;]* + + +and will be converted into property set + + +<feature-name>feature-value1 .... <feature-name>feature-valueN + + + + + + + +For example, the command line + + +target1 debug gcc/runtime-link=dynamic,static + + +would cause target called target1 to be rebuild in +debug mode, except that for gcc, both dynamically and statically +linked binaries would be created. + + +
+
+ Command line options + + All of the Boost.Build options start with the "--" prefix. + They are described in the following table. + + + Command line options + + + + + Option + + Description + + + + + + --version + + Prints information on Boost.Build and Boost.Jam + versions. + + + + --help + + Access to the online help system. This prints general + information on how to use the help system with additional + --help* options. + + + + --clean + + Removes everything instead of building. Unlike + clean target in make, it is possible to clean only + some targets. + + + + --debug + + Enables internal checks. + + + + --dump-projects + + Cause the project structure to be output. + + + + --no-error-backtrace + + Don't print backtrace on errors. Primary usefull for + testing. + + + + --ignore-config + + Do not load site-config.jam and + user-config.jam + + + +
+ +
+
+ +
+ Build request + + +
+ +
+ Build process + + Construction of each main target begins with finding + properties for this main target. They are found by + processing both build request, and target requirements, + which give properties needed for the target to build. For + example, a given main target might require certian defines, or + will not work unless compiled in multithreaded mode. The process + of finding properties for main target is described in property refinement. + + After that, dependencies (i.e. other main targets) are build + recursively. Build request for dependencies is not always equal + to those of dependent — certain properties are dropped and + user can explicitly specify desired properties for dependencies. + See + propagated features and for details. + + When dependencies are constructed, the dependency graph for + this main target and for this property set is created, which + describes which files need to be created, on which other files + they depend and what actions are needed to construct those files. + There's more that one method, and user can define new ones, but + usually, this involves generators and target + types. + + Target type is just a way to classify targets. For example, + there are builtin types EXE, OBJ and + CPP. Generators are objects + that know how to convert between different target type. When a + target of a given type must be created, all generators for that + type, which can handle needed properties, are found. Each is + passed the list of sources, and either fails, or returns a + dependency graph. If a generator cannot produce desired type from + given sources, it may try to recursively construct types that it + can handle from the types is was passed. This allows to try all + possible transformations. When all generators are tried, a + dependency graph is selected. + + Finally, the dependency graph is passed to underlying + Boost.Jam program, which runs all actions needed to bring all + main targets up-to date. At this step, implicit dependencies are + also scanned and accounted for, as described "here." [ link? ] + + Given a list of targets ids and a build request, building goes + this way. First, for each id we obtain the abstract targets + corresponding to it. This also loads all necessary projects. If + no target id is given, project in the current directory is used. + Build request is expanded, and for each resulting property set, + the generate method of all targets is called, which + yields a list of virtual targets. After that all virtual targets + are actualized, and target "all" is set to depend on all created + actual targets. Lastly, depending on whether --clean + option was given, either target "all" or target "clean" is + updated. Generation of virtual target from abstract one is + performed as follows: + + + + For project targets, all of main targets are generated + with the same properties. Then all projects referred via + "build-project" are generated as well. If it's not possible + to refine requested properties with project requirements, the + project is skipped. + + + It is possible to disable building of certain target using the + explicit rule, available in all project + modules. The syntax is + + +rule explicit ( target-name ) + + + If this rule is invoked on a target, it will be built only +when it's explicitly requested on the command line. + + + + + + For main target, with several alternatives, one of them is + selected as described below. + If there's only one + alternative, it's used unconditionally. + + + + + All main target alternatives which requirements are + satisfied by the build request are enumerated. + + + + + + If there are several such alternatives, the one which + longer requirements list is selected. + + + + + + + + + For the selected alternative + + + + + Each target reference in the source list are + recursively constructed. + + + + + + Properties are refined with alternative's requirements, + and active features in the resulting set are executed. + + + + + + Conditional properties are evaluated. + + + + + + The dependency graph for the target is constructed in a + way which depends on the kind of main target, typically + using generators. + + + + + + + + + If, when building sources, the properties on recursively + created targets are not link-compatibile with build properties, + a warning is issued. + + + + +
+ +
+ Alternative selection + + When there are several alternatives, one of them must be + selected. The process is as follows: + + + + + For each alternative condition is defined + as the set of base properies in requirements. [Note: it might be + better to explicitly specify the condition explicitly, as in + conditional requirements]. + + + + + + An alternative is viable only if all properties in condition + are present in build request. + + + + + + If there's one viable alternative, it's choosen. Otherwise, + an attempt is made to find one best alternative. An alternative + a is better than another alternative b, iff set of properties + in b's condition is stict subset of the set of properities of + 'a's condition. If there's one viable alternative, which is + better than all other, it's selected. Otherwise, an error is + reported. + + + + +
+ +
+ Generated headers + + Usually, Boost.Build handles implicit dependendies completely + automatically. For example, for C++ files, all #include + statements are found and handled. The only aspect where user help + might be needed is implicit dependency on generated files. + + By default, Boost.Build handles such dependencies within one + main target. For example, assume that main target "app" has two + sources, "app.cpp" and "parser.y". The latter source is converted + into "parser.c" and "parser.h". Then, if "app.cpp" includes + "parser.h", Boost.Build will detect this dependency. Moreover, + since "parser.h" will be generated into a build directory, the + path to that directory will automatically added to include + path. + + Making this mechanism work across main target boundaries is + possible, but imposes certain overhead. For that reason, if + there's implicit dependency on files from other main targets, the + <implicit-dependency> [ link ] feature must + be used, for example: + + +lib parser : parser.y ; +exe app : app.cpp : <implicit-dependency>parser ; + + + +The above example tells the build system that when scanning +all sources of "app" for implicit-dependencies, it should consider +targets from "parser" as potential dependencies. + + +
+
+ Generators + + To construct a main target with given properties from sources, + it is required to create a dependency graph for that main target, + which will also include actions to be run. The algorithm for + creating the dependency graph is described here. + + The fundamental concept is generator. If encapsulates + the notion of build tool and is capable to converting a set of + input targets into a set of output targets, with some properties. + Generator matches a build tool as closely as possible: it works + only when the tool can work with requested properties (for + example, msvc compiler can't work when requested toolset is gcc), + and should produce exactly the same targets as the tool (for + example, if Borland's linker produces additional files with debug + information, generator should also). + + Given a set of generators, the fundamental operation is to + construct a target of a given type, with given properties, from a + set of targets. That operation is performed by rule + generators.construct and the used algorithm is described + below. + +
+ Selecting and ranking viable generators + + Each generator, in addition to target types that it can + produce, have attribute that affects its applicability in + particular sitiation. Those attributes are: + + + + + Required properties, which are properties absolutely + necessary for the generator to work. For example, generator + encapsulating the gcc compiler would have <toolset>gcc as + required property. + + + + + + Optional properties, which increase the generators + suitability for a particual build. + + + + + + Generator's required and optional properties may not include + either free or incidental properties. (Allowing this would + greatly complicate caching targets). + + + When trying to construct a target, the first step is to select + all possible generators for the requested target type, which + required properties are a subset of requested properties. + Generators which were already selected up the call stack are + excluded. In addition, if any composing generators were selected + up the call stack, all other composing generators are ignored + (TODO: define composing generators). The found generators + assigned a rank, which is the number of optional properties + present in requested properties. Finally, generators with highest + rank are selected for futher processing. + +
+
+ Running generators + + When generators are selected, each is run to produce a list of + created targets. This list might include targets which are not of + requested types, because generators create the same targets as + some tool, and tool's behaviour is fixed. (Note: should specify + that in some cases we actually want extra targets). If generator + fails, it returns an empty list. Generator is free to call + 'construct' again, to convert sources to the types it can handle. + It also can pass modified properties to 'constuct'. However, a + generator is not allowed to modify any propagated properties, + otherwise when actually consuming properties we might discover + that the set of propagated properties is different from what was + used for building sources. + + For all targets which are not of requested types, we try to + convert them to requested type, using a second call to + construct. This is done in order to support + transformation sequences where single source file expands to + several later. See this + message for details. + +
+ +
+ Selecting dependency graph + + + After all generators are run, + it is necessary to decide which of successfull invocation will be + taken as final result. At the moment, this is not done. Instead, + it is checked whether all successfull generator invocation + returned the same target list. Error is issued otherwise. + + +
+ +
+ Property adjustment + + Because target location is determined by the build system, it + is sometimes necessary to adjust properties, in order to not + break actions. For example, if there's an action which generates + a header, say "a_parser.h", and a source file "a.cpp" which + includes that file, we must make everything work as if a_parser.h + is generated in the same directory where it would be generated + without any subvariants. + + Correct property adjustment can be done only after all targets + are created, so the approach taken is: + + + + + When dependency graph is constructed, each action can be + assigned a rule for property adjustment. + + + + + + When virtual target is actualized, that rule is run and + return the final set of properties. At this stage it can use + information of all created virtual targets. + + + + + In case of quoted includes, no adjustment can give 100% + correct results. If target dirs are not changed by build system, + quoted includes are searched in "." and then in include path, + while angle includes are searched only in include path. When + target dirs are changed, we'd want to make quoted includes to be + search in "." then in additional dirs and then in the include + path and make angle includes be searched in include path, + probably with additional paths added at some position. Unless, + include path already has "." as the first element, this is not + possible. So, either generated headers should not be included + with quotes, or first element of include path should be ".", + which essentially erases the difference between quoted and angle + includes. Note: there only way to get "." as include path + into compiler command line is via verbatim compiler option. In + all other case, Boost.Build will convert "." into directory where + it occurs. + +
+ +
+ Transformations cache + + + Under certain conditions, an + attempt is made to cache results of transformation search. First, + the sources are replaced with targets with special name and the + found target list is stored. Later, when properties, requested + type, and source type are the same, the store target list is + retrieved and cloned, with appropriate change in names. + + +
+
+ +
+ diff --git a/v2/doc/src/tutorial.xml b/v2/doc/src/tutorial.xml new file mode 100644 index 000000000..167ee4214 --- /dev/null +++ b/v2/doc/src/tutorial.xml @@ -0,0 +1,516 @@ + + + + + Tutorial + +
+ Hello, world + + The simplest project that Boost.Build can construct is + stored in example/hello directory. The targets are declared in + a file called Jamfile, which contains the + following: + + +exe hello : hello.cpp ; + + + Even with this simple setup, you can do some interesting + things. First of all, running "bjam" would build binary "hello" + from hello.cpp, in debug version. After that, you can run + + +bjam release + + + which would create release version of the 'hello' binary. + Note that debug and release version would be created in different + directories, so if you want to switch from debug to release + version and back, no recompilation is needed. Let's extend the + example by adding another line to Jamfile: + + +exe hello2 : hello.cpp ; + + + You can now rebuild both debug and release versions: + + +bjam debug release + + + You'll see that two versions of "hello2" binary are linked. + Of course, hello.cpp won't be recompiled. Now you decide to remove + all build products. You do that with the following command + + +bjam --clean debug release + + + It's also possible to create or clean only specific targets. + Both following commands are legal and create or clean only files + that belonging the the named binary: + + +bjam hello2 +bjam --clean hello2 + + + +
+
+ Properties + + Boost.Build attempts to allow building different variants of + projects, e.g. for debugging and release, or in single and + multithreaded mode. In order to stay portable, it uses the + concept of features, which is abstract aspect of + build configuration. Property is just a (feature, + value) pair. For example, there's a feature "debug-symbols", which can + have a value of "on" or "off". When users asks to build project is a + particual value, Boost.Build will automatically find the + appropriate flags to the used compiler. + + The "release" and "debug" in bjam invocation that we've seen + are just are short form of specifying values of feature + "variant". There is a lot of builtin features, and it's possible + to write something like: + + +bjam release inlining=off debug-symbols=on + + + + The first command line element specified the value of feature + "variant". The feature is very common and is therefore special + — it's possible to specify only value. Another feature, + "inlining" is not special, and you should use + + +feature-name=feature-value + + + syntax for it. Complete description of features can be found + here. The set of + properties specified in the command line constitute + build request — the desired properties + for requested targets, or for the project in the current + directory. The actual set of properties used for building is + often different. For example, when compiling a program you need + some include paths. It's not reasonable to ask the user to specify + those paths with each bjam invocation, so must be specified in + Jamfile and added to the build request. For another example, + certain application can only be linked in multithreaded mode. To + support such situations, every target is allowed to specify + requirements -- properties that are required + to its building. Consider this example: + + +exe hello + : hello.cpp + : <include>/home/ghost/Work/boost <threading>multi + + + In this case, when hello is build, the two specified properties will + always be present. This leads to a question: what if user explictly + requested single-threading. The answer is that requirement can + affect build properties only to a certain degree: the requested and + actual properties must be link-compatible. See below. If they are not link + compatible, the bulding of the target is skipped. Previously, we've + added "hello2" target. Seems like we have to specify the same + requirements for it, which results in duplication. But there's a + better way. Each project (i.e. each Jamfile), can specify a set of + attributes, including requirements: + + +project + : requirements <include>/home/ghost/Work/boost <threading>multi + ; + +exe hello : hello.cpp ; +exe hello2 : hello.cpp ; + + + The effect would be as if we specified this requirement for + both "hello" and "hello2". + +
+ +
+ Project hierarchy + + So far we only considered examples with one project (i.e. with + one Jamfile). Typically, you'd have a lot of projects organized + into a tree. At the top of the tree there's project + root. This is a directory which contains, besides Jamfile, a + file called "project-root.jam". Each other Jamfile has a single + parent, which is the Jamfile in the nearest parent directory. For + example, in the following directory layout: + + +[top] + | + |-- Jamfile + |-- project-root.jam + | + |-- src + | | + | |-- Jamfile + | \-- app.cpp + | + \-- lib + | + |-- lib1 + | | + | |-- Jamfile + |-- lib1.cpp + + + +project root is at top. Both src/Jamfile and lib/lib1/Jamfile +have [top]/Jamfile as parent project. Projects inherit all +attributes (such as requirements) from their parents. When the same +attributes are specified in the project, they are combined with +inherited ones. For example, if [top]/Jamfile has + + +<include>/home/ghost/local + + +in requirements, then all other projects will have that in +their requirements too. Of course, any project can add additional +includes. More details can be found in the section on projects. Projects are not automatically +built when +their parents are built. You should specify this explicitly. In our +example, [top]/Jamfile might contain: + + +build-project src ; + + + It will cause project in src to be built whenever project in +[top] is built. However, targets in lib/lib1 will be built only if +required. For example, there may be 10 targets, and two of them are +used by targets in src/Jamfile. Then, only those two targets will +be built. + +
+ +
+ Using libraries + + Let's continue the above example and see how src/Jamfile + can use libraries from + lib/lib1. (TODO: need to make this section consistent with + "examples-v2/libraries". Assume lib/lib1/Jamfile contains: + + +lib lib1 : lib1.cpp ; + + + Then, to use this library in src/Jamfile, we can write: + + +exe app : app.cpp ../lib/lib1//lib1 ; + + +While "app.cpp" is a regular source file, "../lib/lib1//lib1" +is a reference to another target, here, library "lib1" declared in +Jamfile at "../lib/lib1". When linking the "app" binary, the needed +version of the library will be built and linked in. But what is +meant by "needed"? For example, we can request to build "app" with +properties + + +<optimization>full <cxxflags>-w-8080 + + +Which properties must be used for "lib1"? The answer is that +some properties are propagated — Boost.Build attemps +to use dependencies with the same value of propagated features. The +<optimization> feature is propagated, so both "app" and +"lib1" will be compiled with full optimization. But +<cxxflags> feature is not propagated: its value will be added +as-is to compiler flags for "a.cpp", but won't affect "lib1". There +is still a couple of problems. First, the library probably has some +headers which must be used when compiling "app.cpp". We could use +requirements on "app" to add those includes, but then this work +will be repeated for all programs which use "lib1". A better +solution is to modify lib/lib1/Jamfilie in this way: + + +project + : usage-requirements <include>. + ; + +lib lib1 : lib1.cpp ; + + +Usage requirements are requirements which are applied to +dependents. In this case, <include> will be applied to all +targets which use "lib1" — i.e. targets which have "lib1" +either in sources or in dependency properties. You'd need to +specify usage requirements only once, and programs which use "lib1" +don't have to care about include paths any longer. Or course, the +path will be interpreted relatively to "lib/lib1" and will be +adjusted according to the bjams invocation +directory. For +example, if building from project root, the final compiler's +command line will contain . + + + The second problem is that we hardcode the path to library's + Jamfile. Imagine it's hardcoded in 20 different places and we + change the directory layout. The solution is to use project ids + — symbolic names, not tied to directory layout. First, we + assign a project id to Jamfile in lib/lib1: + + +project lib1 + : usage-requirements <include>. + ; + + + +Second, we use the project id to refer to the library in +src/Jamfile: + + +exe app : app.cpp /lib1//lib1 ; + + +The "/lib1//lib1" syntax is used to refer to target "lib1" in +project with global id "/lib1" (the slash is used to specify global +id). This way, users of "lib1" do not depend on its location, only +on id, which is supposedly stable. The only thing left, it to make +sure that src/Jamfile knows the project id that it uses. We add to +[top]/Jamfile the following line: + + +use-project /lib1 : lib/lib1 ; + + +Now, all projects can refer to "lib1" using the symbolic +name. If the library is moved somewhere, only a single line in the +top-level Jamfile should be changed. + +
+ +
+ Library dependencies + + The previous example was simple. Often, there are long chains + of dependencies between libraries. The main application is a thin + wrapper on top of library with core logic, which uses library of + utility functions, which uses boost filesystem library. + Expressing these dependencies is straightforward: + + +lib utils : utils.cpp /boost/filesystem//fs ; +lib core : core.cpp utils ; +exe app : app.cpp core ; + + + So, what's the reason to even mention this case? First, + because it's a bit more complex that it seems. When using shared + linking, libraries are build just as written, and everything will + work. However, what happens with static linking? It's not + possible to include another library in static library. + Boost.Build solves this problem by returning back library targets + which appear as sources for static libraries. In this case, if + everything is built statically, the "app" target will link not + only "core" library, but also "utils" and + "/boost/filesystem//fs". + + So, the net result is that the above code will work for both + static linking and for shared linking. + + Sometimes, you want all applications in some project to link + to a certain library. Putting the library in sources of all + targets is possible, but verbose. You can do better by using + <library> property. For example, if "/boost/filesystem//fs" + should be linked to all applications in your project, you can add + <library>/boost/filesystem//fs to requirements of the + project, like this: + + +project + : requirements <library>/boost/filesystem//fs + ; + +
+ +
+ Static and shared libaries + + While the + previous section explained how to create and use libraries, it + omitted one important detail. Libraries can be either + static, which means they are included in executable + files which use them, or shared (a.k.a. + dynamic), which are only referred to from executables, + and must be available at run time. Boost.Build can work with both + types. By default, all libraries are shared. This is much more + efficient in build time and space. But the need to install all + libraries to some location is not always convenient, especially + for debug builds. Also, if the installed shared library changes, + all application which use it might start to behave differently. + + + Static libraries do not suffer from these problems, but + considerably increase the size of application. Before describing + static libraries, it's reasonable to give another, quite simple + approach. If your project is built with + <hardcode-dll-paths>true property, then the application + will include the full paths for all shared libraries, eliminating + the above problems. Unfortunately, you no longer can move shared + library to a different location, which makes this option suitable + only for debug builds. Further, only gcc compiler supports this + option. + + Building a library statically is easy. You'd need to change + the value of <link> feature from it's deafault value + shared, to static. So, to build everything as + static libraries, you'd say + + +bjam link=static + + + +on the command line. The linking mode can be fine-tuned on +per-target basis. + + + + + Suppose your library can be only build statically. This is + easily achieved using requirements: + + +lib l : l.cpp : <link>static ; + + + + + + + + What if library can be both static and shared, but when + using it in specific executable, you want it static? + Target + references are here to help: + + +exe important : main.cpp helpers/<link>static ; + + + + + + + + What if the library is defined in some other project, which + you cannot change. But still, you want static linking to that + library in all cases. You can use target references everywhere: + + +exe e1 : e1.cpp /other_project//lib1/<link>static ; +exe e10 : e10.cpp /other_project//lib1/<link>static ; + + +but that's far from being convenient. Another way is to +introduce a level of indirection: create a local target, which will +refer to static version of lib1. Here's the +solution: + + +alias lib1 : /other_project//lib1/<link>static ; +exe e1 : e1.cpp lib1 ; +exe e10 : e10.cpp lib1 ; + + +(Note, that the "alias" target type is not yet implemented, +but it's quite simple to do. I bet it's waiting for you to do it +;-)) + + + + +
+ +
+ Prebuilt targets + + + We've just learned how to use libraries which are created by + Boost.Build. But some libraries are not. At the same time, those + libraries can have different versions (release and debug, for + example), that we + should select depending on build properties. Prebuilt targets + provide a mechanism for that. Jamfile in lib/lib2 can contain: + + +lib lib2 + : + : <file>lib2_release.a <variant>release + ; + +lib lib2 + : + : <file>lib2_debug.a <variant>debug + ; + + +This defines two alternatives for target "lib2", and for each +one names a prebuilt file. Naturally, there are no sources. +Instead, the <file> feature is used to specify the file name. +Which alternative is selected depends on properties of dependents. +If "app" binary should use "lib2", we can write: + + +exe app : app.cpp /lib/lib1//lib2 ../lib/lib2//lib2 ; + + +If we build release version of "app", then it will be linked +with "lib2_release.a", and debug version will use "lib2_debug.a". +Another important kind of prebuilt targets are system libraries +— more specifically, libraries which are automatically found +by the compiler. E.g. gcc uses "-l" switch for that. Such libraries +should be declared almost like regular ones: + + +lib zlib : : <name>z ; + + +We again don't specify any sources, but give a name which +should be passed to the compiler. In this example, and for gcc +compiler, the "-lz" option will be added. Paths where library +should be searched can also be specified: + + +lib zlib : : <name>z <search>/opt/lib ; + + +And, of course, two variants can be used: + + +lib zlib : : <name>z <variant>release ; +lib zlib : : <name>z_d <variant>debug ; + + +Of course, you'll probably never in your life need debug +version of zlib, but for other libraries this is quite reasonable. + + + More advanced use of prebuilt target is descibed in recipes. + +
+ +
+ diff --git a/v2/doc/src/userman.xml b/v2/doc/src/userman.xml new file mode 100644 index 000000000..9d69bcff6 --- /dev/null +++ b/v2/doc/src/userman.xml @@ -0,0 +1,23 @@ + + + + + + Boost.Build v2 User Manual + + + + + + + + + + + + + + + diff --git a/v2/doc/userman.xml b/v2/doc/userman.xml deleted file mode 100644 index 328ecb351..000000000 --- a/v2/doc/userman.xml +++ /dev/null @@ -1,3189 +0,0 @@ - - - - - Boost.Build v2 User Manual - - - How to use this document - - - If you've just found out about Boost.Build V2 and want to know - if it will work for you, start with . You can continue with the . When you're ready to try Boost.Build - in practice, go to . - - - - If you are about to use Boost.Build on your project, or already - using it and have a problem, look at . - - - - If you're trying to build a project which uses Boost.Build, - look at and then read about - . - - - - Finally, if nothing applies to you, write to our mailing list, - telling what information you'd like to know. - - - - - - Installation - - - Assuming you're installing Boost.Build from released source - distribution, the following steps are needed. All paths are - given relatively to Boost.Build root directory, which is the - directory with the document you are reading. - - - - - - Go to "jam_src" directory and build Boost.Jam. Two convenient - scripts are provided, "build.sh" (for Unix systems) and - "build.bat" (for Windows). Run the appropriate one and - Boost.Jam will be built to directory - bin.{platform_name}.. The Boost.Jam documentation has - more details in case you need them. - - - - - - Place the Boost.Jam binary, called "bjam" or "bjam.exe", - somewhere in your PATH. Go to the root - directory of Boost.Build and run "bjam --version". You should - get - - Boost.Build V2 (Milestone N) - - (where N is the version you've downloaded). - - - - - - Configure toolsets to use. Open the - user-config.jam file and follow - instructions there to specify what compiles/libraries you - have and where they are located. - - - - - - You should now be able to go to - example/hello, and run - bjam there. A simple application will be - built. You can also play with other projects in - example. - - - - - - - If you use Boost distribution, or Boost CVS, the Boost.Build - root is located at $boost_root/tools/build/v2 - and the installation steps are the same. However, don't skip - the bjam rebuilding step, even if you have a previous version. - CVS version of Boost.Build requires CVS version of Boost.Jam. - - - - When starting a new project which uses Boost.Build, you need - to make sure that build system can be found. There are two - ways. - - - - - - Set enviromnetal variable BOOST_BUILD_PATH - to the absolute path to Boost.Build installation directory. - - - - - - Create, at the top of your project, a file called - boost-build.jam, with a single line: - - -boost-build /path/to/boost.build ; - - - - - - - If you're trying to use Boost.Build V2 on Boost itself, please - note that when building Boost, V1 is used by default. You'd have - to add command line option to all "bjam" - invocations. - - - - - Tutorial - -
- Hello, world - - The simplest project that Boost.Build can construct is - stored in example/hello directory. The targets are declared in - a file called Jamfile, which contains the - following: - - -exe hello : hello.cpp ; - - - Even with this simple setup, you can do some interesting - things. First of all, running "bjam" would build binary "hello" - from hello.cpp, in debug version. After that, you can run - - -bjam release - - - which would create release version of the 'hello' binary. - Note that debug and release version would be created in different - directories, so if you want to switch from debug to release - version and back, no recompilation is needed. Let's extend the - example by adding another line to Jamfile: - - -exe hello2 : hello.cpp ; - - - You can now rebuild both debug and release versions: - - -bjam debug release - - - You'll see that two versions of "hello2" binary are linked. - Of course, hello.cpp won't be recompiled. Now you decide to remove - all build products. You do that with the following command - - -bjam --clean debug release - - - It's also possible to create or clean only specific targets. - Both following commands are legal and create or clean only files - that belonging the the named binary: - - -bjam hello2 -bjam --clean hello2 - - - -
-
- Properties - - Boost.Build attempts to allow building different variants of - projects, e.g. for debugging and release, or in single and - multithreaded mode. In order to stay portable, it uses the - concept of features, which is abstract aspect of - build configuration. Property is just a (feature, - value) pair. For example, there's a feature "debug-symbols", which can - have a value of "on" or "off". When users asks to build project is a - particual value, Boost.Build will automatically find the - appropriate flags to the used compiler. - - The "release" and "debug" in bjam invocation that we've seen - are just are short form of specifying values of feature - "variant". There is a lot of builtin features, and it's possible - to write something like: - - -bjam release inlining=off debug-symbols=on - - - - The first command line element specified the value of feature - "variant". The feature is very common and is therefore special - — it's possible to specify only value. Another feature, - "inlining" is not special, and you should use - - -feature-name=feature-value - - - syntax for it. Complete description of features can be found - here. The set of - properties specified in the command line constitute - build request — the desired properties - for requested targets, or for the project in the current - directory. The actual set of properties used for building is - often different. For example, when compiling a program you need - some include paths. It's not reasonable to ask the user to specify - those paths with each bjam invocation, so must be specified in - Jamfile and added to the build request. For another example, - certain application can only be linked in multithreaded mode. To - support such situations, every target is allowed to specify - requirements -- properties that are required - to its building. Consider this example: - - -exe hello - : hello.cpp - : <include>/home/ghost/Work/boost <threading>multi - - - In this case, when hello is build, the two specified properties will - always be present. This leads to a question: what if user explictly - requested single-threading. The answer is that requirement can - affect build properties only to a certain degree: the requested and - actual properties must be link-compatible. See below. If they are not link - compatible, the bulding of the target is skipped. Previously, we've - added "hello2" target. Seems like we have to specify the same - requirements for it, which results in duplication. But there's a - better way. Each project (i.e. each Jamfile), can specify a set of - attributes, including requirements: - - -project - : requirements <include>/home/ghost/Work/boost <threading>multi - ; - -exe hello : hello.cpp ; -exe hello2 : hello.cpp ; - - - The effect would be as if we specified this requirement for - both "hello" and "hello2". - -
- -
- Project hierarchy - - So far we only considered examples with one project (i.e. with - one Jamfile). Typically, you'd have a lot of projects organized - into a tree. At the top of the tree there's project - root. This is a directory which contains, besides Jamfile, a - file called "project-root.jam". Each other Jamfile has a single - parent, which is the Jamfile in the nearest parent directory. For - example, in the following directory layout: - - -[top] - | - |-- Jamfile - |-- project-root.jam - | - |-- src - | | - | |-- Jamfile - | \-- app.cpp - | - \-- lib - | - |-- lib1 - | | - | |-- Jamfile - |-- lib1.cpp - - - -project root is at top. Both src/Jamfile and lib/lib1/Jamfile -have [top]/Jamfile as parent project. Projects inherit all -attributes (such as requirements) from their parents. When the same -attributes are specified in the project, they are combined with -inherited ones. For example, if [top]/Jamfile has - - -<include>/home/ghost/local - - -in requirements, then all other projects will have that in -their requirements too. Of course, any project can add additional -includes. More details can be found in the section on projects. Projects are not automatically -built when -their parents are built. You should specify this explicitly. In our -example, [top]/Jamfile might contain: - - -build-project src ; - - - It will cause project in src to be built whenever project in -[top] is built. However, targets in lib/lib1 will be built only if -required. For example, there may be 10 targets, and two of them are -used by targets in src/Jamfile. Then, only those two targets will -be built. - -
- -
- Using libraries - - Let's continue the above example and see how src/Jamfile - can use libraries from - lib/lib1. (TODO: need to make this section consistent with - "examples-v2/libraries". Assume lib/lib1/Jamfile contains: - - -lib lib1 : lib1.cpp ; - - - Then, to use this library in src/Jamfile, we can write: - - -exe app : app.cpp ../lib/lib1//lib1 ; - - -While "app.cpp" is a regular source file, "../lib/lib1//lib1" -is a reference to another target, here, library "lib1" declared in -Jamfile at "../lib/lib1". When linking the "app" binary, the needed -version of the library will be built and linked in. But what is -meant by "needed"? For example, we can request to build "app" with -properties - - -<optimization>full <cxxflags>-w-8080 - - -Which properties must be used for "lib1"? The answer is that -some properties are propagated — Boost.Build attemps -to use dependencies with the same value of propagated features. The -<optimization> feature is propagated, so both "app" and -"lib1" will be compiled with full optimization. But -<cxxflags> feature is not propagated: its value will be added -as-is to compiler flags for "a.cpp", but won't affect "lib1". There -is still a couple of problems. First, the library probably has some -headers which must be used when compiling "app.cpp". We could use -requirements on "app" to add those includes, but then this work -will be repeated for all programs which use "lib1". A better -solution is to modify lib/lib1/Jamfilie in this way: - - -project - : usage-requirements <include>. - ; - -lib lib1 : lib1.cpp ; - - -Usage requirements are requirements which are applied to -dependents. In this case, <include> will be applied to all -targets which use "lib1" — i.e. targets which have "lib1" -either in sources or in dependency properties. You'd need to -specify usage requirements only once, and programs which use "lib1" -don't have to care about include paths any longer. Or course, the -path will be interpreted relatively to "lib/lib1" and will be -adjusted according to the bjams invocation -directory. For -example, if building from project root, the final compiler's -command line will contain . - - - The second problem is that we hardcode the path to library's - Jamfile. Imagine it's hardcoded in 20 different places and we - change the directory layout. The solution is to use project ids - — symbolic names, not tied to directory layout. First, we - assign a project id to Jamfile in lib/lib1: - - -project lib1 - : usage-requirements <include>. - ; - - - -Second, we use the project id to refer to the library in -src/Jamfile: - - -exe app : app.cpp /lib1//lib1 ; - - -The "/lib1//lib1" syntax is used to refer to target "lib1" in -project with global id "/lib1" (the slash is used to specify global -id). This way, users of "lib1" do not depend on its location, only -on id, which is supposedly stable. The only thing left, it to make -sure that src/Jamfile knows the project id that it uses. We add to -[top]/Jamfile the following line: - - -use-project /lib1 : lib/lib1 ; - - -Now, all projects can refer to "lib1" using the symbolic -name. If the library is moved somewhere, only a single line in the -top-level Jamfile should be changed. - -
- -
- Library dependencies - - The previous example was simple. Often, there are long chains - of dependencies between libraries. The main application is a thin - wrapper on top of library with core logic, which uses library of - utility functions, which uses boost filesystem library. - Expressing these dependencies is straightforward: - - -lib utils : utils.cpp /boost/filesystem//fs ; -lib core : core.cpp utils ; -exe app : app.cpp core ; - - - So, what's the reason to even mention this case? First, - because it's a bit more complex that it seems. When using shared - linking, libraries are build just as written, and everything will - work. However, what happens with static linking? It's not - possible to include another library in static library. - Boost.Build solves this problem by returning back library targets - which appear as sources for static libraries. In this case, if - everything is built statically, the "app" target will link not - only "core" library, but also "utils" and - "/boost/filesystem//fs". - - So, the net result is that the above code will work for both - static linking and for shared linking. - - Sometimes, you want all applications in some project to link - to a certain library. Putting the library in sources of all - targets is possible, but verbose. You can do better by using - <library> property. For example, if "/boost/filesystem//fs" - should be linked to all applications in your project, you can add - <library>/boost/filesystem//fs to requirements of the - project, like this: - - -project - : requirements <library>/boost/filesystem//fs - ; - -
- -
- Static and shared libaries - - While the - previous section explained how to create and use libraries, it - omitted one important detail. Libraries can be either - static, which means they are included in executable - files which use them, or shared (a.k.a. - dynamic), which are only referred to from executables, - and must be available at run time. Boost.Build can work with both - types. By default, all libraries are shared. This is much more - efficient in build time and space. But the need to install all - libraries to some location is not always convenient, especially - for debug builds. Also, if the installed shared library changes, - all application which use it might start to behave differently. - - - Static libraries do not suffer from these problems, but - considerably increase the size of application. Before describing - static libraries, it's reasonable to give another, quite simple - approach. If your project is built with - <hardcode-dll-paths>true property, then the application - will include the full paths for all shared libraries, eliminating - the above problems. Unfortunately, you no longer can move shared - library to a different location, which makes this option suitable - only for debug builds. Further, only gcc compiler supports this - option. - - Building a library statically is easy. You'd need to change - the value of <link> feature from it's deafault value - shared, to static. So, to build everything as - static libraries, you'd say - - -bjam link=static - - - -on the command line. The linking mode can be fine-tuned on -per-target basis. - - - - - Suppose your library can be only build statically. This is - easily achieved using requirements: - - -lib l : l.cpp : <link>static ; - - - - - - - - What if library can be both static and shared, but when - using it in specific executable, you want it static? - Target - references are here to help: - - -exe important : main.cpp helpers/<link>static ; - - - - - - - - What if the library is defined in some other project, which - you cannot change. But still, you want static linking to that - library in all cases. You can use target references everywhere: - - -exe e1 : e1.cpp /other_project//lib1/<link>static ; -exe e10 : e10.cpp /other_project//lib1/<link>static ; - - -but that's far from being convenient. Another way is to -introduce a level of indirection: create a local target, which will -refer to static version of lib1. Here's the -solution: - - -alias lib1 : /other_project//lib1/<link>static ; -exe e1 : e1.cpp lib1 ; -exe e10 : e10.cpp lib1 ; - - -(Note, that the "alias" target type is not yet implemented, -but it's quite simple to do. I bet it's waiting for you to do it -;-)) - - - - -
- -
- Prebuilt targets - - - We've just learned how to use libraries which are created by - Boost.Build. But some libraries are not. At the same time, those - libraries can have different versions (release and debug, for - example), that we - should select depending on build properties. Prebuilt targets - provide a mechanism for that. Jamfile in lib/lib2 can contain: - - -lib lib2 - : - : <file>lib2_release.a <variant>release - ; - -lib lib2 - : - : <file>lib2_debug.a <variant>debug - ; - - -This defines two alternatives for target "lib2", and for each -one names a prebuilt file. Naturally, there are no sources. -Instead, the <file> feature is used to specify the file name. -Which alternative is selected depends on properties of dependents. -If "app" binary should use "lib2", we can write: - - -exe app : app.cpp /lib/lib1//lib2 ../lib/lib2//lib2 ; - - -If we build release version of "app", then it will be linked -with "lib2_release.a", and debug version will use "lib2_debug.a". -Another important kind of prebuilt targets are system libraries -— more specifically, libraries which are automatically found -by the compiler. E.g. gcc uses "-l" switch for that. Such libraries -should be declared almost like regular ones: - - -lib zlib : : <name>z ; - - -We again don't specify any sources, but give a name which -should be passed to the compiler. In this example, and for gcc -compiler, the "-lz" option will be added. Paths where library -should be searched can also be specified: - - -lib zlib : : <name>z <search>/opt/lib ; - - -And, of course, two variants can be used: - - -lib zlib : : <name>z <variant>release ; -lib zlib : : <name>z_d <variant>debug ; - - -Of course, you'll probably never in your life need debug -version of zlib, but for other libraries this is quite reasonable. - - - More advanced use of prebuilt target is descibed in recipes. - -
- -
- - - Advanced - - This section will document - mostly high-level view of Boost.Build, mentioning appropriate - modules and rules. The on-line help system must be used to obtain - low-level documentation (see the help option). - -
- Overview - - The most fundemental entity in Boost.Build is main - target. This is object that user want to construct from - sources and keep up to date with regard to those sources. Typical - examples of main targets are executable files and libraries. - - Main targets are grouped in projects. Their main - purpose is organization: related targets placed in one project, - can then be built together, or share some definitions. - - Main targets and projects are created as the result of reading - one or several Jamfiles. Each Jamfile is a file written in - Boost.Jam interpreted language, and typically contains calls to - functions provided by Boost.Build, which create main targets of - needed type, declare project attributes and access other - projects. The full list of functions provided by Boost.Build is - described below. - Of course, user can create his own functions, or it can directly - access Boost.Build internals from Jamfile, if builtin facilities are - not sufficient. - - Each main target, or project can be built in a number of ways, - say with optimization or without. We'll call such entities - "metatargets". To make Boost.Build produce any real targets, user - issues build request, - which specifies metatargets to be built, and properties to be - used. - - The properties are just (name,value) pairs that - describe various aspects of constructed objects, for example: - -<optimization>full <inlining>off - - - Given the built request, Boost.Build figures out the targets - needed for requested metatargets with requested properties, how - they can be created, and whether exising files can be reused. It - finally issues command to create needed files, automatically - converting properties into appropricate command line options. - -
- -
- Your first project and roadmap - - Creating your first project requires three steps: - - - Create an empty file called "Jamfile" - - - - Create an empty file called "project-root.jam" - - - - - Either set your BOOST_BUILD_PATH environment - variant to Boost.Build root, or create a "boost-build.jam" file - with the following content: - - -boost-build /path/to/boost.build ; - - - - - - - After that, you can run the "bjam" command in the directory - where you've created the files. Surely, it won't do anything, but - it will run without error, at least. Your next steps might - be: - - - - - Adding new main targets to the "Jamfile" file. The basic - syntax for declaring a main target is described below, and all builtin functions for - declaring main targets are listed. - - - - - - Creating subprojects. Create a directory, put new Jamfile - there, and move some main targets to that Jamfile, or declare - new ones. The projects - reference will help with this part. - - - - - - Customizing Boost.Build for your needs. You might have - additional tools you want to run, or just want different - extension for some file. The extender manual is waiting for - you. - - - - -
- -
- Main targets - - - Main target is a user-defined named - entity which can be build, for example a named executable file. - Declaring a main target is usually done using one of main target functions. - The user can also declare custom main target - function. - - Most main targets rules in Boost.Build use similiar - syntax: - - -function-name main-target-name - : sources - : requirements - : default-build - : usage-requirements - ; - - - - - - "main-target-name" is the name used to request the target - on command line and to use it from other main targets. Main - target name may contain alphanumeric characters and symbols '-' - and '_'; - - - - - - "sources" is the list of source files and other main - targets that must be combined. If source file is specified - using relative path, it's considered to be relative to the - source directory of the project where the path is used. See the - project rule - for information how to change source directory. - - - - - - "requirements" is the list of properties that must always - be present when this main target is built. - - - - - - "default-build" is the list of properties that will be used - unless some other value of the same feature is already - specified. - - - - - - "usage-requirements" is the list of properties that will be - propagated to all main targets that use this one, i.e. to all - dependedents. - - - - - Some main target rules have shorter list of parameters, and - you should consult their documentation for details. - - Building of the same main target can differ greatly from - platform to platform. For example, you might have different list - of sources for different compilers. Therefore it is possible to - invoke main target rules several times for a single main target. - For example: - - -exe a : a_gcc.cpp : <toolset>gcc ; -exe a : a.cpp ; - - - - Each call to the 'exe' rule defines a new main target - alternative for the main target a. - In this case, the first alternative will be used for the - gcc toolset, while the second alternative will - be used in other cases. See below for - details. - - - Sometime a main target is really needed only by some other - main target. E.g. a rule that declared test-suite uses a main - target that represent test, but those main targets are rarely - needed by themself. - - It possible to declare target inline, i.e. the "sources" - parameter may include call to other main rules. For example: - - -exe hello : hello.cpp - [ obj helpers : helpers.cpp : <optimization>off ] ; - - - -Will cause "helpers.cpp" to be always compiled without -optimization. It's possible to request main targets declared -inline, but since they are considered local, they are renamed to -"parent-main-target_name..main-target-name". In the example above, -to build only helpers, one should run "bjam hello..helpers". - - -
- -
- Projects - - Boost.Build considers every software it build as organized - into projects — modules which declare targets. - Projects are organized in a hierarchical structure, so each - project may have a single parent project and a number of - subprojects. - - Most often, projects are created as result of loading - Jamfile — files which are specially meant to - describe projects. Boost.Build will implicitly load Jamfile in - the invocation directory, and all Jamfiles referred by the first - one, creating the hierarchy of projects. - - The exact name of file that describes project is configurable. - By default, it's Jamfile, but can be changed by setting - global variables JAMFILE, for example in - boost-build.jam file. The value of the variable is a - list of regex patterns that are used when searching for Jamfile - in a directory. - - Every Boost.Build modules can decide to act as project and be - able to declare targets. For example, the - site-config.jam module can declare libraries - available on a given host, as described here. - - There are three things that can be put in Jamfile: - declarations of main targets, calls to a number of predefined - rules, and arbitrary user code. The predefined rules are listed - below: - - - - <tgroup cols="2"> - <thead> - <row> - <entry>Rule</entry> - - <entry>Semantic</entry> - </row> - </thead> - - <tbody> - <row> - <entry><link linkend= - "bbv2.advanced.projects.attributes.projectrule">project</link> - </entry> - - <entry>Define project attributes.</entry> - </row> - - <row> - <entry><link linkend= - "bbv2.advanced.projects.relationships.useprojectrule">use-project</link></entry> - - <entry>Make another project known.</entry> - </row> - - <row> - <entry><link linkend= - "bbv2.advanced.projects.relationships.buildprojectrule">build-project</link></entry> - - <entry>Build another project when this one is built.</entry> - </row> - - <row> - <entry><link linkend= - "bbv2.reference.buildprocess.explict">explicit</link></entry> - - <entry>States that the target should be built only by explicit - request.</entry> - </row> - - <row> - <entry>glob</entry> - - <entry>Takes a list of wildcards, and returns the list of files - which match any of the wildcards.</entry> - </row> - </tbody> - </tgroup> - </table> - - <para>Each project is also associated with <emphasis>project root</emphasis>. - That's a root for a tree of projects, which specifies some global - properties.</para> - - <section id="bbv2.advanced.projects.root"> - <title>Project root - - - Project root for a projects is the nearest parent directory - which contains a file called - project-root.jam. That file defines - certain properties which apply to all projects under project - root. It can: - - - - - configure toolsets, via call to toolset.using - - - - - - refer to other projects, via the use-project - rule - - - - - - declare constants, via the constant and - path-constant rules. - - - - - - - To facilitate declaration of simple projects, Jamfile and - project-root can be merged together. To achieve this effect, the - project root file should call the project rule. The - semantic is precisely the same as if the call was made in - Jamfile, except that project-root.jam will start serve as - Jamfile. The Jamfile in the directory of project-root.jam will be - ignored, and project-root.jam will be able to declare main - targets as usual. - - - -
- Project attributes - - For each project, there are several attributes. - - Project id is a short way to denote a project, as - opposed to the Jamfile's pathname. It is a hierarchical path, - unrelated to filesystem, such as "boost/thread". Target references make use of project ids to - specify a target. - - Source location specifies the directory where sources - for the project are located. - - Project requirements are requirements that apply to - all the targets in the projects as well as all subprojects. - - Default build is the build request that should be - used when no build request is specified explicitly. - - - The default values for those attributes are - given in the table below. In order to affect them, Jamfile may - call the project rule. The rule has this - syntax: - - -project id : <attributes> ; - - - -Here, attributes is a sequence of (attribute-name, -attribute-value) pairs. The list of attribute names along with its -handling is also shown in the table below. For example, it it -possible to write: - - - -project tennis - : requirements <threading>multi - : default-build release - ; - - -
- - <tgroup cols="4"> - <thead> - <row> - <entry>Attribute</entry> - - <entry>Name for the 'project' rule</entry> - - <entry>Default value</entry> - - <entry>Handling by the 'project' rule</entry> - </row> - </thead> - - <tbody> - - <row> - <entry>Project id</entry> - - <entry>none</entry> - - <entry>none</entry> - - <entry>Assigned from the first parameter of the 'project' rule. - It is assumed to denote absolute project id.</entry> - </row> - - <row> - <entry>Source location</entry> - - <entry><literal>source-location</literal></entry> - - <entry>The location of jamfile for the project</entry> - - <entry>Sets to the passed value</entry> - </row> - - <row> - <entry>Requirements</entry> - - <entry><literal>requirements</literal></entry> - - <entry>The parent's requirements</entry> - - <entry>The parent's requirements are refined with the passed - requirement and the result is used as the project - requirements.</entry> - </row> - - <row> - <entry>Default build</entry> - - <entry><literal>default-build</literal></entry> - - <entry>none</entry> - - <entry>Sets to the passed value</entry> - </row> - - <row> - <entry>Build directory</entry> - - <entry><literal>build-dir</literal></entry> - - <entry>If parent has a build dir set, the value of it, joined - with the relative path from parent to the current project. - Otherwise, empty</entry> - - <entry>Sets to the passed value, interpreted as relative to the - project's location.</entry> - </row> - </tbody> - </tgroup> - </table> - </section> - - <section id="bbv2.advanced.projects.relationships"> - <title>Project relationship - - There are three kinds of project relationships. - - First is parent-child. This relationship is established - implicitly: parent directories of a project are searched, and the - first found Jamfile is assumed to define the parent project. The - parent-child relationship affects only attribute values for the - child project. - - - Second is build relationship. Some - project may request to recursively build other projects. Those - project need not be child projects. The build-project - rule is used for that: - - build-project src ; - - - - The third kind is the 'use' - relationship. In means that one project uses targets from - another. It is possible to just refer to target in other projects - using target id. However, if target id uses project id, it is - required that the project id is known. The - use-project - rule is employed to guarantee that. - - - -use-project ( id : location ) - - - -It loads the project at the specified location, which makes -its project id available in the project which invokes the rule. It -is required that the id parameter passed to the -use-project rule be equal to the id that the loaded -project declared. At this moment, the id paremeter -should be absolute project id. - - - - -
- Target identifiers and references - - Target identifier is used to denote a - target. The syntax is: - - -target-id -> (project-id | target-name | file-name ) - | (project-id | directory-name) "//" target-name -project-id -> path -target-name -> path -file-name -> path -directory-name -> path - - - -This grammar allows some elements to be recognized as either - - - - - project id (at this point, all project ids start with slash). - - - - - - name of target declared in current Jamfile (note that target - names may include slash). - - - - - - a regular file, denoted by absolute name or name relative to - project's sources location. - - - - - To determine the real meaning a check is made if project-id - by the specified name exists, and then if main target of that - name exists. For example, valid target ids might be: - - -a -- target in current project -lib/b.cpp -- regular file -/boost/thread -- project "/boost/thread" -/home/ghost/build/lr_library//parser -- target in specific project - - - - - Rationale:Target is separated from project by special - separator (not just slash), because: - - - - - It emphasises that projects and targets are different things. - - - - - - It allows to have main target names with slashes. - - - - - - - - Target reference is used to - specify a source target, and may additionally specify desired - properties for that target. It has this syntax: - - -target-reference -> target-id [ "/" requested-properties ] -requested-properties -> property-path - - - -For example, - - -exe compiler : compiler.cpp libs/cmdline/<optimization>space ; - - -would cause the version of cmdline library, -optimized for space, to be linked in even if the -compiler executable is build with optimization for -speed. - -
-
- Builtin facilities - -
- Main targets - - - exe - - - - Creates a regular executable file. Sources must be either - object files or libraries, and sources of different types - will be converted to accepted types automatically. - - - - - lib - - - Creates a library file. Depending on the value of - <link> feature the library will be either static or - shared. Like with "exe", sources will be converted either to - objects or libraries. - - The handling of libraries in sources depends on whether - linking is static or shared. For shared linking, libraries - will be linked in. For static linking the library sources - will not be linked in, since it's not possible, and will be - passed on. Other main target which depend on this one will - see those libraries and link to it. Therefore, putting - library in sources of other library works in all cases. - - - alias - - - - Builds all the source targets and returns them unmodified. - Please run "bjam --help alias" for more details. - - - - stage - - - - Copies a number of targets to a single directory. The - primary purpose is installing binaries. Please run "bjam --help - stage" for more details. - - - - unit-test (from module "testing") - - - - Creates an executable file and runs it. Build won't succeed - unless the executable runs successfully. The rule is usefull - for creating test program which should be rerun whenever any - dependency changes. - - - - -
- -
- Features - - - variant - - - - The feature which combines several low-level features in - order to make building most common variants simple. - - - Allowed values: debug, release, - profile - - The value debug expands to - - -<optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on - - - The value release expands to - - -<optimization>speed <debug-symbols>off <inlining>full <runtime-debugging>off - - - The value profile expands to the same as - release, plus: - - -<profiling>on <debug-symbols>on - - - Rationale: Runtime debugging is on in debug build - so suit expectations of people used various IDEs. It's - assumed other folks don't have any specific expectation in - this point. - - - link - - - - Feature which controls how libraries are built. - - - Allowed values: shared, - static - - - library - - - - For exe and lib main targets, the <library>X feature - is equvivalent to putting X in the list of sources. The feature - is sometimes more convenient: you can put <library>X in - the requirements for a project and it will be linked to all - executables. - - - - - use - - - - Causes the target referenced by the value of this feature - to be constructed and adds it's usage requirements to build - properties. The constructed targets are not used in any other - way. The primary use case is when you use some library and want - it's usage requirements (such as include paths) to be applied, - but don't want to link to the library. - - - - - dll-path - - - - Specify a path where dynamic libraries should be found at - where executable or shared library is run. This feature - directly affects binaries with the gcc compiler, allowing them - to pick specific libraries, and ignoring all environment - settings. On other toolsets, the binary still requires proper - environment settings to be run. However, Boost.Build tools - which run executables will notice dll-path settings and create - this environment automatically. - - - - hardcode-dll-paths - - - - Controls automatic generation of dll-path properties. - - - Allowed values: off, on When this - property is on, usage requirements for each library will - include additional dll-path propertry, with the path the the - generated library file. This allows to run executables - without placing all the dependent libraries to a single - location. - - - -
-
- - - - Detailed reference - -
- Features and properties - -
- Definitions - - A feature is a normalized (toolset-independent) - aspect of a build configuration, such as whether inlining is - enabled. Feature names may not contain the '>' - character. - - - - Each feature in a build configuration has one or more - associated values. Feature values for non-free features - may not contain the '<', ':', or - '=' characters. Feature values for free features may not - contain the '<' character. - - A property is a (feature,value) pair, expressed as - <feature>value. - - A subfeature is a feature which only exists in the - presence of its parent feature, and whose identity can be derived - (in the context of its parent) from its value. A subfeature's - parent can never be another subfeature. Thus, features and their - subfeatures form a two-level hierarchy. - - A value-string for a feature F is a string of - the form - value-subvalue1-subvalue2...-subvalueN, where - value is a legal value for F and - subvalue1...subvalueN are legal values of some - of F's subfeatures. For example, the properties - <toolset>gcc <toolset-version>3.0.1 can be - expressed more conscisely using a value-string, as - <toolset>gcc-3.0.1. - - A property set is a set of properties (i.e. a - collection without dublicates), for instance: - <toolset>gcc <runtime-link>static. - - A property path is a property set whose elements have - been joined into a single string separated by slashes. A property - path representation of the previous example would be - <toolset>gcc/<runtime-link>static. - - A build specification is a property set which fully - describes the set of features used to build a target. - -
-
- Property Validity - - - For free - features, all values are valid. For all other features, - the valid values are explicitly specified, and the build - system will report an error for the use of an invalid - feature-value. Subproperty validity may be restricted so - that certain values are valid only in the presence of - certain other subproperties. For example, it is possible - to specify that the <gcc-target>mingw - property is only valid in the presence of - <gcc-version>2.95.2. - - -
-
- Feature Attributes - - Each feature has a collection of zero or more of the following - attributes. Feature attributes are low-level descriptions of how - the build system should interpret a feature's values when they - appear in a build request. We also refer to the attributes of - properties, so that a incidental property, for example, is - one whose feature is has the incidental attribute. - - - - incidental - - Incidental features are assumed not to affect build - products at all. As a consequence, the build system may use - the same file for targets whose build specification differs - only in incidental features. A feature which controls a - compiler's warning level is one example of a likely - incidental feature. - - Non-incidental features are assumed to affect build - products, so the files for targets whose build specification - differs in non-incidental features are placed in different - directories as described in "target paths" below. [ where? ] - - - - - - - propagated - - - Features of this kind are - propagated to dependencies. That is, if a main target is built using a - propagated - property, the build systems attempts to use the same property - when building any of its dependencies as part of that main - target. For instance, when an optimized exectuable is - requested, one usually wants it to be linked with optimized - libraries. Thus, the <optimization> feature is - propagated. - - - - - - free - - - Most features have a finite set of allowed values, and can - only take on a single value from that set in a given build - specification. Free features, on the other hand, can have - several values at a time and each value can be an arbitrary - string. For example, it is possible to have several - preprocessor symbols defined simultaneously: - - -<define>NDEBUG=1 <define>HAS_CONFIG_H=1 - - - - - - optional - - An optional feature is a feature which is not required to - appear in a build specification. Every non-optional non-free - feature has a default value which is used when a value for - the feature is not otherwise specified, either in a target's - requirements or in the user's build request. [A feature's - default value is given by the first value listed in the - feature's declaration. -- move this elsewhere - dwa] - - - - symmetric - - A symmetric feature's default value is not automatically - included in build variants. Normally - a feature only generates a subvariant directory when its - value differs from the value specified by the build variant, - leading to an assymmetric subvariant directory structure for - certain values of the feature. A symmetric feature, when - relevant to the toolset, always generates a corresponding - subvariant directory. - - - - path - - The value of a path feature specifies a path. The path is - treated as relative to the directory of Jamfile where path - feature is used and is translated appropriately by the build - system when the build is invoked from a different - directory - - - - implicit - - Values of implicit features alone identify the feature. - For example, a user is not required to write - "<toolset>gcc", but can simply write "gcc". Implicit - feature names also don't appear in variant paths, although - the values do. Thus: bin/gcc/... as opposed to - bin/toolset-gcc/.... There should typically be only a few - such features, to avoid possible name clashes. - - - - composite - - Composite features actually correspond to groups of - properties. For example, a build variant is a composite - feature. When generating targets from a set of build - properties, composite features are recursively expanded and - added to the build property set, so rules can find - them if neccessary. Non-composite non-free features override - components of composite features in a build property set. - - - - link-incompatible - - See below. - - - - dependency - - The value of dependency feature if a target reference. - When used for building of a main target, the value of - dependency feature is treated as additional dependency. - - For example, dependency features allow to state that - library A depends on library B. As the result, whenever an - application will link to A, it will also link to B. - Specifying B as dependency of A is different from adding B to - the sources of A. - - - - Features which are neither free nor incidental are called - base features. - - TODO: document active features.. - -
-
- Feature Declaration - - The low-level feature declaration interface is the - feature rule from the - feature module: - - -rule feature ( name : allowed-values * : attributes * ) - - - A feature's allowed-values may be extended wit The build -system will provide high-level rules which define features in terms -of valid and useful combinations of attributes. - - -
-
- -
- Build Variants - - -A build variant, or (simply variant) is a special kind of composite - feature which automatically incorporates the default values of - features that . Typically you'll want at least two separate - variants: one for debugging, and one for your release code. [ - Volodya says: "Yea, we'd need to mention that it's a composite - feature and describe how they are declared, in pacticular that - default values of non-optional features are incorporated into - build variant automagically. Also, do we wan't some variant - inheritance/extension/templates. I don't remember how it works in - V1, so can't document this for V2.". Will clean up soon -DWA ] - - -
- Link compatible and incompatible properties - - When the build system tries to generate a target (such as - library dependency) matching a given build request, it may find - that an exact match isn't possible — for example, the - target may impose additonal build requirements. We need to - determine whether a buildable version of that target can actually - be used. - - The build request can originate in many ways: it may come - directly from the user's command-line, from a dependency of a - main target upon a library, or from a dependency of a target upon - an executable used to build that target, for example. For each - way, there are different rules whether we can use a given - subvariant or not. The current rules are described below. - - Two property sets are called link-compatible when - targets with those property sets can be used interchangably. In - turn, two property sets are link compatible when there's no - link-incompatible feature which has different values in those - property sets. - - When building of a main target is requested from a command - line or some project, link-compatibility is not considered. When - building is requested by other main target, via sources or - dependency properties, the requested and actual property sets - must be link-compatible, otherwise a warning is produced. - - Rationale:Link-compatibility is not considered when - main target is requested by a project, because it causes problems - in practice. For example, some parts of a project might be - single-threaded, while others — multi-threaded. They are - not link-compatible, but they are not linked, either. So, there's - no need to issue error or warning. The errors used to be - generated, and only caused problems. - -
-
- Definition of property refinement - - When a target with certain properties is requested, and that - target requires some set of properties, it is needed to find the - set of properties to use for building. This process is called - property refinement and is performed by these rules - - - - - If original properties and required properties are not - link-compatible, refinement fails. - - - - - - Each property in the required set is added to the original - property set - - - - - - If the original property set includes property with a different - value of non free feature, that property is removed. - - - -
- -
- Conditional properties - - Sometime it's desirable to apply certain requirements only for - specific combination of other properties. For example, one of - compilers that you use issues a poinless warning that you want to - suppress by passing a command line option to it. You would not - want to pass that option to other compilers. Condititional - properties allow to do that. Their systax is: - - -property ( "," property ) * ":" property - - - -For example, the problem above would be solved by: - - -exe hello : hello.cpp : <toolset>yfc:<cxxflags>-disable-pointless-warning ; - - - -
-
- -
- Initialization - - bjam's first job upon startup is to load the Jam code which - implements the build system. To do this, it searches for a file - called "boost-build.jam", first in the invocation directory, then - in its parent and so forth up to the filesystem root, and finally - in the directories specified by the environment variable - BOOST_BUILD_PATH. When found, the file is interpreted, and should - specify the build system location by calling the boost-build - rule: - - -rule boost-build ( location ? ) - - - -If location is a relative path, it is treated as relative to -the directory of boost-build.jam. The directory specified by -location and directories in BOOST_BUILD_PATH are then searched for -a file called bootstrap.jam which is interpreted and is expected to -bootstrap the build system. This arrangement allows the build -system to work without any command-line or environment variable -settings. For example, if the build system files were located in a -directory "build-system/" at your project root, you might place a -boost-build.jam at the project root containing: - - -boost-build build-system ; - - -In this case, running bjam anywhere in the project tree will -automatically find the build system. - - The default "bootstrap.jam", after loading some standard - definitions, loads two files, which can be provided/customised by - user: "site-config.jam" and "user-config.jam". - - Locations where those files a search are summarized below: - -
- Search paths for configuration files - - - - - - - - site-config.jam - - user-config.jam - - - - - - - Linux - - - /etc - $HOME - $BOOST_BUILD_PATH - - - - $HOME - $BOOST_BUILD_PATH - - - - - Windows - - - $SystemRoot - $HOME - $BOOST_BUILD_PATH - - - - $HOME - $BOOST_BUILD_PATH - - - - -
- - -Boost.Build comes with default versions of those files, - which can serve as templates for customized versions. - - -
-
- Command line - - The command line may contain: - - - Jam options, - - Boost.Build options, - - Command line arguments - - -
- Command line arguments - - - Command line arguments specify targets and build - request using the following rules. - - - - - - An argument which does not contain slashes or the "=" - symbol is either a value of an implicit feature, or target to - be built. It is taken to be value of a feature if appropriate - feature exists. Otherwise, it is considered a target id. Special target name "clean" - has the same effect as "--clean" option. - - - - - - An argument with either slashes or the "=" symbol specifies - a number of build - request - elements. In the simplest form, it's just a set of properties, - separated by slashes, which become a single build request - element, for example: - - -borland/<runtime-link>static - - -More complex form is used to save typing. For example, -instead of - - -borland/runtime-link=static borland/runtime-link=dynamic - - -one can use - - -borland/runtime-link=static,dynamic - - -Exactly, the conversion from argument to build request -elements is performed by (1) splitting the argument at each slash, -(2) converting each split part into a set of properties and (3) -taking all possible combination of the property sets. Each split -part should have the either the form - - -feature-name=feature-value1[","feature-valueN]* - - -or, in case of implict feature - - -feature-value1[","feature-valueN;]* - - -and will be converted into property set - - -<feature-name>feature-value1 .... <feature-name>feature-valueN - - - - - - - -For example, the command line - - -target1 debug gcc/runtime-link=dynamic,static - - -would cause target called target1 to be rebuild in -debug mode, except that for gcc, both dynamically and statically -linked binaries would be created. - - -
-
- Command line options - - All of the Boost.Build options start with the "--" prefix. - They are described in the following table. - - - Command line options - - - - - Option - - Description - - - - - - --version - - Prints information on Boost.Build and Boost.Jam - versions. - - - - --help - - Access to the online help system. This prints general - information on how to use the help system with additional - --help* options. - - - - --clean - - Removes everything instead of building. Unlike - clean target in make, it is possible to clean only - some targets. - - - - --debug - - Enables internal checks. - - - - --dump-projects - - Cause the project structure to be output. - - - - --no-error-backtrace - - Don't print backtrace on errors. Primary usefull for - testing. - - - - --ignore-config - - Do not load site-config.jam and - user-config.jam - - - -
- -
-
- -
- Build request - - -
- -
- Build process - - Construction of each main target begins with finding - properties for this main target. They are found by - processing both build request, and target requirements, - which give properties needed for the target to build. For - example, a given main target might require certian defines, or - will not work unless compiled in multithreaded mode. The process - of finding properties for main target is described in property refinement. - - After that, dependencies (i.e. other main targets) are build - recursively. Build request for dependencies is not always equal - to those of dependent — certain properties are dropped and - user can explicitly specify desired properties for dependencies. - See - propagated features and for details. - - When dependencies are constructed, the dependency graph for - this main target and for this property set is created, which - describes which files need to be created, on which other files - they depend and what actions are needed to construct those files. - There's more that one method, and user can define new ones, but - usually, this involves generators and target - types. - - Target type is just a way to classify targets. For example, - there are builtin types EXE, OBJ and - CPP. Generators are objects - that know how to convert between different target type. When a - target of a given type must be created, all generators for that - type, which can handle needed properties, are found. Each is - passed the list of sources, and either fails, or returns a - dependency graph. If a generator cannot produce desired type from - given sources, it may try to recursively construct types that it - can handle from the types is was passed. This allows to try all - possible transformations. When all generators are tried, a - dependency graph is selected. - - Finally, the dependency graph is passed to underlying - Boost.Jam program, which runs all actions needed to bring all - main targets up-to date. At this step, implicit dependencies are - also scanned and accounted for, as described "here." [ link? ] - - Given a list of targets ids and a build request, building goes - this way. First, for each id we obtain the abstract targets - corresponding to it. This also loads all necessary projects. If - no target id is given, project in the current directory is used. - Build request is expanded, and for each resulting property set, - the generate method of all targets is called, which - yields a list of virtual targets. After that all virtual targets - are actualized, and target "all" is set to depend on all created - actual targets. Lastly, depending on whether --clean - option was given, either target "all" or target "clean" is - updated. Generation of virtual target from abstract one is - performed as follows: - - - - For project targets, all of main targets are generated - with the same properties. Then all projects referred via - "build-project" are generated as well. If it's not possible - to refine requested properties with project requirements, the - project is skipped. - - - It is possible to disable building of certain target using the - explicit rule, available in all project - modules. The syntax is - - -rule explicit ( target-name ) - - - If this rule is invoked on a target, it will be built only -when it's explicitly requested on the command line. - - - - - - For main target, with several alternatives, one of them is - selected as described below. - If there's only one - alternative, it's used unconditionally. - - - - - All main target alternatives which requirements are - satisfied by the build request are enumerated. - - - - - - If there are several such alternatives, the one which - longer requirements list is selected. - - - - - - - - - For the selected alternative - - - - - Each target reference in the source list are - recursively constructed. - - - - - - Properties are refined with alternative's requirements, - and active features in the resulting set are executed. - - - - - - Conditional properties are evaluated. - - - - - - The dependency graph for the target is constructed in a - way which depends on the kind of main target, typically - using generators. - - - - - - - - - If, when building sources, the properties on recursively - created targets are not link-compatibile with build properties, - a warning is issued. - - - - -
- -
- Alternative selection - - When there are several alternatives, one of them must be - selected. The process is as follows: - - - - - For each alternative condition is defined - as the set of base properies in requirements. [Note: it might be - better to explicitly specify the condition explicitly, as in - conditional requirements]. - - - - - - An alternative is viable only if all properties in condition - are present in build request. - - - - - - If there's one viable alternative, it's choosen. Otherwise, - an attempt is made to find one best alternative. An alternative - a is better than another alternative b, iff set of properties - in b's condition is stict subset of the set of properities of - 'a's condition. If there's one viable alternative, which is - better than all other, it's selected. Otherwise, an error is - reported. - - - - -
- -
- Generated headers - - Usually, Boost.Build handles implicit dependendies completely - automatically. For example, for C++ files, all #include - statements are found and handled. The only aspect where user help - might be needed is implicit dependency on generated files. - - By default, Boost.Build handles such dependencies within one - main target. For example, assume that main target "app" has two - sources, "app.cpp" and "parser.y". The latter source is converted - into "parser.c" and "parser.h". Then, if "app.cpp" includes - "parser.h", Boost.Build will detect this dependency. Moreover, - since "parser.h" will be generated into a build directory, the - path to that directory will automatically added to include - path. - - Making this mechanism work across main target boundaries is - possible, but imposes certain overhead. For that reason, if - there's implicit dependency on files from other main targets, the - <implicit-dependency> [ link ] feature must - be used, for example: - - -lib parser : parser.y ; -exe app : app.cpp : <implicit-dependency>parser ; - - - -The above example tells the build system that when scanning -all sources of "app" for implicit-dependencies, it should consider -targets from "parser" as potential dependencies. - - -
-
- Generators - - To construct a main target with given properties from sources, - it is required to create a dependency graph for that main target, - which will also include actions to be run. The algorithm for - creating the dependency graph is described here. - - The fundamental concept is generator. If encapsulates - the notion of build tool and is capable to converting a set of - input targets into a set of output targets, with some properties. - Generator matches a build tool as closely as possible: it works - only when the tool can work with requested properties (for - example, msvc compiler can't work when requested toolset is gcc), - and should produce exactly the same targets as the tool (for - example, if Borland's linker produces additional files with debug - information, generator should also). - - Given a set of generators, the fundamental operation is to - construct a target of a given type, with given properties, from a - set of targets. That operation is performed by rule - generators.construct and the used algorithm is described - below. - -
- Selecting and ranking viable generators - - Each generator, in addition to target types that it can - produce, have attribute that affects its applicability in - particular sitiation. Those attributes are: - - - - - Required properties, which are properties absolutely - necessary for the generator to work. For example, generator - encapsulating the gcc compiler would have <toolset>gcc as - required property. - - - - - - Optional properties, which increase the generators - suitability for a particual build. - - - - - - Generator's required and optional properties may not include - either free or incidental properties. (Allowing this would - greatly complicate caching targets). - - - When trying to construct a target, the first step is to select - all possible generators for the requested target type, which - required properties are a subset of requested properties. - Generators which were already selected up the call stack are - excluded. In addition, if any composing generators were selected - up the call stack, all other composing generators are ignored - (TODO: define composing generators). The found generators - assigned a rank, which is the number of optional properties - present in requested properties. Finally, generators with highest - rank are selected for futher processing. - -
-
- Running generators - - When generators are selected, each is run to produce a list of - created targets. This list might include targets which are not of - requested types, because generators create the same targets as - some tool, and tool's behaviour is fixed. (Note: should specify - that in some cases we actually want extra targets). If generator - fails, it returns an empty list. Generator is free to call - 'construct' again, to convert sources to the types it can handle. - It also can pass modified properties to 'constuct'. However, a - generator is not allowed to modify any propagated properties, - otherwise when actually consuming properties we might discover - that the set of propagated properties is different from what was - used for building sources. - - For all targets which are not of requested types, we try to - convert them to requested type, using a second call to - construct. This is done in order to support - transformation sequences where single source file expands to - several later. See this - message for details. - -
- -
- Selecting dependency graph - - - After all generators are run, - it is necessary to decide which of successfull invocation will be - taken as final result. At the moment, this is not done. Instead, - it is checked whether all successfull generator invocation - returned the same target list. Error is issued otherwise. - - -
- -
- Property adjustment - - Because target location is determined by the build system, it - is sometimes necessary to adjust properties, in order to not - break actions. For example, if there's an action which generates - a header, say "a_parser.h", and a source file "a.cpp" which - includes that file, we must make everything work as if a_parser.h - is generated in the same directory where it would be generated - without any subvariants. - - Correct property adjustment can be done only after all targets - are created, so the approach taken is: - - - - - When dependency graph is constructed, each action can be - assigned a rule for property adjustment. - - - - - - When virtual target is actualized, that rule is run and - return the final set of properties. At this stage it can use - information of all created virtual targets. - - - - - In case of quoted includes, no adjustment can give 100% - correct results. If target dirs are not changed by build system, - quoted includes are searched in "." and then in include path, - while angle includes are searched only in include path. When - target dirs are changed, we'd want to make quoted includes to be - search in "." then in additional dirs and then in the include - path and make angle includes be searched in include path, - probably with additional paths added at some position. Unless, - include path already has "." as the first element, this is not - possible. So, either generated headers should not be included - with quotes, or first element of include path should be ".", - which essentially erases the difference between quoted and angle - includes. Note: there only way to get "." as include path - into compiler command line is via verbatim compiler option. In - all other case, Boost.Build will convert "." into directory where - it occurs. - -
- -
- Transformations cache - - - Under certain conditions, an - attempt is made to cache results of transformation search. First, - the sources are replaced with targets with special name and the - found target list is stored. Later, when properties, requested - type, and source type are the same, the store target list is - retrieved and cloned, with appropriate change in names. - - -
-
- -
- - - Boost.Build development - - [ TODO ] - - - - Frequently Asked Questions - -
- I'm getting "Duplicate name of actual target" error. - What does it mean? - - - - The most likely case is that you're trying to - compile the same file twice, with almost the same, - but differing properties. For example: - - -exe a : a.cpp : <include>/usr/local/include ; -exe b : a.cpp ; - - - - - - The above snippet requires two different compilations - of 'a.cpp', which differ only in 'include' property. - Since the 'include' property is free, Boost.Build - can't generate two ojects files into different directories. - On the other hand, it's dangerous to compile the file only - once -- maybe you really want to compile with different - includes. - - - - To solve this issue, you need to decide if file should - be compiled once or twice. - - - - Two compile file only once, make sure that properties - are the same: - - -exe a : a.cpp : <include>/usr/local/include ; -exe b : a.cpp : <include>/usr/local/include ; - - - - If changing the properties is not desirable, for example - if 'a' and 'b' target have other sources which need - specific properties, separate 'a.cpp' into it's own target: - - -obj a_obj : a.cpp : <include>/usr/local/include ; -exe a : a_obj ; - - - - To compile file twice, you can make the object file local - to the main target: - - - exe a : [ obj a_obj : a.cpp ] : <include>/usr/local/include ; - exe b : [ obj a_obj : a.cpp ] ; - - - - - A good question is why Boost.Build can't use some of the above - approaches automatically. The problem is that such magic would - require additional implementation complexities and would only - help in half of the cases, while in other half we'd be silently - doing the wrong thing. It's simpler and safe to ask user to - clarify his intention in such cases. - -
- - -
- - - - Extender Manual - -
- Introduction - - This document explains how to extend Boost.Build to accomodate - your local requirements. Let's start with quite simple, but - realistic example. - - Say you're writing an application which generates C++ code. If - you ever did this, you know that it's not nice. Embedding large - portions of C++ code in string literals is very awkward. A much - better solution is: - - - - - Write the template of the code to be generated, leaving - placeholders at the points which will change - - - - - - Access the template in your application and replace - placeholders with appropriate text. - - - - - Write the result. - - - - It's quite easy to archive. You write special verbatim files, - which are just C++, except that the very first line of the file - gives a name of variable that should be generated. A simple tool - is created which takes verbatim file and creates a cpp file with - a single char* variable, which name is taken from the first line - of verbatim file, and which value is properly quoted content of - the verbatim file. - - Let's see what Boost.Build can do. - - First off, Boost.Build has no idea about "verbatim files". So, - you must register a new type. The following code does it: - - -import type ; -type.register VERBATIM : verbatim ; - - - The first parameter to 'type.register' gives the name of - declared type. By convention, it's uppercase. The second - parameter is suffix for this type. So, if Boost.Build sees - "code.verbatim" in the list of sources, it knows that it's of - type VERBATIM. - - Lastly, you need a tool to convert verbatim files to C++. Say - you've sketched such a tool in Python. Then, you have to inform - Boost.Build about the tool. The Boost.Build concept which - represents a tool is generator. - - First, you say that generator 'inline-file' is able to convert - VERBATIM type into C++: - - -import generators ; -generators.register-standard verbatim.inline-file : VERBATIM : CPP ; - - - Second, you must specify the commands to be run to actually - perform convertion: - - -actions inline-file -{ - "./inline-file.py" $(<) $(>) -} - - - - Now, we're ready to tie it all together. Put all the code - above in file "verbatim.jam", add "import verbatim ;" to - "project-root.jam", and it's possible to write the following in - Jamfile: - - -exe codegen : codegen.cpp class_template.verbatim usage.verbatim ; - - - -The verbatim files will be automatically converted into C++ -and linked it. - - - The complete code is available in example/customization - directory. - -
-
- Target types - -
- -
- Tools - -
- -
- Main target rules - -
- -
- Scanners - -
-
- - - Boost Build System V2 recipes - -
- Targets in site-config.jam - - It is desirable to declare standard libraries available on a - given system. Putting target declaration in Jamfile is not really - good, since locations of the libraries can vary. The solution is - to put the following to site-config.jam. - - -import project ; -project.initialize $(__name__) ; -project site-config ; -lib zlib : : <name>z ; - - - The second line allows this module to act as project. The - third line gives id to this project — it really has no location - and cannot be used otherwise. The fourth line just declares a - target. Now, one can write - - -exe hello : hello.cpp /site-config//zlib ; - - - in any Jamfile. - -
-
- - - Boost.Build v2 architecture - - - This document is work-in progress. Don't expect much from it - yet. - - -
- Targets - - There are two user-visible kinds of targets in Boost.Build. - First are "abstract" — they correspond to things declared - by user, for example, projects and executable files. The primary - thing about abstract target is that it's possible to request them - to be build with a particular values of some properties. Each - combination of properties may possible yield different set of - real file, so abstract target do not have a direct correspondence - with files. - - File targets, on the contary, are associated with concrete - files. Dependency graphs for abstract targets with specific - properties are constructed from file targets. User has no was to - create file targets, however it can specify rules that detect - file type for sources, and also rules for transforming between - file targets of different types. That information is used in - constructing dependency graph, as desribed in the "next section". - [ link? ] Note:File targets are not - the same as targets in Jam sense; the latter are created from - file targets at the latest possible moment. Note:"File - target" is a proposed name for what we call virtual targets. It - it more understandable by users, but has one problem: virtual - targets can potentially be "phony", and not correspond to any - file. - -
- Dependency scanning - - Dependency scanning is the process of finding implicit - dependencies, like "#include" statements in C++. The requirements - for right dependency scanning mechanism are: - - - - - Support for different scanning algorithms. C++ and XML have - quite different syntax for includes and rules for looking up - included files. - - - - - - Ability to scan the same file several times. For example, - single C++ file can be compiled with different include - paths. - - - - - - Proper detection of dependencies on generated files. - - - - - - Proper detection of dependencies from generated file. - - - - -
- Support for different scanning algorithms - - Different scanning algorithm are encapsulated by objects - called "scanners". Please see the documentation for "scanner" - module for more details. - -
- -
- Ability to scan the same file several times - - As said above, it's possible to compile a C++ file twice, with - different include paths. Therefore, include dependencies for - those compilations can be different. The problem is that bjam - does not allow several scans of the same target. - - The solution in Boost.Build is straigtforward. When a virtual - target is converted to bjam target (via - virtual-target.actualize method), we specify the scanner - object to be used. The actualize method will create different - bjam targets for different scanners. - - All targets with specific scanner are made dependent on target - without scanner, which target is always created. This is done in - case the target is updated. The updating action will be - associated with target without scanner, but if sources for that - action are touched, all targets — with scanner and without - should be considered outdated. - - For example, assume that "a.cpp" is compiled by two compilers - with different include path. It's also copied into some install - location. In turn, it's produced from "a.verbatim". The - dependency graph will look like: - - -a.o (<toolset>gcc) <--(compile)-- a.cpp (scanner1) ----+ -a.o (<toolset>msvc) <--(compile)-- a.cpp (scanner2) ----| -a.cpp (installed copy) <--(copy) ----------------------- a.cpp (no scanner) - ^ - | - a.verbose --------------------------------+ - - -
-
- Proper detection of dependencies on generated files. - - This requirement breaks down to the following ones. - - - - - If when compiling "a.cpp" there's include of "a.h", the - "dir" directory is in include path, and a target called "a.h" - will be generated to "dir", then bjam should discover the - include, and create "a.h" before compiling "a.cpp". - - - - - - Since almost always Boost.Build generates targets to a - "bin" directory, it should be supported as well. I.e. in the - scanario above, Jamfile in "dir" might create a main target, - which generates "a.h". The file will be generated to "dir/bin" - directory, but we still have to recornize the dependency. - - - - - The first requirement means that when determining what "a.h" - means, when found in "a.cpp", we have to iterate over all - directories in include paths, checking for each one: - - - - - If there's file "a.h" in that directory, or - - - - - - If there's a target called "a.h", which will be generated - to that directory. - - - - - Classic Jam has built-in facilities for point (1) above, but - that's not enough. It's hard to implement the right semantic - without builtin support. For example, we could try to check if - there's targer called "a.h" somewhere in dependency graph, and - add a dependency to it. The problem is that without search in - include path, the semantic may be incorrect. For example, one can - have an action which generated some "dummy" header, for system - which don't have the native one. Naturally, we don't want to - depend on that generated header on platforms where native one is - included. - - There are two design choices for builtin support. Suppose we - have files a.cpp and b.cpp, and each one includes header.h, - generated by some action. Dependency graph created by classic jam - would look like: - - -a.cpp -----> <scanner1>header.h [search path: d1, d2, d3] - - - <d2>header.h --------> header.y - [generated in d2] - -b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4] - - - -In this case, Jam thinks all header.h target are not -realated. The right dependency graph might be: - - -a.cpp ---- - \ - \ - >----> <d2>header.h --------> header.y - / [generated in d2] - / -b.cpp ---- - - -or - - -a.cpp -----> <scanner1>header.h [search path: d1, d2, d3] - | - (includes) - V - <d2>header.h --------> header.y - [generated in d2] - ^ - (includes) - | -b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4] - - - - -The first alternative was used for some time. The problem -however is: what include paths should be used when scanning -header.h? The second alternative was suggested by Matt Armstrong. -It has similiar effect: add targets which depend on -<scanner1>header.h will also depend on <d2>header.h. -But now we have two different target with two different scanners, -and those targets can be scanned independently. The problem of -first alternative is avoided, so the second alternative is -implemented now. - - - The second sub-requirements is that targets generated to "bin" - directory are handled as well. Boost.Build implements - semi-automatic approach. When compiling C++ files the process - is: - - - - - The main target to which compiled file belongs is found. - - - - - - All other main targets that the found one depends on are - found. Those include main target which are used as sources, or - present as values of "dependency" features. - - - - - - All directories where files belonging to those main target - will be generated are added to the include path. - - - - - After this is done, dependencies are found by the approach - explained previously. - - Note that if a target uses generated headers from other main - target, that main target should be explicitly specified as - dependency property. It would be better to lift this requirement, - but it seems not very problematic in practice. - - For target types other than C++, adding of include paths must - be implemented anew. - -
-
- Proper detection of dependencies from generated files - - Suppose file "a.cpp" includes "a.h" and both are generated by - some action. Note that classic jam has two stages. In first stage - dependency graph graph is build and actions which should be run - are determined. In second stage the actions are executed. - Initially, neither file exists, so the include is not found. As - the result, jam might attempt to compile a.cpp before creating - a.h, and compilation will fail. - - The solution in Boost.Jam is to perform additional dependency - scans after targets are updated. This break separation between - build stages in jam — which some people consider a good - thing — but I'm not aware of any better solution. - - In order to understand the rest of this section, you better - read some details about jam dependency scanning, available - - at this link. - - Whenever a target is updated, Boost.Jam rescans it for - includes. Consider this graph, created before any actions are - run. - - -A -------> C ----> C.pro - / -B --/ C-includes ---> D - - - -Both A and B have dependency on C and C-includes (the latter -dependency is not shown). Say during building we've tried to create -A, then tried to create C and successfully created C. - - - In that case, the set of includes in C might well have - changed. We do not bother to detect precisely which includes were - added or removed. Instead we create another internal node - C-includes-2. Then we determine what actions should be run to - update the target. In fact this mean that we perform logic of - first stage while already executing stage. - - After actions for C-includes-2 are determined, we add - C-includes-2 to the list of A's dependents, and stage 2 proceeds - as usual. Unfortunately, we can't do the same with target B, - since when it's not visited, C target does not know B depends on - it. So, we add a flag to C which tells and it was rescanned. When - visiting B target, the flag is notices and C-includes-2 will be - added to the list of B's dependencies. - - Note also that internal nodes are sometimes updated too. - Consider this dependency graph: - - -a.o ---> a.cpp - a.cpp-includes --> a.h (scanned) - a.h-includes ------> a.h (generated) - | - | - a.pro <-------------------------------------------+ - - - Here, out handling of generated headers come into play. Say - that a.h exists but is out of date with respect to "a.pro", then - "a.h (generated)" and "a.h-includes" will be marking for - updating, but "a.h (scanned)" won't be marked. We have to rescan - "a.h" file after it's created, but since "a.h (generated)" has no - scanner associated with it, it's only possible to rescan "a.h" - after "a.h-includes" target was updated. - - Tbe above consideration lead to decision that we'll rescan a - target whenever it's updated, no matter if this target is - internal or not. - - - - The remainder of this document is not indended to be read at - all. This will be rearranged in future. - - - -
- File targets - - - As described above, file targets corresponds - to files that Boost.Build manages. User's may be concerned about - file targets in three ways: when declaring file target types, - when declaring transformations between types, and when - determining where file target will be placed. File targets can - also be connected with actions, that determine how the target is - created. Both file targets and actions are implemented in the - virtual-target module. - - -
- Types - - A file target can be given a file, which determines - what transformations can be applied to the file. The - type.register rule declares new types. File type can - also be assigned a scanner, which is used to find implicit - dependencies. See "dependency scanning" [ link? ] below. -
-
- -
- Target paths - - To distinguish targets build with different properties, they - are put in different directories. Rules for determining target - paths are given below: - - - - - All targets are placed under directory corresponding to the - project where they are defined. - - - - - - Each non free, non incidental property cause an additional - element to be added to the target path. That element has the - form <feature-name>-<feature-value> for - ordinary features and <feature-value> for - implicit ones. [Note about composite features]. - - - - - - If the set of free, non incidental properties is different - from the set of free, non incidental properties for the project - in which the main target that uses the target is defined, a - part of the form main_target-<name> is added to - the target path. Note:It would be nice to completely - track free features also, but this appears to be complex and - not extremely needed. - - - - - For example, we might have these paths: - - -debug/optimization-off -debug/main-target-a - - -
-
-
-
-
- -