2
1

adding-packages-tips.adoc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. // -*- mode:doc; -*-
  2. // vim: set syntax=asciidoc:
  3. === Tips and tricks
  4. [[package-name-variable-relation]]
  5. ==== Package name, config entry name and makefile variable relationship
  6. In Buildroot, there is some relationship between:
  7. * the _package name_, which is the package directory name (and the
  8. name of the +*.mk+ file);
  9. * the config entry name that is declared in the +Config.in+ file;
  10. * the makefile variable prefix.
  11. It is mandatory to maintain consistency between these elements,
  12. using the following rules:
  13. * the package directory and the +*.mk+ name are the _package name_
  14. itself (e.g.: +package/foo-bar_boo/foo-bar_boo.mk+);
  15. * the _make_ target name is the _package name_ itself (e.g.:
  16. +foo-bar_boo+);
  17. * the config entry is the upper case _package name_ with `.` and `-`
  18. characters substituted with `_`, prefixed with +BR2_PACKAGE_+ (e.g.:
  19. +BR2_PACKAGE_FOO_BAR_BOO+);
  20. * the +*.mk+ file variable prefix is the upper case _package name_
  21. with `.` and `-` characters substituted with `_` (e.g.:
  22. +FOO_BAR_BOO_VERSION+).
  23. [[check-package]]
  24. ==== How to check the coding style
  25. Buildroot provides a script in +utils/check-package+ that checks new or
  26. changed files for coding style. It is not a complete language validator,
  27. but it catches many common mistakes. It is meant to run in the actual
  28. files you created or modified, before creating the patch for submission.
  29. This script can be used for packages, filesystem makefiles, Config.in
  30. files, etc. It does not check the files defining the package
  31. infrastructures and some other files containing similar common code.
  32. To use it, run the +check-package+ script, by telling which files you
  33. created or changed:
  34. ----
  35. $ ./utils/check-package package/new-package/*
  36. ----
  37. If you have the +utils+ directory in your path you can also run:
  38. ----
  39. $ cd package/new-package/
  40. $ check-package *
  41. ----
  42. The tool can also be used for packages in a br2-external:
  43. ----
  44. $ check-package -b /path/to/br2-ext-tree/package/my-package/*
  45. ----
  46. The +check-package+ script requires you install +shellcheck+ and the
  47. Python PyPi packages +flake8+ and +python-magic+. The Buildroot code
  48. base is currently tested against version 0.7.1 of ShellCheck. If you
  49. use a different version of ShellCheck, you may see additional,
  50. unfixed, warnings.
  51. If you have Docker or Podman you can run +check-package+ without
  52. installing dependencies:
  53. ----
  54. $ ./utils/docker-run ./utils/check-package
  55. ----
  56. [[testing-package]]
  57. ==== How to test your package
  58. Once you have added your new package, it is important that you test it
  59. under various conditions: does it build for all architectures? Does it
  60. build with the different C libraries? Does it need threads, NPTL? And
  61. so on...
  62. Buildroot runs http://autobuild.buildroot.org/[autobuilders] which
  63. continuously test random configurations. However, these only build the
  64. `master` branch of the git tree, and your new fancy package is not yet
  65. there.
  66. Buildroot provides a script in +utils/test-pkg+ that uses the same base
  67. configurations as used by the autobuilders so you can test your package
  68. in the same conditions.
  69. First, create a config snippet that contains all the necessary options
  70. needed to enable your package, but without any architecture or toolchain
  71. option. For example, let's create a config snippet that just enables
  72. +libcurl+, without any TLS backend:
  73. ----
  74. $ cat libcurl.config
  75. BR2_PACKAGE_LIBCURL=y
  76. ----
  77. If your package needs more configuration options, you can add them to the
  78. config snippet. For example, here's how you would test +libcurl+ with
  79. +openssl+ as a TLS backend and the +curl+ program:
  80. ----
  81. $ cat libcurl.config
  82. BR2_PACKAGE_LIBCURL=y
  83. BR2_PACKAGE_LIBCURL_CURL=y
  84. BR2_PACKAGE_OPENSSL=y
  85. ----
  86. Then run the +test-pkg+ script, by telling it what config snippet to use
  87. and what package to test:
  88. ----
  89. $ ./utils/test-pkg -c libcurl.config -p libcurl
  90. ----
  91. By default, +test-pkg+ will build your package against a subset of the
  92. toolchains used by the autobuilders, which has been selected by the
  93. Buildroot developers as being the most useful and representative
  94. subset. If you want to test all toolchains, pass the +-a+ option. Note
  95. that in any case, internal toolchains are excluded as they take too
  96. long to build.
  97. The output lists all toolchains that are tested and the corresponding
  98. result (excerpt, results are fake):
  99. ----
  100. $ ./utils/test-pkg -c libcurl.config -p libcurl
  101. armv5-ctng-linux-gnueabi [ 1/11]: OK
  102. armv7-ctng-linux-gnueabihf [ 2/11]: OK
  103. br-aarch64-glibc [ 3/11]: SKIPPED
  104. br-arcle-hs38 [ 4/11]: SKIPPED
  105. br-arm-basic [ 5/11]: FAILED
  106. br-arm-cortex-a9-glibc [ 6/11]: OK
  107. br-arm-cortex-a9-musl [ 7/11]: FAILED
  108. br-arm-cortex-m4-full [ 8/11]: OK
  109. br-arm-full [ 9/11]: OK
  110. br-arm-full-nothread [10/11]: FAILED
  111. br-arm-full-static [11/11]: OK
  112. 11 builds, 2 skipped, 2 build failed, 1 legal-info failed
  113. ----
  114. The results mean:
  115. * `OK`: the build was successful.
  116. * `SKIPPED`: one or more configuration options listed in the config
  117. snippet were not present in the final configuration. This is due to
  118. options having dependencies not satisfied by the toolchain, such as
  119. for example a package that +depends on BR2_USE_MMU+ with a noMMU
  120. toolchain. The missing options are reported in +missing.config+ in
  121. the output build directory (+~/br-test-pkg/TOOLCHAIN_NAME/+ by
  122. default).
  123. * `FAILED`: the build failed. Inspect the +logfile+ file in the output
  124. build directory to see what went wrong:
  125. ** the actual build failed,
  126. ** the legal-info failed,
  127. ** one of the preliminary steps (downloading the config file, applying
  128. the configuration, running `dirclean` for the package) failed.
  129. When there are failures, you can just re-run the script with the same
  130. options (after you fixed your package); the script will attempt to
  131. re-build the package specified with +-p+ for all toolchains, without
  132. the need to re-build all the dependencies of that package.
  133. The +test-pkg+ script accepts a few options, for which you can get some
  134. help by running:
  135. ----
  136. $ ./utils/test-pkg -h
  137. ----
  138. [[github-download-url]]
  139. ==== How to add a package from GitHub
  140. Packages on GitHub often don't have a download area with release tarballs.
  141. However, it is possible to download tarballs directly from the repository
  142. on GitHub. As GitHub is known to have changed download mechanisms in the
  143. past, the 'github' helper function should be used as shown below.
  144. ----
  145. # Use a tag or a full commit ID
  146. FOO_VERSION = 1.0
  147. FOO_SITE = $(call github,<user>,<package>,v$(FOO_VERSION))
  148. ----
  149. .Notes
  150. - The FOO_VERSION can either be a tag or a commit ID.
  151. - The tarball name generated by github matches the default one from
  152. Buildroot (e.g.: +foo-f6fb6654af62045239caed5950bc6c7971965e60.tar.gz+),
  153. so it is not necessary to specify it in the +.mk+ file.
  154. - When using a commit ID as version, you should use the full 40 hex characters.
  155. - When the tag contains a prefix such as +v+ in +v1.0+, then the
  156. +VERSION+ variable should contain just +1.0+, and the +v+ should be
  157. added directly in the +SITE+ variable, as illustrated above. This
  158. ensures that the +VERSION+ variable value can be used to match
  159. against http://www.release-monitoring.org/[release-monitoring.org]
  160. results.
  161. If the package you wish to add does have a release section on GitHub, the
  162. maintainer may have uploaded a release tarball, or the release may just point
  163. to the automatically generated tarball from the git tag. If there is a
  164. release tarball uploaded by the maintainer, we prefer to use that since it
  165. may be slightly different (e.g. it contains a configure script so we don't
  166. need to do AUTORECONF).
  167. You can see on the release page if it's an uploaded tarball or a git tag:
  168. image::github_hash_mongrel2.png[]
  169. - If it looks like the image above then it was uploaded by the
  170. maintainer and you should use that link (in that example:
  171. 'mongrel2-v1.9.2.tar.bz2') to specify +FOO_SITE+, and not use the
  172. 'github' helper.
  173. - On the other hand, if there's is *only* the "Source code" link, then
  174. it's an automatically generated tarball and you should use the
  175. 'github' helper function.
  176. [[gitlab-download-url]]
  177. ==== How to add a package from Gitlab
  178. In a similar way to the +github+ macro described in
  179. xref:github-download-url[], Buildroot also provides the +gitlab+ macro
  180. to download from Gitlab repositories. It can be used to download
  181. auto-generated tarballs produced by Gitlab, either for specific tags
  182. or commits:
  183. ----
  184. # Use a tag or a full commit ID
  185. FOO_VERSION = 1.0
  186. FOO_SITE = $(call gitlab,<user>,<package>,v$(FOO_VERSION))
  187. ----
  188. By default, it will use a +.tar.gz+ tarball, but Gitlab also provides
  189. +.tar.bz2+ tarballs, so by adding a +<pkg>_SOURCE+ variable, this
  190. +.tar.bz2+ tarball can be used:
  191. ----
  192. # Use a tag or a full commit ID
  193. FOO_VERSION = 1.0
  194. FOO_SITE = $(call gitlab,<user>,<package>,v$(FOO_VERSION))
  195. FOO_SOURCE = foo-$(FOO_VERSION).tar.bz2
  196. ----
  197. If there is a specific tarball uploaded by the upstream developers in
  198. +https://gitlab.com/<project>/releases/+, do not use this macro, but
  199. rather use directly the link to the tarball.
  200. [[accessing-private-repos]]
  201. ==== Accessing a private repository for a package
  202. If you want to create a package in a br2-external tree and its source
  203. is in a private repository (e.g. on gitlab, github, bitbucket, ...),
  204. you have to write it in a way that it is buildable both by developers
  205. and in CI. This poses a challenge, because you need to authenticate in
  206. order to access it.
  207. There are several ways you can approach this. The following two are the
  208. most practical ones.
  209. ===== Using SSH and +insteadOf+
  210. Configure your private packages to use SSH.
  211. ----
  212. FOO_SITE = git@githosting.com:/<group>/<package>.git
  213. ----
  214. Developers already have an ssh key installed so they can access it
  215. this way. The only limitation is that if they build in docker, they
  216. have to make sure the ssh key is accessible from within the container.
  217. Either mount the SSH directory into the container by passing the
  218. options +-v ~/.ssh:<homedir>/.ssh+, or load the private key into
  219. ssh-agent and pass +--mount type=bind,source=$SSH_AUTH_SOCK,target=/ssh-agent
  220. --env SSH_AUTH_SOCK=/ssh-agent+
  221. CI builders typically will not have an SSH key that allows
  222. access to other repositories. For those, you'll need to generate an
  223. access token. Then you configure git to replace the SSH access with HTTPS
  224. access. As a preparation step in CI, run the following command.
  225. ----
  226. git config --global url."https://<token>:x-oauth-basic@githosting.com/<group>/".insteadOf "git@githosting.com:/<group>/"
  227. ----
  228. The way to use a token for basic authentication differs between different
  229. git hosting providers, and sometimes between different types of tokens.
  230. Consult your provider's documentation to find out how to access git over
  231. HTTPS with a token.
  232. ===== Use HTTPS and +.netrc+
  233. If, for any reason, developers don't have an SSH key already, then it may
  234. be simpler to use HTTPS authentication. For this, every developer will
  235. have to generate a token that has (read) access to all relevant repositories.
  236. Some git hosting providers have a command-line utility that can generate
  237. such a token, otherwise you'll need to generate it in the web interface. The
  238. token has a limited lifetime so you'll need to regularly refresh it.
  239. To make sure the token is used in the Buildroot build, add it to +~/.netrc+
  240. ----
  241. machine githosting.com
  242. login <username>
  243. password <token>
  244. ----
  245. The +<username>+ and +<password>+ to use are again different for different
  246. git hosting providers.
  247. In CI, generate the +.netrc+ file as a preparation step.
  248. Configure your private packages to use HTTPS.
  249. ----
  250. FOO_SITE = https://githosting.com/<group>/<package>.git
  251. ----
  252. Both wget (https) and git will use +.netrc+ to get login information. This
  253. approach is potentially somewhat less secure because +.netrc+ cannot be
  254. password-protected. The advantage is that users and CI use the exact same
  255. way of providing credentials.