123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- Hacking on Tor Browser Build
- ============================
- This file tries to list the main things to know when making changes to
- the Tor Browser build.
- rbm documentation
- -----------------
- If you go to directory rbm/doc, you can find the rbm documentation. You
- can build it with 'make html' or 'make man'.
- Using and defining options
- --------------------------
- Options can be used in templates with the following syntax:
- [% c("option_name") %]
- More details about the templates syntax can be found in
- rbm/doc/rbm_templates.7 and [http://template-toolkit.org/docs/manual/index.html].
- Some options have a specific meaning to rbm. You can see their descriptions
- in rbm/doc/rbm_config.7 and rbm/doc/rbm_input_files.7.
- When the option does not have a specific meaning to rbm, it is a good
- idea to define it under var/ to avoid potential conflicts in option names
- with a future version of rbm.
- The options can be defined in different places:
- - rbm.conf for options available to all components
- - project/$project/config for options available to one component
- - rbm.local.conf for user defined options
- In each of those places, an option can be defined:
- - at the root of the document
- - under targets/$target/, in which case the definition only applies when
- a specific target is defined
- The targets are usually used to select:
- - the platform: torbrowser-linux-x86_64, torbrowser-linux-i686,
- torbrowser-windows-i686, torbrowser-windows-x86_64, torbrowser-osx-x86_64,
- torbrowser-android-armv7, torbrowser-android-aarch64, torbrowser-android-x86,
- torbrowser-android-x86_64
- - the channel: release, nightly, alpha
- The targets torbrowser-linux-x86_64, torbrowser-linux-i686,
- torbrowser-windows-i686, torbrowser-windows-x86_64, torbrowser-osx-x86_64,
- torbrowser-android-armv7, torbrowser-android-x86, torbrowser-android-aarch64,
- torbrowser-android-x86_64 are special cases. They do not contain options
- directly, instead they contain a list of other targets. For instance, the
- torbrowser-linux-x86_64 target is pointing to the linux-x86_64 and linux
- targets. You should define an option under the linux target if it applies to
- Linux on both architectures, or under the linux-x86_64 if it only applies to
- the x86_64 architecture.
- An option that is defined at the root of rbm.conf can be overridden by
- an other definition under a target, or inside projects/$project/config.
- You can find the complete priority order in rbm/doc/rbm_config.7.
- Defining a project's filename
- -----------------------------
- The filename option defines the output file or directory from the build
- of a component. If the file or directory exists in the out/$component
- directory, the component will not be rebuilt when it is used as a
- dependency from an other component.
- The filename is usually something like this:
- filename: '[% project %]-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %].tar.gz'
- The var/build_id value is a hash that is based on the build inputs of
- the component:
- - the build script (after template evaluation)
- - the container definition
- - the input files (the filename when it is a dependency on an other
- project, the filename and hash of its content otherwise)
- This means that each time the build script, the container or one of the
- dependencies is modified, the output filename will change and a rebuild
- of the component will be required.
- The version and var/osname values could be removed from the filename,
- but they are useful to get an idea of what a file contains.
- Adding some Linux/Windows/OSX specific changes to a build script
- ----------------------------------------------------------------
- You can use the following template syntax in the build scripts:
- [% IF c("var/linux") -%]
- # do something for linux
- [% ELSIF c("var/windows") -%]
- # do something for windows
- [% ELSIF c("var/osx") -%]
- # do something for osx
- [% END -%]
- You can also use var/linux-x86_64 and var/linux-i686 for things that
- only apply to x86_64 and i686 linux builds. You can use the var/release,
- var/alpha and var/nightly options to do things depending on the channel.
- As an alternative you can define an option with a different value
- depending on the target:
- targets:
- linux:
- var:
- do_something: 'do something for linux'
- windows-i686:
- var:
- do_something: 'do something for windows'
- osx-x86_64:
- var:
- do_something: 'do something for osx'
- And in the build script, use:
- [% c("var/do_something") %]
- Evaluating a component's build script
- -------------------------------------
- If you want to look at the build script used to build a component for a
- specific platform/channel, you can use the following command:
- $ ./rbm/rbm showconf $component build --target $channel --target $platform
- $component should be replaced by the name of the component.
- $channel should be one of the following:
- - release
- - alpha
- - nightly
- $platform should be one of the following:
- - torbrowser-linux-x86_64
- - torbrowser-linux-i686
- - torbrowser-windows-i686
- - torbrowser-windows-x86_64
- - torbrowser-osx-x86_64
- - torbrowser-android-armv7
- - torbrowser-android-aarch64
- - torbrowser-android-x86
- - torbrowser-android-x86_64
- For example, to see tor's build script for linux x86_64 on the alpha
- channel, you can use:
- $ ./rbm/rbm showconf tor build --target alpha --target \
- torbrowser-linux-x86_64
- If the component you are looking at has many dependencies, the display
- can take some time as various build_id values need to be computed. If
- you don't care about the accuracy of input and output file names, you
- can add '--target no_build_id' to the command line. For instance, if you
- want to look at the build script for the tor-browser component (which
- has a lot of dependencies), you can use:
- $ ./rbm/rbm showconf tor build --target alpha --target \
- torbrowser-linux-x86_64 --target no_build_id
- The same type of commands can be used to look at any option values,
- replacing build with the name of the option you want to look at. For
- instance, if you want to know the output filename of tor on linux-x86_64
- on the alpha channel, you can use:
- $ ./rbm/rbm showconf tor filename --target alpha --target \
- torbrowser-linux-x86_64
- Building a single component
- ---------------------------
- When you are working on some changes to a component, before creating a
- full bundle with those changes, you might want to try a build of the
- component you modified only.
- This can be done with the following command:
- $ ./rbm/rbm build $component --target $channel --target $platform
- See the previous section "Evaluating a component's build script" for a
- list of possible values for $channel and $platform.
- For instance, if you want to build tor for linux-x86_64 on the alpha
- channel, you can run:
- $ ./rbm/rbm build tor --target alpha --target torbrowser-linux-x86_64
- To find the resulting file from the build, you can use 'ls -ltr out/tor/'
- to find the file with the last modification time.
- Patching Firefox (or an other component)
- ----------------------------------------
- If you want to test a Firefox patch, the easiest way to do it is to
- copy the patch file to the projects/firefox/ directory, then edit
- projects/firefox/config to add the new patch to the list of input_files:
- - filename: patch-for-XXXX.patch
- Then edit projects/firefox/build to add a line somewhere (probably just
- before running the configure script) to apply the patch:
- patch -p1 < $rootdir/patch-for-XXXX.patch
- You can now run 'make testbuild' (or an other build target) to start a
- build with the patch.
- As an alternative, if you have your patch in a git repository, you can
- edit projects/firefox/config to change the git_url option to point to
- your git repository, and change the git_hash option to point to the
- commit you want to build. If the new git_hash option is not pointing to
- a signed tag, you will also need to comment the 'tag_gpg_id: 1' line.
- The git_hash option can point to a tag, a commit, a branch or anything
- that is understood by git.
- If you specify a branch in the git_hash option, you don't need to prefix
- it with a git remote name as all branches from the git repository
- selected in the git_url option are created as local branches.
- If you want to work on a local git repository, it is not a good idea to
- work on the git_clones/firefox repository directly. Instead you should
- create a separate git repository and update the git_url option with a
- file:// URL pointing to your repository.
- After changing the git_url option or when new commits have been added
- to a branch, you should run "make fetch" before starting a build to get
- the new commits. If you want to fetch new commits automatically when
- starting a new build you can add a "fetch: 1" line to
- projects/firefox/config.
- Remember that the git_hash option has different definitions for alpha
- and nightly builds, so you should modify the right one depending on
- what type of build you are doing (see also the "Types of builds" section).
- The first alternative is not working in case patches contain binary diffs,
- which the patch command can't handle. However, working with submodules can
- make the git branch alternative tricky to use. In that case you can resort
- to a third option by installing git in the build container (via var/deps in
- the respective config file). Then you can change to the submodule directory
- in the build script and do a
- git apply patch-for-XXXX.patch
- after adding the patch to the project's config file (see above).
- The Firefox mozconfig files
- ---------------------------
- In the gitian build, we are using the mozconfig files included in the
- tor-browser.git repository (the .mozconfig, .mozconfig-mac and
- .mozconfig-mingw files).
- In the rbm build however, we need to make some small modifications to
- those files, so we are instead using mozconfig files stored in the
- projects/firefox/ directory, ignoring the .mozconfig files from the
- tor-browser.git repository.
- This could change in the future, when we are not using Gitian anymore.
- Debugging a build error
- -----------------------
- If the build fails, a debugging shell will automatically be opened in
- the container used for the build (unless you set debug to 0 in
- rbm.local.conf).
- Before using the debugging shell, you can first look at the build logs
- in an other terminal (the filename of the log file is indicated in the
- rbm output).
- In the debug shell, you can type 'bash' to get a shell with completion.
- You can then look at the 'build' file, and copy paste some of its commands
- to debug the problem. If you need to edit files, vim is not installed
- in the build containers, but vi can be used instead.
- When you press ctrl+d (twice if you opened a bash shell) the debug shell
- is closed and the container containing the failed build is removed.
- The path to the container should be printed on the screen in case you
- want to backup its rootfs to be able to look at it later.
- Manually removing old containers
- --------------------------------
- When a build finishes or when you exit a debugging shell, the old
- container should automatically be removed. In some cases however, for
- example your computer is rebooted in the middle of a build, some old
- container directories may be left in the tmp directory. Some of the
- files in the container directories are owned by subordinate user ids
- (see the subuid man page), which will prevent you from removing them
- with your normal user id. To remove them you can open a container
- shell (a new User namespace) using the following command:
- $ ./rbm/container run -- /bin/bash
- From this shell you should be able to remove the old containers
- directories in the tmp directory.
- It is also possible to pass the rm command directly without opening a
- shell:
- $ ./rbm/container run -- rm -Rf ./tmp/rbm-*
- Testing an rbm patch
- --------------------
- When you are working on a patch to rbm, you might want to try a Tor
- Browser build using your patched version of rbm. You could patch the
- rbm in the rbm/ directory, however your patch can be reverted if you
- use any of the makefile rules that does a 'git submodule update'.
- To avoid this you can clone the rbm git repository to a separate
- directory, where you will apply your patch. To do a build using your
- patched rbm, take the command from the makefile, but replace $(rbm)
- with the path to your patched rbm.
- For example, if you want to try a Linux x86_64 alpha build, you can run:
- $ /path_to_rbm/rbm build release --target alpha --target \
- torbrowser-linux-x86_64
- Types of builds: nightly, alpha, release, and testbuild
- -------------------------------------------------------
- The testbuild makefile target allows you to do a build quickly in the
- testbuild directory, skipping the generation of all the locales and the
- .mar files. This is useful during development.
- In the case of Android builds, we are generating a multi-locale apk,
- contrary to the desktop builds where we have one bundle for each locale.
- Removing locales in a multi-locale bundle does not make a significant
- difference in build time, therefore we still include all the locales in
- the Android testbuild. There are also no .mar files generated in the
- Android builds, so currently, in the Android case, the only difference
- introduced by the testbuild target is the output directory.
- By default the testbuild is based on the alpha build. All the options
- can have a different definition for the alpha, release and nightly builds.
- Usually the git_hash option has a different definition for the nightly
- builds in order to point to the master branch.
- If you want your testbuild target to create builds based on nightly
- rather than alpha, you can edit your rbm.local.conf file and uncomment
- the targets/torbrowser-testbuild definition.
|