HACKING.txt 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. Hacking on Tor Browser Build
  2. ============================
  3. This file tries to list the main things to know when making changes to
  4. the Tor Browser build.
  5. rbm documentation
  6. -----------------
  7. If you go to directory rbm/doc, you can find the rbm documentation. You
  8. can build it with 'make html' or 'make man'.
  9. Using and defining options
  10. --------------------------
  11. Options can be used in templates with the following syntax:
  12. [% c("option_name") %]
  13. More details about the templates syntax can be found in
  14. rbm/doc/rbm_templates.7 and [http://template-toolkit.org/docs/manual/index.html].
  15. Some options have a specific meaning to rbm. You can see their descriptions
  16. in rbm/doc/rbm_config.7 and rbm/doc/rbm_input_files.7.
  17. When the option does not have a specific meaning to rbm, it is a good
  18. idea to define it under var/ to avoid potential conflicts in option names
  19. with a future version of rbm.
  20. The options can be defined in different places:
  21. - rbm.conf for options available to all components
  22. - project/$project/config for options available to one component
  23. - rbm.local.conf for user defined options
  24. In each of those places, an option can be defined:
  25. - at the root of the document
  26. - under targets/$target/, in which case the definition only applies when
  27. a specific target is defined
  28. The targets are usually used to select:
  29. - the platform: torbrowser-linux-x86_64, torbrowser-linux-i686,
  30. torbrowser-windows-i686, torbrowser-windows-x86_64, torbrowser-osx-x86_64,
  31. torbrowser-android-armv7, torbrowser-android-aarch64, torbrowser-android-x86,
  32. torbrowser-android-x86_64
  33. - the channel: release, nightly, alpha
  34. The targets torbrowser-linux-x86_64, torbrowser-linux-i686,
  35. torbrowser-windows-i686, torbrowser-windows-x86_64, torbrowser-osx-x86_64,
  36. torbrowser-android-armv7, torbrowser-android-x86, torbrowser-android-aarch64,
  37. torbrowser-android-x86_64 are special cases. They do not contain options
  38. directly, instead they contain a list of other targets. For instance, the
  39. torbrowser-linux-x86_64 target is pointing to the linux-x86_64 and linux
  40. targets. You should define an option under the linux target if it applies to
  41. Linux on both architectures, or under the linux-x86_64 if it only applies to
  42. the x86_64 architecture.
  43. An option that is defined at the root of rbm.conf can be overridden by
  44. an other definition under a target, or inside projects/$project/config.
  45. You can find the complete priority order in rbm/doc/rbm_config.7.
  46. Defining a project's filename
  47. -----------------------------
  48. The filename option defines the output file or directory from the build
  49. of a component. If the file or directory exists in the out/$component
  50. directory, the component will not be rebuilt when it is used as a
  51. dependency from an other component.
  52. The filename is usually something like this:
  53. filename: '[% project %]-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %].tar.gz'
  54. The var/build_id value is a hash that is based on the build inputs of
  55. the component:
  56. - the build script (after template evaluation)
  57. - the container definition
  58. - the input files (the filename when it is a dependency on an other
  59. project, the filename and hash of its content otherwise)
  60. This means that each time the build script, the container or one of the
  61. dependencies is modified, the output filename will change and a rebuild
  62. of the component will be required.
  63. The version and var/osname values could be removed from the filename,
  64. but they are useful to get an idea of what a file contains.
  65. Adding some Linux/Windows/OSX specific changes to a build script
  66. ----------------------------------------------------------------
  67. You can use the following template syntax in the build scripts:
  68. [% IF c("var/linux") -%]
  69. # do something for linux
  70. [% ELSIF c("var/windows") -%]
  71. # do something for windows
  72. [% ELSIF c("var/osx") -%]
  73. # do something for osx
  74. [% END -%]
  75. You can also use var/linux-x86_64 and var/linux-i686 for things that
  76. only apply to x86_64 and i686 linux builds. You can use the var/release,
  77. var/alpha and var/nightly options to do things depending on the channel.
  78. As an alternative you can define an option with a different value
  79. depending on the target:
  80. targets:
  81. linux:
  82. var:
  83. do_something: 'do something for linux'
  84. windows-i686:
  85. var:
  86. do_something: 'do something for windows'
  87. osx-x86_64:
  88. var:
  89. do_something: 'do something for osx'
  90. And in the build script, use:
  91. [% c("var/do_something") %]
  92. Evaluating a component's build script
  93. -------------------------------------
  94. If you want to look at the build script used to build a component for a
  95. specific platform/channel, you can use the following command:
  96. $ ./rbm/rbm showconf $component build --target $channel --target $platform
  97. $component should be replaced by the name of the component.
  98. $channel should be one of the following:
  99. - release
  100. - alpha
  101. - nightly
  102. $platform should be one of the following:
  103. - torbrowser-linux-x86_64
  104. - torbrowser-linux-i686
  105. - torbrowser-windows-i686
  106. - torbrowser-windows-x86_64
  107. - torbrowser-osx-x86_64
  108. - torbrowser-android-armv7
  109. - torbrowser-android-aarch64
  110. - torbrowser-android-x86
  111. - torbrowser-android-x86_64
  112. For example, to see tor's build script for linux x86_64 on the alpha
  113. channel, you can use:
  114. $ ./rbm/rbm showconf tor build --target alpha --target \
  115. torbrowser-linux-x86_64
  116. If the component you are looking at has many dependencies, the display
  117. can take some time as various build_id values need to be computed. If
  118. you don't care about the accuracy of input and output file names, you
  119. can add '--target no_build_id' to the command line. For instance, if you
  120. want to look at the build script for the tor-browser component (which
  121. has a lot of dependencies), you can use:
  122. $ ./rbm/rbm showconf tor build --target alpha --target \
  123. torbrowser-linux-x86_64 --target no_build_id
  124. The same type of commands can be used to look at any option values,
  125. replacing build with the name of the option you want to look at. For
  126. instance, if you want to know the output filename of tor on linux-x86_64
  127. on the alpha channel, you can use:
  128. $ ./rbm/rbm showconf tor filename --target alpha --target \
  129. torbrowser-linux-x86_64
  130. Building a single component
  131. ---------------------------
  132. When you are working on some changes to a component, before creating a
  133. full bundle with those changes, you might want to try a build of the
  134. component you modified only.
  135. This can be done with the following command:
  136. $ ./rbm/rbm build $component --target $channel --target $platform
  137. See the previous section "Evaluating a component's build script" for a
  138. list of possible values for $channel and $platform.
  139. For instance, if you want to build tor for linux-x86_64 on the alpha
  140. channel, you can run:
  141. $ ./rbm/rbm build tor --target alpha --target torbrowser-linux-x86_64
  142. To find the resulting file from the build, you can use 'ls -ltr out/tor/'
  143. to find the file with the last modification time.
  144. Patching Firefox (or an other component)
  145. ----------------------------------------
  146. If you want to test a Firefox patch, the easiest way to do it is to
  147. copy the patch file to the projects/firefox/ directory, then edit
  148. projects/firefox/config to add the new patch to the list of input_files:
  149. - filename: patch-for-XXXX.patch
  150. Then edit projects/firefox/build to add a line somewhere (probably just
  151. before running the configure script) to apply the patch:
  152. patch -p1 < $rootdir/patch-for-XXXX.patch
  153. You can now run 'make testbuild' (or an other build target) to start a
  154. build with the patch.
  155. As an alternative, if you have your patch in a git repository, you can
  156. edit projects/firefox/config to change the git_url option to point to
  157. your git repository, and change the git_hash option to point to the
  158. commit you want to build. If the new git_hash option is not pointing to
  159. a signed tag, you will also need to comment the 'tag_gpg_id: 1' line.
  160. The git_hash option can point to a tag, a commit, a branch or anything
  161. that is understood by git.
  162. If you specify a branch in the git_hash option, you don't need to prefix
  163. it with a git remote name as all branches from the git repository
  164. selected in the git_url option are created as local branches.
  165. If you want to work on a local git repository, it is not a good idea to
  166. work on the git_clones/firefox repository directly. Instead you should
  167. create a separate git repository and update the git_url option with a
  168. file:// URL pointing to your repository.
  169. After changing the git_url option or when new commits have been added
  170. to a branch, you should run "make fetch" before starting a build to get
  171. the new commits. If you want to fetch new commits automatically when
  172. starting a new build you can add a "fetch: 1" line to
  173. projects/firefox/config.
  174. Remember that the git_hash option has different definitions for alpha
  175. and nightly builds, so you should modify the right one depending on
  176. what type of build you are doing (see also the "Types of builds" section).
  177. The first alternative is not working in case patches contain binary diffs,
  178. which the patch command can't handle. However, working with submodules can
  179. make the git branch alternative tricky to use. In that case you can resort
  180. to a third option by installing git in the build container (via var/deps in
  181. the respective config file). Then you can change to the submodule directory
  182. in the build script and do a
  183. git apply patch-for-XXXX.patch
  184. after adding the patch to the project's config file (see above).
  185. The Firefox mozconfig files
  186. ---------------------------
  187. In the gitian build, we are using the mozconfig files included in the
  188. tor-browser.git repository (the .mozconfig, .mozconfig-mac and
  189. .mozconfig-mingw files).
  190. In the rbm build however, we need to make some small modifications to
  191. those files, so we are instead using mozconfig files stored in the
  192. projects/firefox/ directory, ignoring the .mozconfig files from the
  193. tor-browser.git repository.
  194. This could change in the future, when we are not using Gitian anymore.
  195. Debugging a build error
  196. -----------------------
  197. If the build fails, a debugging shell will automatically be opened in
  198. the container used for the build (unless you set debug to 0 in
  199. rbm.local.conf).
  200. Before using the debugging shell, you can first look at the build logs
  201. in an other terminal (the filename of the log file is indicated in the
  202. rbm output).
  203. In the debug shell, you can type 'bash' to get a shell with completion.
  204. You can then look at the 'build' file, and copy paste some of its commands
  205. to debug the problem. If you need to edit files, vim is not installed
  206. in the build containers, but vi can be used instead.
  207. When you press ctrl+d (twice if you opened a bash shell) the debug shell
  208. is closed and the container containing the failed build is removed.
  209. The path to the container should be printed on the screen in case you
  210. want to backup its rootfs to be able to look at it later.
  211. Manually removing old containers
  212. --------------------------------
  213. When a build finishes or when you exit a debugging shell, the old
  214. container should automatically be removed. In some cases however, for
  215. example your computer is rebooted in the middle of a build, some old
  216. container directories may be left in the tmp directory. Some of the
  217. files in the container directories are owned by subordinate user ids
  218. (see the subuid man page), which will prevent you from removing them
  219. with your normal user id. To remove them you can open a container
  220. shell (a new User namespace) using the following command:
  221. $ ./rbm/container run -- /bin/bash
  222. From this shell you should be able to remove the old containers
  223. directories in the tmp directory.
  224. It is also possible to pass the rm command directly without opening a
  225. shell:
  226. $ ./rbm/container run -- rm -Rf ./tmp/rbm-*
  227. Testing an rbm patch
  228. --------------------
  229. When you are working on a patch to rbm, you might want to try a Tor
  230. Browser build using your patched version of rbm. You could patch the
  231. rbm in the rbm/ directory, however your patch can be reverted if you
  232. use any of the makefile rules that does a 'git submodule update'.
  233. To avoid this you can clone the rbm git repository to a separate
  234. directory, where you will apply your patch. To do a build using your
  235. patched rbm, take the command from the makefile, but replace $(rbm)
  236. with the path to your patched rbm.
  237. For example, if you want to try a Linux x86_64 alpha build, you can run:
  238. $ /path_to_rbm/rbm build release --target alpha --target \
  239. torbrowser-linux-x86_64
  240. Types of builds: nightly, alpha, release, and testbuild
  241. -------------------------------------------------------
  242. The testbuild makefile target allows you to do a build quickly in the
  243. testbuild directory, skipping the generation of all the locales and the
  244. .mar files. This is useful during development.
  245. In the case of Android builds, we are generating a multi-locale apk,
  246. contrary to the desktop builds where we have one bundle for each locale.
  247. Removing locales in a multi-locale bundle does not make a significant
  248. difference in build time, therefore we still include all the locales in
  249. the Android testbuild. There are also no .mar files generated in the
  250. Android builds, so currently, in the Android case, the only difference
  251. introduced by the testbuild target is the output directory.
  252. By default the testbuild is based on the alpha build. All the options
  253. can have a different definition for the alpha, release and nightly builds.
  254. Usually the git_hash option has a different definition for the nightly
  255. builds in order to point to the master branch.
  256. If you want your testbuild target to create builds based on nightly
  257. rather than alpha, you can edit your rbm.local.conf file and uncomment
  258. the targets/torbrowser-testbuild definition.