diff --git a/v2/doc/src/tasks.xml b/v2/doc/src/tasks.xml new file mode 100644 index 000000000..d92ec2ebf --- /dev/null +++ b/v2/doc/src/tasks.xml @@ -0,0 +1,739 @@ + + + + + Common tasks + + This section describes main targets types that Boost.Build supports + of-of-the-box. Unless otherwise noted, all mentioned main target rules + have the common signature, described in . + + +
+ Programs + + Builtin + rulesexe + Programs are created using the exe rule, which + follows the common + syntax. For example: + +exe hello : hello.cpp some_library.lib /some_project//library + : <threading>multi + ; + + This will create an executable file from the sources -- in this case, + one C++ file, one library file present in the same directory, and + another library that is created by Boost.Build. Generally, sources + can include C and C++ files, object files and libraries. Boost.Build + will automatically try to convert targets of other types. + + + + + On Windows, if an application uses dynamic libraries, and both + the application and the libraries are built by Boost.Build, its not + possible to immediately run the application, because the + PATH environment variable should include the path + to the libraries. It means you have to either add the paths + manually, or place the application and the libraries to the same + directory, for example using the + stage rule. + + + +
+ +
+ Libraries + + Libraries are created using the lib rule, which + follows the common + syntax. For example: + +lib helpers : helpers.cpp : <include>boost : : <include>. ; + + + + In the most common case, the lib creates a library + from the specified sources. Depending on the value of + <link> feature the library will be either static or + shared. There are two other cases. First is when the library is + installed somewhere in compiler's search paths, and should be + searched by the compiler (typically, using the + option). The second case is where the library is available as a + prebuilt file and the full path is known. + + + + + The syntax for these case is given below: + +lib z : : <name>z <search>/home/ghost ; +lib compress : : <file>/opt/libs/compress.a ; + + The name property specifies the name that should be + passed to the option, and the file + property specifies the file location. The search feature + specifies paths in which to search for the library. That feature can + be specified several times, or it can be omitted, in which case only + default compiler paths will be searched. + + + The difference between using the file feature as + opposed to the name feature together with the + search feature is that file is more + precise. A specific file will be used. On the other hand, the + search feature only adds a library path, and the + name feature gives the basic name of the library. The + search rules are specific to the linker. For example, given these + definition: + +lib a : : <variant>release <file>/pool/release/a.so ; +lib a : : <variant>debug <file>/pool/debug/a.so ; +lib b : : <variant>release <file>/pool/release/b.so ; +lib b : : <variant>debug <file>/pool/debug/b.so ; + + It's possible to use release version of a and debug + version of b. Had we used the name and + search features, the linker would always pick either + release or debug versions. + + + + + For convenience, the following syntax is allowed: + +lib z ; +lib gui db aux ; + + and is does exactly the same as: + +lib z : : <name>z ; +lib gui : : <name>gui ; +lib db : : <name>db ; +lib aux : : <name>aux ; + + + + When a library uses another library you should put that other + library in the list of sources. This will do the right thing in all + cases. For portability, you should specify library dependencies even + for searched and prebuilt libraries, othewise, static linking on + Unix won't work. For example: + +lib z ; +lib png : z : <name>png ; + + + + + When a library (say, a), that has another + library, (say, b) + + is linked dynamically, the b + library will be incorporated + + in a. (If b + is dynamic library as well, then a will only refer to + it, and not include any extra code.) + + When the a + library is linked statically, Boost.Build will assure that all + executables that link to a will also link to + b. + + + + One feature of Boost.Build that is very important for libraries + is usage requirements. + + For example, if you write: + +lib helpers : helpers.cpp : : : <include>. ; + + then the compiler include path for all targets that use + helpers will contain the directory + + where the target is defined.path to "helpers.cpp". The user + only needs to add helpers to the list of sources, + and needn't consider the requirements its use imposes on a + dependent target. This feature greatly simplifies Jamfiles. + + + + + If you don't want shared libraries to include all libraries + that are specified in sources (especially statically linked ones), + you'd need to use the following: + +lib b : a.cpp ; +lib a : a.cpp : <use>b : : <library>b ; + + This specifies that a uses b, and causes + all executables that link to a also link to + b. In this case, even for shared linking, the + a library won't even refer to b. + + + +
+ +
+ Alias + + + The alias rule gives alternative name to + a group of targets. For example, to give the name + core to a group of three other targets with the + following code: + +alias core : im reader writer ; + Using core on the command line, or in the source list + of any other target is the same as explicitly using + im, reader, and + writer, but it is just more convenient. + + + + + + Another use of the alias rule is to change build + properties. For example, if you always want static linking for a + specific C++ Boost library, you can write the following: + +alias threads : /boost/thread//boost_thread : <link>static ; + + and use only the threads alias in your Jamfiles. + + + + + You can also specify usage requirements for the + alias target. If you write the following: + +alias header_only_library : : : : <include>/usr/include/header_only_library ; + + then using header_only_library in sources will only add an + include path. Also note that when there are some sources, their usage + requirements are propagated, too. For example: + +lib lib : lib.cpp : : : <include>. ; +alias lib_alias ; +exe main : main.cpp lib_alias ; + + will compile main.cpp with the additional include. + + +
+ +
+ Installing + + This section describes various ways to install built target + and arbitrary files. + + Basic install + + For installing a built target you should use the + install rule, which follows the common syntax. For + example: + +install dist : hello helpers ; + + will cause the targets hello and helpers to + be moved to the dist directory, relative to + Jamfile's directory. The directory can + be changed with the location property: + +install dist : hello helpers : <location>/usr/bin ; + + While you can achieve the same effect by changing the target name to + /usr/bin, using the location + property is better, because it allows you to use a mnemonic target + name. + + + The location property is especially handy when the location + is not fixed, but depends on build variant or environment variables: + +install dist : hello helpers : <variant>release:<location>dist/release + <variant>debug:<location>dist/debug ; +install dist2 : hello helpers : <location>$(DIST) ; + + See also conditional + properties and environment variables + + + Installing with all dependencies + + + Specifying the names of all libraries to install can be boring. The + install allows you to specify only the top-level executable + targets to install, and automatically install all dependencies: + +install dist : hello + : <install-dependencies>on <install-type>EXE + <install-type>LIB + ; + + will find all targets that hello depends on, and install + all of those which are either executables or libraries. More + specifically, for each target, other targets that were specified as + sources or as dependency properties, will be recursively found. One + exception is that targets referred with the use feature + are not considered, because that feature is typically used to refer to + header-only libraries. + If the set of target types is specified, only targets of that type + will be installed, otherwise, all found target will be installed. + + + Preserving Directory Hierarchy + + By default, the install rules will stip paths from + it's sources. So, if sources include a/b/c.hpp, + the a/b part will be ignored. To make the + install rule preserve the directory hierarchy you need + to use the install-source-root feature to specify the + root of the hierarchy you are installing. Relative paths from that + root will be preserved. For example, if you write: + + +install headers + : a/b/c.h + : <location>/tmp <install-source-root>a + ; + + + the a file named /tmp/b/c.h will be created. + + + Installing into Several Directories + + The alias + rule can be used when targets must be installed into several + directories: + +alias install : install-bin install-lib ; +install install-bin : applications : /usr/bin ; +install install-lib : helper : /usr/lib ; + + + + Because the install rule just copies targets, most + free features see the definition of "free" in . + have no effect when used in requirements of the install rule. + The only two which matter are + + dependency and, on Unix, + dll-path. + + + + + (Unix specific). On Unix, executables built with Boost.Build typically + contain the list of paths to all used dynamic libraries. For + installing, this is not desired, so Boost.Build relinks the executable + with an empty list of paths. You can also specify additional paths for + installed executables with the dll-path feature. + + + + +
+ +
+ + Testing + + Boost.Build has convenient support for running unit tests. The + simplest way is the unit-test rule, which follows the + common syntax. For + example: + +unit-test helpers_test : helpers_test.cpp helpers ; + + + + The unit-test rule behaves like the + exe rule, but after the executable is created it is + run. If the executable returns an error code, the build system will also + return an error and will try running the executable on the next + invocation until it runs successfully. This behaviour ensures that you + can't miss a unit test failure. + + + By default, the executable is run directly. Sometimes, it's + desirable to run the executable using some helper command. You should use the + testing.launcher property to specify the name of the + helper command. For example, if you write: + + +unit-test helpers_test + : helpers_test.cpp helpers + : <testing.launcher>valgrind + ; + + The command used to run the executable will be: + +valgrind bin/$toolset/debug/helpers_test + + + + + There are rules for more elaborate testing: compile, + compile-fail, run and + run-fail. They are more suitable for automated testing, and + are not covered here. + +
+ +
+ + Raw commands: 'make' and 'notfile' + + Sometimes, the builtin target types are not enough, and you + want Boost.Build to just run specific commands. There are two main + target rules that make it possible: make + and notfile. + + + The make rule is used when you want to + create one file from a number of sources using some specific command. + The notfile is used to unconditionally run + a command. + + + + Suppose you want to create file file.out from + file file.in by running command + in2out. Here's how you'd do this in Boost.Build: + +actions in2out +{ + in2out $(<) $(>) +} +make file.out : file.in : @in2out ; + + If you run bjam and file.out + does not exist, Boost.Build will run the in2out + command to create that file. For more details on specifying actions, + see . + + + + + The make rule is useful to express custom + transformation that are used just once or twice in your project. For + transformations that are used often, you are advised to declare + new generator, as described in . + + + + + It could be that you just want to run some command unconditionally, + and that command does not create any specific files. The, you can use + the notfile rule. For example: + +notfile echo_something : @echo ; +actions echo +{ + echo "something" +} + + The only difference from the make rule is + that the name of the target is not considered a name of a file, so + Boost.Build will unconditionally run the action. + + +
+ +
+ 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. + +
+ + +
+ Builtin features + + + variant + + + + A feature that combines several low-level features, making + it easy to request common build configurations. + + + 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 + + + User can define his own build variants using the variant rule from the common + module. + + Notee: Runtime + debugging is on in debug builds to suit the expectations of + people used to various IDEs. + + + + + + link + + + + A feature that controls how libraries are built. + + + Allowed values: shared, + static + + + source + + + + The <source>X feature has the same effect on + building a target as putting X in the list of sources. + It's useful when you want to add + the same source to all targets in the project + (you can put <source> in requirements) or to conditionally + include a source (using conditional requirements, see ) + See also the <library> feature. + + + + + library + + + + This feature is almost equivalent to the <source> feature, + except that it takes effect only for linking. When you want to + link all targets in a Jamfile to certain library, the + <library> feature is preferred over + <source>X -- the latter will add the library to + all targets, even those that have nothing to do with libraries. + + + + + + dependency + + + + Introduces a dependency on the target named by the + value of this feature (so it will be brought + up-to-date whenever the target being declared is). + The dependency is not used in any other way. For example, in + application with plugins, the plugins are not used when linking + the application, + application might have dependency on its plugins, even though + + + , and + adds its usage requirements to the build properties + of the target being declared. + + The primary use case is when you want + the usage requirements (such as #include paths) of some + library to be applied, but don't want to link to it. + + + + + + + + use + + + + Introduces a dependency on the target named by the + value of this feature (so it will be brought + up-to-date whenever the target being declared is), and + adds its usage requirements to the build properties + + of the target being declared. The dependency is not used + in any other way. The primary use case is when you want + the usage requirements (such as #include paths) of some + library to be applied, but don't want to link to it. + + + + + + + dll-path + + + + Specify an additional directory where the system should + look for shared libraries when the executable or shared + library is run. This feature only affects Unix + compilers. Plase see + in for details. + + + + hardcode-dll-paths + + + + Controls automatic generation of dll-path properties. + + + Allowed values: + true, false. This property + is specific to Unix systems. If an executable is built with + <hardcode-dll-paths>true, the generated binary + will contain the list of all the paths to the used shared + libraries. As the result, the executable can be run without + changing system paths to shared libraries or installing the + libraries to system paths. This + + is very convenient during + development. Plase see the FAQ entry for details. + Note that on Mac OSX, the paths are unconditionally hardcoded by + the linker, and it's not possible to disable that behaviour. + + + + + cflags + cxxflags + linkflags + + + + The value of those features is passed without modification to the + corresponding tools. For cflags that's both the C and C++ + compilers, for cxxflags that's the C++ compiler and for + linkflags that's the linker. The features are handy when + you're trying to do something special that cannot be achieved by + higher-level feature in Boost.Build. + + + + + warnings + + + + The <warnings> feature controls the warning level of compilers. It has the following values: + + off - disables all warnings. + on - enables default warning level for the tool. + all - enables all warnings. + + Default value is all. + + + + + warnings-as-errors + + + + The <warnings-as-errors> makes it possible to treat warnings as errors and abort + compilation on a warning. The value on enables this behaviour. The default value is + off. + + + + + build + + + Allowed values: no + + + The build feature is used to conditionally disable build of a target. If <build>no + is in properties when building a target, build of that target is skipped. Combined with conditional requirements this + allows to skip building some target in configurations where the build is known to fail. + + + + + + + + + +
+
+ + + diff --git a/v2/doc/src/v1_vs_v2.xml b/v2/doc/src/v1_vs_v2.xml new file mode 100644 index 000000000..7223175e7 --- /dev/null +++ b/v2/doc/src/v1_vs_v2.xml @@ -0,0 +1,107 @@ + + + + + Differences to Boost.Build V1 + + + While Boost.Build V2 is based on the same ideas as Boost.Build V1, + some of the syntax was changed, and some new important features were + added. This chapter describes most of the changes. + +
+ Configuration + + In V1, toolsets were configured by environment variables. If you + wanted to use two versions of the same toolset, you had to create a new + toolset module that would set the variables and then invoke the base + toolset. In V2, toolsets are configured by the + using, and you can easily configure several + versions of a toolset. See for details. + + +
+ +
+ Writing Jamfiles + + Probably one of the most important differences in V2 Jamfiles is + the use of project requirements. In V1, if several targets had the same + requirements (for example, a common #include path), it was necessary to + manually write the requirements or use a helper rule or template target. In V2, the + common properties can be specified with the requirements project + attribute, as documented in . + + + Usage requirements + also help to simplify Jamfiles. + + If a library requires + all clients to use specific #include paths or macros when compiling + code that depends on the library, that information can be cleanly + represented. + + The difference between lib and dll targets in V1 is completely + eliminated in V2. There's only one library target type, lib, which can create + either static or shared libraries depending on the value of the + <link> + feature. If your target should be only built in one way, you + can add <link>shared or <link>static to its requirements. + + + The syntax for referring to other targets was changed a bit. While + in V1 one would use: + +exe a : a.cpp <lib>../foo/bar ; + + the V2 syntax is: + +exe a : a.cpp ../foo//bar ; + + Note that you don't need to specify the type of other target, but the + last element should be separated from the others by a double slash to indicate that + you're referring to target bar in project ../foo, and not to + project ../foo/bar. + + + +
+ +
+ Build process + + The command line syntax in V2 is completely different. For example + +bjam -sTOOLS=msvc -sBUILD=release some_target + + now becomes: + +bjam toolset=msvc variant=release some_target + + or, using implicit features, just: + +bjam msvc release some_target + + See the reference for a + complete description of the syntax. + + + +
+
+ + + diff --git a/v2/example/pch/include/pch.hpp b/v2/example/pch/include/pch.hpp new file mode 100644 index 000000000..22df8443f --- /dev/null +++ b/v2/example/pch/include/pch.hpp @@ -0,0 +1,11 @@ +/* Copyright 2006 Vladimir Prus + + Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +class TestClass { +public: + TestClass(int, int) {} +}; diff --git a/v2/example/pch/source/hello_world.cpp b/v2/example/pch/source/hello_world.cpp new file mode 100644 index 000000000..f618056a0 --- /dev/null +++ b/v2/example/pch/source/hello_world.cpp @@ -0,0 +1,15 @@ +/* Copyright 2006 Ilya Sokolov + Copyright 2006 Vladimir Prus + + Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +#include + +int main() +{ + TestClass c(1, 2); + return 0; +} diff --git a/v2/test/pch.py b/v2/test/pch.py new file mode 100644 index 000000000..87ca0846b --- /dev/null +++ b/v2/test/pch.py @@ -0,0 +1,70 @@ +#!/usr/bin/python + +# Copyright 2006 Vladimir Prus. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from BoostBuild import Tester, List +import string +import os + +t = Tester() + +t.write("Jamroot", """ + +import pch ; + +cpp-pch pch : pch.hpp : msvc:pch.cpp . ; + +exe hello : hello.cpp pch : . ; +""") + +t.write("pch.hpp.bad", """ +THIS WON'T COMPILE +""") + +# Note that pch.hpp is written after pch.hpp.bad, so its timestamp won't +# be less than timestamp of pch.hpp.bad. +t.write("pch.hpp", """ +class TestClass { +public: + TestClass(int, int) {} +}; + +""") + + + +t.write("pch.cpp", """ #include + +""") + +t.write("hello.cpp", """ #include + +int main() +{ + TestClass c(1, 2); + return 0; +} + +""") + +t.run_build_system() + +t.expect_addition("bin/$toolset/debug/hello.exe") + +# Now make the header unusable, without changing timestamp. +# If everything is OK, Boost.Build won't recreate PCH, and +# compiler will happily use pre-compiled header, not noticing +# that the real header is bad. + +t.copy_preserving_timestamp("pch.hpp.bad", "pch.hpp") + +t.rm("bin/$toolset/debug/hello.obj") + +t.run_build_system() +t.expect_addition("bin/$toolset/debug/hello.obj") + +t.cleanup() +