Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| docs:guide-developer:package-policies [2019/01/19 23:08] – section on dynamic library packages jow | docs:guide-developer:package-policies [2021/10/15 08:32] (current) – ↷ Links adapted because of a move operation bobafetthotmail | ||
|---|---|---|---|
| Line 3: | Line 3: | ||
| The OpenWrt system is maintained and distributed as a collection of // | The OpenWrt system is maintained and distributed as a collection of // | ||
| - | Allmost | + | Almost |
| - | provided by such a package with notable exception being the Linux kernel itself. | + | provided by such a package with a notable exception being the Linux kernel itself. |
| - | The term //OpenWrt package// may either refer to an OpenWrt //source package// which | + | The term //OpenWrt package// may either refer to one of two things: |
| - | essentially is a directory consisting | + | |
| - | describing the acquisition, | + | |
| - | an optional supplemental directory with //OpenWrt package patches// which modify the | + | |
| - | acquired source code and optionally further, static supplemental files shipped along | + | |
| - | with the package, such as init script files, default configurations, | + | |
| - | support files. | + | |
| - | Furthermore, | ||
| - | which is a GNU tar compatible archive containing binary executable software artifacts | ||
| - | along with accompanying //package control files// for installation on a running system, | ||
| - | similar to Debian '' | ||
| - | SuSE etc. | ||
| - | OpenWrt //binary package// are almost exclusively produced from //source packages// | + | * an OpenWrt //source package// which essentially is a directory consisting of: |
| + | * an //OpenWrt package Makefile// describing the acquisition, | ||
| + | * a supplemental directory with //OpenWrt package patches// which modify the acquired source code (optional) | ||
| + | * other static files that go with the package, such as init script files, default configurations, | ||
| + | |||
| + | * an OpenWrt //binary package//, which is a GNU tar compatible archive containing binary executable software artifacts and the accompanying //package control files// for installation on a running system, similar to the '' | ||
| + | |||
| + | OpenWrt //binary packages// are almost exclusively produced from //source packages// | ||
| by invoking either the //OpenWrt buildroot// or the //OpenWrt SDK// in order to translate | by invoking either the //OpenWrt buildroot// or the //OpenWrt SDK// in order to translate | ||
| the source package Makefile descriptions into executable binary artifacts tailored for | the source package Makefile descriptions into executable binary artifacts tailored for | ||
| a given target system. | a given target system. | ||
| - | Allthough | + | Although |
| //tar// and placing the appropriate control files in the correct directories, | //tar// and placing the appropriate control files in the correct directories, | ||
| strongly discouraged to do so since such binary packages are usually not easily | strongly discouraged to do so since such binary packages are usually not easily | ||
| - | reproducable | + | reproducible |
| Source packages are developed in multiple OpenWrt //package feeds// hosted in different | Source packages are developed in multiple OpenWrt //package feeds// hosted in different | ||
| Line 59: | Line 55: | ||
| as OpenWrt specific package Makefile. | as OpenWrt specific package Makefile. | ||
| - | See [[https:// | + | See [[docs:guide-developer:packages|Creating packages]] for details |
| on Makefile contents. | on Makefile contents. | ||
| Line 82: | Line 78: | ||
| Patch files must be in //unified diff// format and carry the extension '' | Patch files must be in //unified diff// format and carry the extension '' | ||
| The file names must also carry a numerical prefix to denote the order in which the patch | The file names must also carry a numerical prefix to denote the order in which the patch | ||
| - | files must be applied. Patch file names should be short and concise and avoid special | + | files must be applied. |
| - | characters such as white spaces, special | + | Patch file names should be concise and avoid characters |
| Suitable patch file names could look like: | Suitable patch file names could look like: | ||
| Line 91: | Line 87: | ||
| * '' | * '' | ||
| - | It is adviced | + | It is recommended |
| === The src directory === | === The src directory === | ||
| Line 105: | Line 101: | ||
| directory verbatim to the compilation scratch directory (//build directory// | directory verbatim to the compilation scratch directory (//build directory// | ||
| retaining the structure and naming of the files. | retaining the structure and naming of the files. | ||
| + | |||
| + | ==== Feature Considerations ==== | ||
| + | |||
| + | Many OpenWrt supported devices still have only a few megabytes of flash and RAM available which makes it important to shrink the packages as much as possible. Opt for the lowest common denominator whenever possible. | ||
| + | |||
| + | Some general considerations when packaging a new piece of software are: | ||
| + | |||
| + | * Do not ship man pages or documentation, | ||
| + | * Minimize external dependencies - try to avoid optional external dependencies whenever possible. An extreme example is '' | ||
| + | * Modularize packages - if the software you're packaging supports and uses plugins then put those plugins into separate binary package declarations instead of lumping them all together along with the main program. This way you can externalize dependencies and move them into the plugin packages instead of having them in the main component, which makes the package usable on a wider range of targets because users can omit parts with large dependencies. | ||
| + | * Try to rely on standard facilities - instead of requiring extra programs to implement tasks like user context switching, use the '' | ||
| + | |||
| + | Often it is tempting to add various '' | ||
| + | |||
| + | Binary packages in the official OpenWrt repositories are always built with the default settings of a package so a maintainer should ensure that the default feature selection represents a fair balance between resource requirements and most common user needs. | ||
| + | |||
| + | ==== Copyright statements ==== | ||
| + | |||
| + | Historically, | ||
| + | |||
| + | # Copyright (C) 2007-2010 OpenWrt.org | ||
| + | This is free software, licensed under the GNU General Public License v2. | ||
| + | See /LICENSE for more information. | ||
| + | |||
| + | Since contributors likely do not have a formal contract with OpenWrt to develop packages, they cannot disclaim their own copyrights and assign them to the project. | ||
| + | |||
| + | When adding new packages, please don't simply copy the statement from another package but add either your own in the form: | ||
| + | |||
| + | # Copyright (C) 2016 Joe Random < | ||
| + | |||
| + | or omit it entirely. | ||
| + | |||
| + | ==== Versioning ==== | ||
| + | |||
| + | There are a number of Makefile variables influencing the visible version of the resulting packages. When packaging upstream release tarballs, the '' | ||
| + | For example, if the '' | ||
| + | |||
| + | When there are no upstream release tarballs available or when software is packaged straight from a source code repository, the '' | ||
| + | For example, if the '' | ||
| + | |||
| + | The build system will combine these variables into a common version identifier and truncate the revision identifier if needed. Given the values in the example, the resulting version identifier will be '' | ||
| + | |||
| + | === Package Revisions === | ||
| + | |||
| + | Source packages must specify a '' | ||
| + | |||
| + | The package revision should start with the value '' | ||
| + | |||
| + | Some examples for dealing with the '' | ||
| + | * Fixed a typo in the maintainer' | ||
| + | * Added a '' | ||
| + | * Updated '' | ||
| + | |||
| + | ==== Downloading ==== | ||
| + | |||
| + | When declaring the source download method in the Makefile, direct tarball downloads via HTTP | ||
| + | or HTTPS are the preferred way to acquire package sources, Git or other SCM clones should be avoided, mainly to keep the locally cached source downloads reproducible. | ||
| + | |||
| + | If direct Git cloning is required (for example because there is no release tarballs available upstream) then Git via HTTPS is preferred over Git via HTTP is preferred over Git via its native protocol. Many OpenWrt users are behind corporate firewalls which disallow Git native traffic (TCP 9418). | ||
| + | |||
| + | === Mirror Sites === | ||
| + | |||
| + | The use of mirror sites for tarball download locations is encouraged and helps to reduce the traffic load on upstream project sites. When choosing mirrors for a package, please try to ensure that the mirror is: | ||
| + | |||
| + | * officially endorsed by the upstream project (E.G. mentioned on their download page). | ||
| + | * well reachable by people from a wide range of different locations. | ||
| + | * using proper SSL certificates when using HTTPS. | ||
| + | * hosting the most current version of the software in question. | ||
| + | |||
| + | Multiple mirrors can be specified in a package Makefile by assigning a white-space separated list of URLs to the '' | ||
| + | It is a good convention to assign the upstream project site itself to the end of the mirror list. | ||
| + | This provides a canonical fallback location in case a new version has not yet propagated to all mirrors and conveys the original download location to casual readers. | ||
| + | |||
| + | Try to limit the amount of mirror sites to 3 to 5 different locations, including the main download site. | ||
| + | |||
| + | ==== Building ==== | ||
| + | |||
| + | The build recipes in a source package should adhere to the OpenWrt defaults as much as possible. This ensures that source package declarations remain compact and free of copy-pasted boilerplate | ||
| + | code. | ||
| + | |||
| + | By default, the build system uses a set of standard '' | ||
| + | |||
| + | Please refer to [[https:// | ||
| + | |||
| + | Whenever possible, try to avoid redefining the default macros but use the provided variables to encode functional differences. | ||
| + | |||
| + | Example for a bad redefinition: | ||
| + | |||
| + | define Build/ | ||
| + | (cd $(PKG_BUILD_DIR)/ | ||
| + | endef | ||
| + | |||
| + | Example for achieving the same using variable overrides: | ||
| + | |||
| + | MAKE_PATH := nonstandard/ | ||
| + | |||
| + | Likewise, do not attempt to override '' | ||
| + | |||
| + | === Hooks === | ||
| + | |||
| + | In some cases it is possible to arrange things before e.g. the | ||
| + | '' | ||
| + | or echo values into stampfiles. In such cases, it is permissible to | ||
| + | redefine the recipe in order to achieve the desired result. Use the | ||
| + | default implementations of the macros to call the original behaviour | ||
| + | after the custom work is done. Refer to the examples below for some | ||
| + | common use cases. | ||
| + | |||
| + | == Running custom commands after unpacking but before patching the sources: == | ||
| + | |||
| + | define Build/ | ||
| + | echo " | ||
| + | $(call Build/ | ||
| + | endef | ||
| + | |||
| + | == Running custom commands after unpacking and patching the sources: == | ||
| + | |||
| + | define Build/ | ||
| + | $(call Build/ | ||
| + | rm -f $(PKG_BUILD_DIR)/ | ||
| + | cp $(PKG_BUILD_DIR)/ | ||
| + | endef | ||
| + | |||
| + | == Running custom commands before invoking configure: == | ||
| + | |||
| + | define Build/ | ||
| + | touch $(PKG_BUILD_DIR)/ | ||
| + | $(call Build/ | ||
| + | endef | ||
| + | |||
| + | == Running custom commands after executing make: == | ||
| + | |||
| + | define Build/ | ||
| + | $(call Build/ | ||
| + | cp $(PKG_BUILD_DIR)/ | ||
| + | endef | ||
| + | |||
| + | === Autotools === | ||
| + | |||
| + | Many open source projects rely on GNU autoconf and automake as their build system which may lead to a number of problems in a cross compilation setting. | ||
| + | |||
| + | Usual problems revolve around: | ||
| + | |||
| + | * '' | ||
| + | * Pregenerated '' | ||
| + | * Macros in configure scripts probing host system details to configure the package for the target, like calling '' | ||
| + | * Projects shipping convenience scripts like '' | ||
| + | |||
| + | Due to the complex nature of the GNU autoconf/ | ||
| + | |||
| + | * Never patch the generated / shipped '' | ||
| + | * Make '' | ||
| + | * Pre-seed '' | ||
| + | * Never trust shipped '' | ||
| ===== Dependencies ===== | ===== Dependencies ===== | ||
| Line 125: | Line 275: | ||
| dynamic runtime requirements. | dynamic runtime requirements. | ||
| - | //Runtime dependencies// | + | //Runtime dependencies// |
| instructing the package manager to fetch and install the listed dependencies before installing | instructing the package manager to fetch and install the listed dependencies before installing | ||
| the binary package itself. A //runtime dependency// | the binary package itself. A //runtime dependency// | ||
| Line 146: | Line 296: | ||
| changed APIs, removed functionality and so on. | changed APIs, removed functionality and so on. | ||
| - | While the package dependency mechanisms will ensure that the build system compiles | + | While the package dependency mechanisms will ensure that the build system compiles |
| packages before the program packages requiring them, they do not guarantee that such programs | packages before the program packages requiring them, they do not guarantee that such programs | ||
| are getting rebuilt when the library package itself is updated. | are getting rebuilt when the library package itself is updated. | ||
| Line 161: | Line 311: | ||
| ==== SONAME ==== | ==== SONAME ==== | ||
| - | Most upstream libraries contain an [[https:// | + | Most upstream libraries contain an [[wp>Soname|ELF SONAME]] |
| attribute denoting the canonical name of the library including a version suffix specifying | attribute denoting the canonical name of the library including a version suffix specifying | ||
| the version of the exposed ABI. Changes breaking the exposed ABI usually result in a change | the version of the exposed ABI. Changes breaking the exposed ABI usually result in a change | ||
| Line 173: | Line 323: | ||
| ==== ABI Version ==== | ==== ABI Version ==== | ||
| - | Setting an '' | + | Setting an '' |
| to track the value of this variable and trigger recompilations in all packages depending on | to track the value of this variable and trigger recompilations in all packages depending on | ||
| this library package whenever the value is incremented. This is useful to force re-linking of | this library package whenever the value is incremented. This is useful to force re-linking of | ||
| Line 190: | Line 340: | ||
| Example: when '' | Example: when '' | ||
| changed from '' | changed from '' | ||
| - | from '' | + | from '' |
| '' | '' | ||
| on '' | on '' | ||
| Line 196: | Line 346: | ||
| When a shared library is packaged, the '' | When a shared library is packaged, the '' | ||
| '' | '' | ||
| - | contained within the binary package. The '' | + | contained within the binary package. The '' |
| '' | '' | ||
| - | within the library, | + | within the library, |
| symbols. | symbols. | ||
| - | The public [[https:// | + | The public [[https:// |
| decide whether an '' | decide whether an '' | ||
| to a newer upstream version. | to a newer upstream version. | ||
| Some upstream library projects do not use a '' | Some upstream library projects do not use a '' | ||
| - | their libraries, in such cases, the '' | + | their libraries, in such cases, the '' |
| reflecting the source code change date of the last incompatible change being made. | reflecting the source code change date of the last incompatible change being made. | ||
| Line 228: | Line 378: | ||
| Versionless symlinks are usually not needed for libraries using the '' | Versionless symlinks are usually not needed for libraries using the '' | ||
| and are only used during the linking phase when compiling programs depending on the library. | and are only used during the linking phase when compiling programs depending on the library. | ||
| + | |||
| + | === NOTE === | ||
| + | |||
| + | '' | ||
| + | symlink itself, so prefer '' | ||
| + | above, if you run | ||
| + | |||
| + | $(INSTALL_BIN) $(PKG_INSTALL_DIR)/ | ||
| + | | ||
| + | it will result in two copies of the library in regular files: | ||
| + | |||
| + | libbar.so.1 | ||
| + | libbar.so.1.2.3 | ||
| + | |||
| + | Instead, use | ||
| + | |||
| + | $(CP) $(PKG_INSTALL_DIR)/ | ||
| + | | ||
| + | and you'll get the intended result: | ||
| + | libbar.so.1 | ||
| + | libbar.so.1.2.3 | ||
| + | |||
| + | While there has been a proposal to change '' | ||
| + | to work. | ||
| + | |||
| + | ==== Development Files ==== | ||
| + | |||
| + | Source packages defining binary packages that ship shared libraries should declare a '' | ||
| + | recipe that copies all resources required to discover and link the shared libraries into the staging directory. | ||
| + | |||
| + | A typical '' | ||
| + | header files and, in case they' | ||