Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
docs:guide-developer:packages [2020/03/05 00:46] – [Building in a subdirectory of the source] adamkpickeringdocs:guide-developer:packages [2024/05/22 20:59] (current) – fix make target for package bam
Line 1: Line 1:
 ====== Creating packages ====== ====== Creating packages ======
  
-**See also -> [[package-policies|Package Policy Guide]]**, it contains a wealth of extra technical information not covered here.+**See also -> [[package-policies|Package Policy Guide]]**, which contains a wealth of extra technical information not covered here.
  
 One of the things that we've attempted to do with OpenWrt's template system is make it incredibly easy to port software to OpenWrt. If you look at a typical package directory in OpenWrt you'll find three things: One of the things that we've attempted to do with OpenWrt's template system is make it incredibly easy to port software to OpenWrt. If you look at a typical package directory in OpenWrt you'll find three things:
- 
  
   * package/Makefile   * package/Makefile
Line 13: Line 12:
 The files directory is optional. It typically includes default config or init files. The files directory is optional. It typically includes default config or init files.
  
-The package makefile is the important item because it provides the steps actually needed to download and compile the package. +The package ''Makefile'' is the important item because it provides the steps actually needed to download and compile the package. 
  
-Looking at one of the package makefiles, you'd hardly recognize it as a makefile. Through what can only be described as blatant disregard and abuse of the traditional make format, the makefile has been transformed into an object oriented template which simplifies the entire ordeal.+Looking at one of the package makefiles, you'd hardly recognize it as a makefile. Through what can only be described as blatant disregard and abuse of the traditional make format, the ''Makefile'' has been transformed into an object oriented template which simplifies the entire ordeal.
  
-Here for example, is package/bridge/Makefile:+Herefor example, is package/bridge/Makefile:
  
-<code>+<code make>
 include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
  
Line 30: Line 29:
 PKG_SOURCE_URL:=@SF/bridge PKG_SOURCE_URL:=@SF/bridge
 PKG_HASH:=9b7dc52656f5cbec846a7ba3299f73bd PKG_HASH:=9b7dc52656f5cbec846a7ba3299f73bd
-PKG_CAT:=zcat 
  
 include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/package.mk
Line 62: Line 60:
  
 ===== BuildPackage variables ===== ===== BuildPackage variables =====
 +
 As you can see, there's not much work to be done; everything is hidden in other makefiles and abstracted to the point where you only need to specify a few variables. As you can see, there's not much work to be done; everything is hidden in other makefiles and abstracted to the point where you only need to specify a few variables.
  
-  * ''PKG_NAME''        - The name of the package, as seen via menuconfig and ipkg. Avoid using underscores in the package name, to avoid build failures--for example, the underscore separates name from version information, and  may confuse the buildsystem in hard-to-spot places.+  * ''PKG_NAME''        - The name of the package, as seen via menuconfig and ipkg. Avoid using underscores in the package name, to avoid build failures--for example, the underscore separates name from version information, and may confuse the build system in hard-to-spot places.
   * ''PKG_VERSION''     - The upstream version number that we're downloading   * ''PKG_VERSION''     - The upstream version number that we're downloading
-  * ''PKG_RELEASE''     - The version of this package Makefile+  * ''PKG_RELEASE''     - The version of this package Makefile.  Should be initially set to 1, and reset to 1 whenever the ''PKG_VERSION'' is changed.  Increment it when ''PKG_VERSION'' stays the same, but when there are functional changes to the installed artifacts.
   * ''PKG_LICENSE''     - The license(s) the package is available under, [[https://spdx.org/licenses/|SPDX]] form.   * ''PKG_LICENSE''     - The license(s) the package is available under, [[https://spdx.org/licenses/|SPDX]] form.
   * ''PKG_LICENSE_FILES''- file containing the license text   * ''PKG_LICENSE_FILES''- file containing the license text
Line 72: Line 71:
   * ''PKG_SOURCE''      - The filename of the original sources   * ''PKG_SOURCE''      - The filename of the original sources
   * ''PKG_SOURCE_URL''  - Where to download the sources from (directory)   * ''PKG_SOURCE_URL''  - Where to download the sources from (directory)
-  * ''PKG_HASH''      - A checksum to validate the download.  It can be either a MD5 or SHA256 checksum, but SHA256 should be used, see [[https://git.lede-project.org/?p=source.git;a=blob;f=scripts/download.pl;h=90d50a88622f26f554344f20b07f9da7ba649e74;hb=HEAD#l63|scripts/download.pl]]+  * ''PKG_HASH''      - A checksum to validate the download.  It can be either a MD5 or SHA256 checksum, but SHA256 should be used, see [[commit>?p=openwrt/openwrt.git;a=blob;f=scripts/download.pl;h=676c6e9e6b10b6a44ed2bbc03a7ba3c983aaf639;hb=HEAD#l66|scripts/download.pl]]
   * ''PKG_CAT''         - How to decompress the sources (zcat, bzcat, unzip)   * ''PKG_CAT''         - How to decompress the sources (zcat, bzcat, unzip)
 +  * ''PKG_URL''       - Upstream project homepage
   * ''PKG_BUILD_DEPENDS'' - Packages that need to be built before this package. Use this option if you need to make sure that your package has access to includes and/or libraries of another package at build time. Specify the directory name (i.e. openssl) rather than the binary package name (i.e. libopenssl). This build variable only establishes the build time dependency. Use ''DEPENDS'' to establish the runtime dependencies. This variable uses the same syntax as ''DEPENDS'' below.   * ''PKG_BUILD_DEPENDS'' - Packages that need to be built before this package. Use this option if you need to make sure that your package has access to includes and/or libraries of another package at build time. Specify the directory name (i.e. openssl) rather than the binary package name (i.e. libopenssl). This build variable only establishes the build time dependency. Use ''DEPENDS'' to establish the runtime dependencies. This variable uses the same syntax as ''DEPENDS'' below.
   * ''PKG_CONFIG_DEPENDS'' - specifies which config options influence the build configuration and should trigger a rerun of Build/Configure on change   * ''PKG_CONFIG_DEPENDS'' - specifies which config options influence the build configuration and should trigger a rerun of Build/Configure on change
Line 79: Line 79:
   * ''PKG_INSTALL_DIR'' - Where "make install" copies the compiled files   * ''PKG_INSTALL_DIR'' - Where "make install" copies the compiled files
   * ''PKG_FIXUP''       - See below   * ''PKG_FIXUP''       - See below
 +  * ''PKG_CVE_IGNORE''  - Variable for defining CVEs that don't apply to this version of the package due to features not enabled, or affecting other platforms (e.g. Windows issues or features that are not used and so not relevant)
 +  * ''PKG_CVE_FIXED''   - Variable for defining CVEs that are patches in the current version, but aren't properly marked as fixed at cve.org in the current version
  
 Optional support for fetching sources from a VCS (git, bzr, svn, etc), see [[#use_source_repository|Use source repository]] below for more information: Optional support for fetching sources from a VCS (git, bzr, svn, etc), see [[#use_source_repository|Use source repository]] below for more information:
  
   * ''PKG_SOURCE_PROTO'' - the protocol to use for fetching the sources (git, svn, etc).   * ''PKG_SOURCE_PROTO'' - the protocol to use for fetching the sources (git, svn, etc).
-  * ''PKG_SOURCE_URL''  - source repository to fetch from.  The URL scheme must be consistent with ''PKG_SOURCE_PROTO'' (e.g. ''git:%%//%%''), but most VCS accept ''http:%%//%%'' or ''https:%%//%%'' URL nowadays.+  * ''PKG_SOURCE_URL''  - source repository to fetch from.  The URL scheme must be consistent with ''PKG_SOURCE_PROTO'' (e.g. ''git:%%//%%''), but most VCS accept ''http:%%//%%'' or ''https:%%//%%'' URLs nowadays.
   * ''PKG_SOURCE_VERSION'' - must be specified, the commit hash or SVN revision to check out.   * ''PKG_SOURCE_VERSION'' - must be specified, the commit hash or SVN revision to check out.
   * ''PKG_SOURCE_DATE'' - a date like ''2017-12-25'', will be used in the name of generated tarballs.   * ''PKG_SOURCE_DATE'' - a date like ''2017-12-25'', will be used in the name of generated tarballs.
   * ''PKG_MIRROR_HASH'' - SHA256 checksum of the tarball generated from the source repository checkout (previously named ''PKG_MIRROR_MD5SUM'').  See [[#use_source_repository|below]] for details.   * ''PKG_MIRROR_HASH'' - SHA256 checksum of the tarball generated from the source repository checkout (previously named ''PKG_MIRROR_MD5SUM'').  See [[#use_source_repository|below]] for details.
-  * ''PKG_SOURCE_SUBDIR'' - where should the temporary source checkout should be stored, defaults to ''$(PKG_NAME)-$(PKG_VERSION)'' +  * ''PKG_SOURCE_SUBDIR'' - where the temporary source checkout should be stored, defaults to ''$(PKG_NAME)-$(PKG_VERSION)''
  
 The ''PKG_*'' variables define where to download the package from; @SF is a special keyword for downloading packages from sourceforge. The md5sum is used to verify the package was downloaded correctly and PKG_BUILD_DIR defines where to find the package after the sources are uncompressed into $(BUILD_DIR). PKG_INSTALL_DIR defines where the files will be copied after calling "make install" (set with the PKG_INSTALL variable), and after that you can package them in the install section. The ''PKG_*'' variables define where to download the package from; @SF is a special keyword for downloading packages from sourceforge. The md5sum is used to verify the package was downloaded correctly and PKG_BUILD_DIR defines where to find the package after the sources are uncompressed into $(BUILD_DIR). PKG_INSTALL_DIR defines where the files will be copied after calling "make install" (set with the PKG_INSTALL variable), and after that you can package them in the install section.
Line 95: Line 96:
  
 Avoid reuse of PKG_NAME in call, define and eval lines for consistency and readability. Write the full name instead. Avoid reuse of PKG_NAME in call, define and eval lines for consistency and readability. Write the full name instead.
 +
  
 ===== Testing a package Makefile ===== ===== Testing a package Makefile =====
  
-LEDE recently [[https://git.lede-project.org/7a315b0b5d6aa91695853a8647383876e4b49a7a|introduced support]] for a range of sanity checks like mismatched checksums.+There is [[commit>?p=openwrt/openwrt.git;a=commit;h=7a315b0b5d6aa91695853a8647383876e4b49a7a|support for a range of sanity checks]] like mismatched checksums.
  
 To check your package: To check your package:
Line 113: Line 115:
 </code> </code>
  
-Note: despite the similar name, this has nothing to do with the ''PKG_FIXUP'' variable presented below...+Note: despite the similar name, this has nothing to do with the ''PKG_FIXUP'' variable presented below. 
  
 ===== PKG_FIXUP ===== ===== PKG_FIXUP =====
  
-Some/many packages that think autotools is a good idea end up needing "fixesto work around autotools "accidentally" knowing better and using host tools instead of the build environment tools. OpenWrt defines some PKG_FIXUP rules to help work around this.+Some packages that use autotools end up needing fixes to work around autotools using host tools instead of the build environment tools. OpenWrt defines some PKG_FIXUP rules to help work around this.
  
 <code make> <code make>
Line 126: Line 129:
  
 Any variations of this you see in the wild are simply aliases for these. Any variations of this you see in the wild are simply aliases for these.
 +
  
 == autoreconf == == autoreconf ==
 +
 This fixup performs This fixup performs
  
Line 134: Line 139:
   * ensures that openwrt-libtool is linked   * ensures that openwrt-libtool is linked
   * suppresses autopoint/gettext   * suppresses autopoint/gettext
 +
  
 == patch-libtool == == patch-libtool ==
-If the shipped automake recipes are broken beyound repair then simply find instances of libtool, detect their version and apply openwrt fix patches to it+ 
 +If the shipped automake recipes are broken beyond repairthen simply find instances of libtool, detect their version and apply OpenWrt fix patches to it
  
 == gettext-version == == gettext-version ==
-This fixup suppress version mismatch errors in automake's gettext support+ 
 +This fixup suppresses version mismatch errors in automake's gettext support
  
 === Tips === === Tips ===
Line 145: Line 155:
 Packages that are using Autotools should work with simply "PKG_FIXUP:=autoreconf". However there might be issues with required versions. Packages that are using Autotools should work with simply "PKG_FIXUP:=autoreconf". However there might be issues with required versions.
  
-:!: Instead of patching ./configure one should fix the file from which ./configure is generated in autotools: configure.ac (or configure.in, for very old packages). Another important file is Makefile.am from which Makefiles (with configure output) are generated.+:!: Instead of patching ''./configure'', one should fix the file from which ''./configure'' is generated in autotools: ''configure.ac'' (or ''configure.in'', for very old packages). Another important file is ''Makefile.am'' from which ''Makefile''(with ''configure'' output) are generated. 
  
 ===== Package Sourcecode ===== ===== Package Sourcecode =====
  
 OpenWrt Buildroot supports many different ways to download external source code. OpenWrt Buildroot supports many different ways to download external source code.
 +
  
 ==== Use packed source code archive ==== ==== Use packed source code archive ====
 Most packages use a packed .tar.gz, .tar.bz2, .tar.xz or similar source code file. Most packages use a packed .tar.gz, .tar.bz2, .tar.xz or similar source code file.
 +
  
 ==== Use source repository ==== ==== Use source repository ====
Line 166: Line 179:
 </code> </code>
  
-Besides the source repository ''PKG_SOURCE_URL'', you also need to specify which exact version you are building using ''PKG_SOURCE_VERSION'' (e.g. a commit hash for git, or a revision number for svn)+Besides the source repository ''PKG_SOURCE_URL'', you also need to specify which exact version you are building using ''PKG_SOURCE_VERSION'' e.g. a commit hash for git, or a revision number for svn. The ''PKG_SOURCE_VERSION'' can be a git tag and specified like ''PKG_SOURCE_VERSION:=v$(PKG_VERSION)''.
  
 Buildroot will first clone the source repository, and then generate a tarball from the source repository, with a name like ''dl/odhcpd-2017-08-16-94e65ee0.tar.xz''. Buildroot will first clone the source repository, and then generate a tarball from the source repository, with a name like ''dl/odhcpd-2017-08-16-94e65ee0.tar.xz''.
Line 172: Line 185:
 You should also define ''PKG_MIRROR_HASH'' with the SHA256 checksum of this generated tarball. This way, users building OpenWrt will directly download the generated tarball from a buildbot and verify its checksum, thus avoiding a clone of the source repository. You should also define ''PKG_MIRROR_HASH'' with the SHA256 checksum of this generated tarball. This way, users building OpenWrt will directly download the generated tarball from a buildbot and verify its checksum, thus avoiding a clone of the source repository.
  
-:!: the tarballs generated from svn checkouts are not reproducible, so you should avoid defining ''PKG_MIRROR_HASH'' when building from svn!+:!: The tarballs generated from svn checkouts are not reproducible, so you should avoid defining ''PKG_MIRROR_HASH'' when building from svn!
  
-To generate ''PKG_MIRROR_HASH'' automatically, use the following (replace ''package/network/services/odhcpd'' by your package):+To generate ''PKG_MIRROR_HASH'' automatically, use the following (replace ''package/odhcpd'' by your package):
  
 <code> <code>
-# First add "PKG_MIRROR_HASH:=skip" to the package Makefile and/or "HASH:=skip" if required +# First add "PKG_MIRROR_HASH:=skip" to the package Makefile and/or "HASH:=skip"if required. 
-make package/network/services/odhcpd/download V=s +make package/odhcpd/download V=s 
-make package/network/services/odhcpd/check FIXUP=1 V=s+make package/odhcpd/check FIXUP=1 V=s
 </code> </code>
  
Line 192: Line 205:
 </code> </code>
  
-History: ''PKG_MIRROR_MD5SUM'' was [[https://git.lede-project.org/b568a64f8c1f7c077c83d8c189d4c84ca270aeb4|introduced in 2011]] and [[https://git.lede-project.org/7416d2e046b87b262b407f8af70b8dd9b2927c70|renamed to ''PKG_MIRROR_HASH'' in LEDE in 2016]].+History: ''PKG_MIRROR_MD5SUM'' was [[commit>?p=openwrt/openwrt.git;a=commitdiff;h=b568a64f8c1f7c077c83d8c189d4c84ca270aeb4|introduced in 2011]] and [[commit>?p=openwrt/openwrt.git;a=commitdiff;h=7416d2e046b87b262b407f8af70b8dd9b2927c70|renamed to ''PKG_MIRROR_HASH'' in 2016]]. 
  
 ==== Bundle source code with OpenWrt Makefile ==== ==== Bundle source code with OpenWrt Makefile ====
Line 198: Line 212:
 It is also possible to have the source code in the package/<packagename> directory. Often a ./src/ subdirectory is used. It is also possible to have the source code in the package/<packagename> directory. Often a ./src/ subdirectory is used.
   Examples: px5g , px5g-standalone   Examples: px5g , px5g-standalone
 +
  
 ==== Download override ==== ==== Download override ====
Line 204: Line 219:
  
 You can download additional data from external sources. You can download additional data from external sources.
-<code>+<code make>
 USB_IDS_VER:=0.321 USB_IDS_VER:=0.321
 USB_IDS_FILE:=usb.ids.$(USB_IDS_VER) USB_IDS_FILE:=usb.ids.$(USB_IDS_VER)
Line 217: Line 232:
  
 and unpack it or integrate it into the build process and unpack it or integrate it into the build process
-<code>+<code make>
 define Build/Prepare define Build/Prepare
         $(Build/Prepare/Default)         $(Build/Prepare/Default)
Line 237: Line 252:
 </code> </code>
   Examples: px5g, px5g-standalone, usbutils, debootstrap, gcc,    Examples: px5g, px5g-standalone, usbutils, debootstrap, gcc, 
 +
 +
 ===== BuildPackage defines ===== ===== BuildPackage defines =====
 +
 +
 == Package/ == == Package/ ==
  
Line 252: Line 271:
   *  DEPENDS     - (optional) Which packages must be built/installed before this package. See [[#dependency_types|below]] for the syntax   *  DEPENDS     - (optional) Which packages must be built/installed before this package. See [[#dependency_types|below]] for the syntax
   *  EXTRA_DEPENDS - (optional) Runtime dependencies, don't get built, only added to package ''control'' file   *  EXTRA_DEPENDS - (optional) Runtime dependencies, don't get built, only added to package ''control'' file
 +  *  PROVIDES    - (optional) allow to define a virtual package that might be provided by multiple real-packages
   *  PKGARCH     - (optional) Set this to "all" to produce a package with "Architecture: all" (See below)   *  PKGARCH     - (optional) Set this to "all" to produce a package with "Architecture: all" (See below)
   *  USERID      - (optional) a username:groupname pair to create at package installation time.   *  USERID      - (optional) a username:groupname pair to create at package installation time.
 +
  
 == PKGARCH (optional) == == PKGARCH (optional) ==
-By default, packages are built for the target architecture, and the ipk files generated are tagged that way.  This is normally correct, for any compiled code, but if a package only contains scripts or resources, marking it with PKGARCH:=all will make a single ipk file that can be installed on any target architecture.  (It will still be compiled into bin/packages/arch/ however)+By default, packages are built for the target architecture, and the ipk files generated are tagged that way.  This is normally correct, for any compiled code, but if a package only contains scripts or resources, marking it with PKGARCH:=all will make a single ipk file that can be installed on any target architecture.  (It will still be compiled into ''bin/packages/arch/'', however.)
  
  
 == Package/conffiles (optional) == == Package/conffiles (optional) ==
  
-A list of config files installed by this package, one file per line.+A list of config files installed by this package, one file per line.  
 +The file list section should not be indented: no leading tabs or spaces in the section. 
  
 == Package/description == == Package/description ==
  
 A free text description of the package A free text description of the package
 +
  
 == Build/Prepare (optional) == == Build/Prepare (optional) ==
Line 271: Line 295:
 A set of commands to unpack and patch the sources. You may safely leave this A set of commands to unpack and patch the sources. You may safely leave this
 undefined. undefined.
 +
  
 == Build/Configure (optional) == == Build/Configure (optional) ==
Line 278: Line 303:
 "$(call Build/Configure/Default,)" as above to pass in additional "$(call Build/Configure/Default,)" as above to pass in additional
 arguments for a standard configure script. arguments for a standard configure script.
 +
  
 == Build/Compile (optional) == == Build/Compile (optional) ==
Line 284: Line 310:
 then the default is used, which calls make. If you want to pass special arguments then the default is used, which calls make. If you want to pass special arguments
 to make, use e.g. "$(call Build/Compile/Default,FOO=bar)" to make, use e.g. "$(call Build/Compile/Default,FOO=bar)"
 +
  
 == Build/Install (optional) == == Build/Install (optional) ==
  
-How to install the compiled source. The default is to call "make install". Again, to +How to install the compiled source. The default is to call "make install". 
-pass special arguments or targets, use "$(call Build/Install/Default,install install-foo)"+Again, to pass special arguments or targets, use "$(call Build/Install/Default,install install-foo)".
 Note that you need put all the needed make arguments here. If you just need to add Note that you need put all the needed make arguments here. If you just need to add
-something to the "install" argument, don't forget the 'installitself.+something to the "install" argument, don't forget the "installitself. 
  
 == Build/InstallDev (optional) == == Build/InstallDev (optional) ==
  
 For things needed to compile packages against it (static libs, header files), but that are of no use on the target device. For things needed to compile packages against it (static libs, header files), but that are of no use on the target device.
 +
  
 == Build/Clean (optional) == == Build/Clean (optional) ==
Line 308: Line 337:
 == Package/preinst == == Package/preinst ==
  
-The actual text of the script which is to be executed before installation. Dont forget +The actual text of the script which is to be executed before installation. 
-to include the #!/bin/sh. If you need to abort installation have the script return false.+Don't forget to include the ''#!/bin/sh''. 
 +If you need to abort installationhave the script return ''false''. 
  
 == Package/postinst == == Package/postinst ==
  
-The actual text of the script which is to be executed after installation. Dont forget +The actual text of the script which is to be executed after installation. 
-to include the #!/bin/sh. +Don't forget to include the ''#!/bin/sh''. 
 +Alternatively you can also use an [[docs:guide-developer:uci-defaults|uci-default script]] which will be executed automatically on runtime installations by opkg or embedding into an image. 
  
 == Package/prerm == == Package/prerm ==
  
-The actual text of the script which is to be executed before removal. Dont forget +The actual text of the script which is to be executed before removal. 
-to include the #!/bin/sh. If you need to abort removal have the script return false.+Don't forget to include the ''#!/bin/sh''. 
 +If you need to abort removalhave the script return ''false''. 
  
 == Package/postrm == == Package/postrm ==
  
-The actual text of the script which is to be executed after removal. Dont forget +The actual text of the script which is to be executed after removal. 
-to include the #!/bin/sh. +Don't forget to include the ''#!/bin/sh''.
  
-The reason that some of the defines are prefixed by "Package/" and others are simply "Build" is because of the possibility of generating multiple packages from a single source. OpenWrt works under the assumption of one source per package makefile, but you can split that source into as many packages as+The reason that some of the defines are prefixed by "Package/" and others are simply "Build" is because of the possibility of generating multiple packages from a single source. OpenWrt works under the assumption of one source per package ''Makefile'', but you can split that source into as many packages as
 desired. Since you only need to compile the sources once, there's one global set of "Build" defines, but you can add as many "Package/" defines as you want by adding extra calls to BuildPackage -- see the dropbear package for an example. desired. Since you only need to compile the sources once, there's one global set of "Build" defines, but you can add as many "Package/" defines as you want by adding extra calls to BuildPackage -- see the dropbear package for an example.
 +
  
 ===== Building in a subdirectory of the source ===== ===== Building in a subdirectory of the source =====
Line 338: Line 374:
  
 This path is relative to ''PKG_BUILD_DIR'' and defaults to ''.''. Alternatively, you can override ''Build/Compile'' (see above), though this is more work. This path is relative to ''PKG_BUILD_DIR'' and defaults to ''.''. Alternatively, you can override ''Build/Compile'' (see above), though this is more work.
 +
  
 ===== Dependency Types ====== ===== Dependency Types ======
Line 346: Line 383:
 | <foo>    | Package will depend on package <foo> and  will be invisible until <foo> is selected.   | | <foo>    | Package will depend on package <foo> and  will be invisible until <foo> is selected.   |
 | @FOO | Package depends on the config symbol CONFIG_FOO and will be invisible unless CONFIG_FOO is set. This usually used for depending on certain Linux versions or targets, e.g. @TARGET_foo will make a package only available for target foo. You can also use boolean expressions for complex dependencies, e.g. @(!TARGET_foo&&!TARGET_bar) will make the package unavailable for foo and bar. | | @FOO | Package depends on the config symbol CONFIG_FOO and will be invisible unless CONFIG_FOO is set. This usually used for depending on certain Linux versions or targets, e.g. @TARGET_foo will make a package only available for target foo. You can also use boolean expressions for complex dependencies, e.g. @(!TARGET_foo&&!TARGET_bar) will make the package unavailable for foo and bar. |
-| +FOO:<bar> | Package will depend on <bar> if CONFIG_FOO is set, and will select <bar> when it is selected itself. The typical use case would be if there compile time options for this package toggling features that depend on external libraries. :!: Note that the + replaces the @. :!: There is limited support for boolean operators here compared to the @ type above.  Negation ! is only supported to negate the whole condition.  Parentheses are ignored, so use them only for readability.  Like C, && has a higher precedence than %%||%%. So +(YYY%%||%%FOO&&BAR):package will select package if CONFIG_YYY is set or if both CONFIG_FOO and CONFIG_BAR are set. |+| +FOO:<bar> | Package will depend on <bar> if CONFIG_FOO is set, and will select <bar> when it is selected itself. The typical use case would be if there are compile time options for this package toggling features that depend on external libraries. :!: Note that the + replaces the @. :!: There is limited support for boolean operators here compared to the @ type above.  Negation ! is only supported to negate the whole condition.  Parentheses are ignored, so use them only for readability.  Like C, && has a higher precedence than %%||%%. So +(YYY%%||%%FOO&&BAR):package will select package if CONFIG_YYY is set or if both CONFIG_FOO and CONFIG_BAR are set. |
 | %%@FOO:<bar>%% | Package will depend on <bar> if CONFIG_FOO is set, and will be invisible until <bar> is selected when CONFIG_FOO is set. | | %%@FOO:<bar>%% | Package will depend on <bar> if CONFIG_FOO is set, and will be invisible until <bar> is selected when CONFIG_FOO is set. |
  
Line 368: Line 405:
  
 ''EXTRA_DEPENDS'' is more often used to depend on specific versions, by adding the desired version specification in parentheses, using >=,>,<,%%<%%=,=. Make sure you add the ''PKG_RELEASE'' number if you're using '=', such as ''EXTRA_DEPENDS:=foo (=2.0.0-1)'': where foo's ''PKG_VERSION'' is 2.0.0, and ''PKG_RELEASE'' is 1. ''EXTRA_DEPENDS'' is more often used to depend on specific versions, by adding the desired version specification in parentheses, using >=,>,<,%%<%%=,=. Make sure you add the ''PKG_RELEASE'' number if you're using '=', such as ''EXTRA_DEPENDS:=foo (=2.0.0-1)'': where foo's ''PKG_VERSION'' is 2.0.0, and ''PKG_RELEASE'' is 1.
 +
  
 ===== Configure a package source ===== ===== Configure a package source =====
  
 Example: Example:
-<code>+<code make>
 CONFIGURE_ARGS += \ CONFIGURE_ARGS += \
         --disable-native-affinity \         --disable-native-affinity \
Line 389: Line 427:
  
 :!: The article [[docs:guide-developer:packages.flags]] contains more information and examples about overriding and setting these. :!: The article [[docs:guide-developer:packages.flags]] contains more information and examples about overriding and setting these.
 +
  
 ==== Host tools required ==== ==== Host tools required ====
-If your package needs some private tools built on the host, you can use the following snippet as pointer of where to look for more info+ 
 +In order to build your package, you may require some extra build tools or libraries that are not already in the standard OpenWrt toolchain. These must be built as part of the OpenWrt build process ie. you cannot rely on them being installed via the build system's package manager (or manually by the user or administrator). This is so that OpenWrt can be built reliably and repeatably on wide variety of machines. These are referred to as //host tools// because they run on (or are compiled for) the host, not the target. 
 + 
 +If your package requires host tools in order to be built for the target machine, these should go in ''PKG_BUILD_DEPENDS'' and will end with ''/host''. For example, the ''json-glib'' package requires the [[https://mesonbuild.com/|Meson build system]] to generate build files, as well as Glib2 on the host, so it has:
  
 <code make> <code make>
-HOST_BUILD_DEPENDS:=<packagename>/host +PKG_BUILD_DEPENDS:=glib2/host meson/host 
-PKG_BUILD_DEPENDS:=<packagename>/host +</code>
-include $(INCLUDE_DIR)/host-build.mk+
  
-define Host/Compile +A package might itself provide host tools, and building or using //those// might require //other// host tools to be built first. These other tools go in ''HOST_BUILD_DEPENDS''. For example, the host tool that the Meson package provides requires another build tool, [[https://ninja-build.org/|Ninja]], so it has this line:
-define Host/Install+
  
-$(eval $(call HostBuild))+<code make> 
 +HOST_BUILD_DEPENDS:=ninja/host
 </code> </code>
  
-FIXME TODO Expand on how to use this, and include examples+The makefile for a package that provides host tools will: 
 + 
 +  * Include ''$(INCLUDE_DIR)/host-build.mk''. You can look at this makefile for the details of the host tool build process. 
 +  * Have sections similar to the ''Build/...''  sections of other packagesbut they will start with ''Host/''. For example, ''Host/Configure'', ''Host/Compile'' and ''Host/Install'' are common. 
 +  * Call ''$(eval $(call HostBuild))'' at the end. 
 + 
 +Some examples of packages that //provide// host tools (and their makefiles): 
 + 
 +  * [[https://github.com/openwrt/packages/blob/master/devel/meson/Makefile|Meson]] 
 +  * [[https://github.com/openwrt/packages/blob/master/net/samba4/Makefile|Samba 4]] - note that the Samba 4 //target// package actually depends on the Samba 4 //host// package provided in the same makefile 
 +  * [[https://github.com/openwrt/packages/blob/master/lang/golang/golang/Makefile|Go (golang)]] - this is a much more complex example, and useful if you're thinking of adding support for a new language in OpenWrt.
  
-Extracted from this thead on the devel mailing list: https://lists.openwrt.org/pipermail/openwrt-devel/2014-February/023970.html 
  
 == BUILD == == BUILD ==
Line 417: Line 467:
  
 The make arguments **QUILT=1** and **V=s** are also valid. The make arguments **QUILT=1** and **V=s** are also valid.
 +
  
 == PATCHES == == PATCHES ==
-If you want to patch the host and target tool separately+ 
-Then you have to add `HOST_PATCH_DIR:=./<directory>` for example `**HOST_PATCH_DIR:=./patches-host**` to the makefile, so the host tool has its own patch directory. +If you want to patch the host and target tool separately, then you have to add ''HOST_PATCH_DIR:=./<directory>''
-The target tool use still the separate patch directory  `./patchesin his package directory.+For example, add ''HOST_PATCH_DIR:=./patches-host'' to the ''Makefile'' so the host tool has its own patch directory. 
 +The target tool will still use the standard patch directory ''./patches'' in its package directory. 
  
 == NOTES == == NOTES ==
Line 433: Line 486:
  
 ===== Adding configuration options ===== ===== Adding configuration options =====
-If you would like configure your package installation/compilation in the menuconfig you can do the following:+ 
 +If you would like to configure your package installation/compilation in the menuconfig you can do the following:
 Add MENU:=1 to your package definition like this: Add MENU:=1 to your package definition like this:
  
- define Package/mjpg-streamer +<code make> 
-   SECTION:=multimedia +define Package/mjpg-streamer 
-   CATEGORY:=Multimedia +  SECTION:=multimedia 
-   TITLE:=MJPG-streamer +  CATEGORY:=Multimedia 
-   DEPENDS:=@!LINUX_2_4 +libpthread-stubs +jpeg +  TITLE:=MJPG-streamer 
-   URL:=http://mjpg-streamer.wiki.sourceforge.net/ +  DEPENDS:=@!LINUX_2_4 +libpthread-stubs +jpeg 
-   MENU:=1 +  URL:=http://mjpg-streamer.wiki.sourceforge.net/ 
- endef +  MENU:=1 
 +endef 
 +</code>
  
 Create a config key in the Makefile: Create a config key in the Makefile:
- +<code make> 
- define Package/mjpg-streamer/config +define Package/mjpg-streamer/config 
- source "$(SOURCE)/Config.in" + source "$(SOURCE)/Config.in" 
- endef +endef 
 +</code>
  
 Create a Config.in file directory where the Makefile is located with the content like this: Create a Config.in file directory where the Makefile is located with the content like this:
  
-<code>+<code make>
  # Mjpg-streamer configuration  # Mjpg-streamer configuration
  menu "Configuration"  menu "Configuration"
Line 511: Line 566:
 </code> </code>
  
-Above you can see examples for various type config parameters.+Aboveyou can see examples for various types of config parameters. 
 +Finally, you can check your configuration parameters in your Makefile in the following way 
 +(note that you can reference the parameter's value with its name prefixed with ''CONFIG_''):
  
-And finally you can check your configuration parameters in your Makefile in the following way: +<code make> 
-(Note that you can reference to the parameters value with it name prefixed with CONFIG_)+ifeq ($(CONFIG_MJPEG_STREAMER_INPUT_UVC),y) 
 +    $(CP) $(PKG_BUILD_DIR)/input_uvc.so $(1)/usr/lib 
 +endif 
 +</code>
  
- ifeq ($(CONFIG_MJPEG_STREAMER_INPUT_UVC),y) 
- $(CP) $(PKG_BUILD_DIR)/input_uvc.so $(1)/usr/lib 
- endif 
  
 ===== Working on local application source ===== ===== Working on local application source =====
-If you are still working on the application itself, at the same time as you are working on the packaging, it can be very useful to have OpenWrt build your work in progress code, rather than a specific version+md5sum combination checked out of revision control, or downloaded from your final "release" location.  There are a few ways of doing this.+ 
 +If you are still working on the applicationitself, at the same time as you are working on the packaging, it can be very useful to have OpenWrt build your work in progress code, rather than a specific version+md5sum combination checked out of revision control, or downloaded from your final "release" location.  There are a few ways of doing this. 
  
 ==== CONFIG_SRC_TREE_OVERRIDE ==== ==== CONFIG_SRC_TREE_OVERRIDE ====
 +
 This is an option in menuconfig. See "Advanced configuration options (for developers)" -> "Enable package source tree override" This is an option in menuconfig. See "Advanced configuration options (for developers)" -> "Enable package source tree override"
  
Line 532: Line 592:
 </code> </code>
  
-Benefits of this approach are that you don't need any special infrastructure in your package makefiles, they stay completely as they would be for a final build. The downside is that it only builds whatever is currently _committed_ in HEAD of your local tree.  (Not master, this could be a private testing branch, but it must be committed it can't be local changes) +Benefits of this approach are that you don't need any special infrastructure in your package makefiles, they stay completely as they would be for a final build. The downside is that it only builds whatever is currently **committed** in HEAD of your local tree. 
-This will also use a _separate_ directory for building and checking out the code.  So any built objects in your local git tree (for example, build targeting a different architecture) will be left alone, but whatever _branch_ is checked out in your tree determines where HEAD is.+(This could be a private testing branch, but everything you want to include in the package must be committed: uncommitted local changes will not be included in the build.
 +This will also use a **separate** directory for building and checking out the code. 
 +Soany built objects in your local git tree (for example, build targeting a different architecture) will be left alone, but whichever **branch** is checked out in your tree determines where HEAD is. 
  
 ==== USE_SOURCE_DIR ==== ==== USE_SOURCE_DIR ====
  
-As part of deprecating package-version-override.mk (below) a method to point directly to local source was introduced.+As part of deprecating ''package-version-override.mk'' (below)a method to point directly to local source was introduced.
 <code> <code>
 make package/awesome_app/clean V=s make package/awesome_app/clean V=s
Line 543: Line 606:
 make package/awesome_app/clean V=s make package/awesome_app/clean V=s
 </code> </code>
-(V=s is optional above)+(''V=s'' is optional above)
  
-This doesn't require any config change to enable rules, and doesn't require that you have a local git tree, and doesn't require any files to be committed. +This doesn't require any config change to enable rules, doesn't require that you have a local git tree, and doesn't require any files to be committed. 
  
-At least at present however, this has the following problems:+At least at presenthowever, this has the following problems:
   * make clean doesn't clean the source link directory, but still seems to be removing a link   * make clean doesn't clean the source link directory, but still seems to be removing a link
   * make prepare needs to be run every time   * make prepare needs to be run every time
Line 554: Line 617:
  
 See http://www.mail-archive.com/openwrt-devel@lists.openwrt.org/msg23122.html for the original discussion of this new feature See http://www.mail-archive.com/openwrt-devel@lists.openwrt.org/msg23122.html for the original discussion of this new feature
 +
 +:!: Since OpenWrt 19.07.5, ''USE_SOURCE_DIR'' only works with packages that have a valid ''PKG_MIRROR_HASH''. For packages under development, hash checking can be disabled by setting ''PKG_MIRROR_HASH=skip''. This allows using ''USE_SOURCE_DIR'' for packages pulling sources from a developer branch (e.g. having ''PKG_SOURCE_VERSION:=branchname'') without updating ''PKG_MIRROR_HASH'' every time.
  
 ==== (Deprecated) package-version-override.mk ==== ==== (Deprecated) package-version-override.mk ====
-:!: ** Don't use this anymore ** 
-Support for this style of local source building was removed in: https://dev.openwrt.org/changeset/40392.  This style required a permanent modification to your package makefile, and then entering a path via menuconfig to where the source was found.  It was fairly easy to use, and didn't care whether your local source was in git or svn or visual source safe even, but it had the major downside that the "clean" target simply didn't work.  (As it simply removed a symlink for cleaning) 
  
-If you build a current OpenWrt tree, with packages that still attempt to use this style of local building, you _will_ receive errors like so:+:!: ** Don't use this anymore! ** 
 + 
 +Support for this style of local source building was removed. This style required a permanent modification to your package makefile, and then entering a path via menuconfig to where the source was found. It was fairly easy to use, and didn't care whether your local source was in git or svn or visual source safe even, but it had the major downside that the "clean" target simply didn't work (as it simply removed a symlink for cleaning). 
 + 
 +If you build a current OpenWrt tree, with packages that still attempt to use this style of local building, you **will** receive errors like so:
 ERROR: please fix package/feeds/feed_name/application_name/Makefile - see logs/package/feeds/feed_name/application_name/dump.txt for details ERROR: please fix package/feeds/feed_name/application_name/Makefile - see logs/package/feeds/feed_name/application_name/dump.txt for details
  
Line 569: Line 636:
  
 ===== Creating packages for kernel modules ===== ===== Creating packages for kernel modules =====
-A [[http://www.digitalhermit.com/linux/Kernel-Build-HOWTO.html|kernel module]] is an installable program which extends the behavior of the linux kernel. A kernel module gets loaded after the kernel itself, (e.g. using insmod). 
  
-Many kernel programs are included in the linux source distribution; typically the kernel build may be configured to, for each program,  +A [[https://wiki.archlinux.org/title/Kernel_module|kernel module]] is an installable program which extends the behavior of the linux kernel. A kernel module gets loaded after the kernel itself, E.G. using ''insmod''
-  compile it into the kernel as a built-in,  + 
-  compile it as a loadable kernel module, or  +Many kernel programs are included in the Linux source distribution; typically the kernel build may be configured to, for each program,  
-  ignore it.+  compile it into the kernel as a built-in,  
 +  compile it as a loadable kernel module, or  
 +  ignore it.
 See //**FIX:Customizingthekerneloptions customizing the kernel options**// for including it in the kernel. See //**FIX:Customizingthekerneloptions customizing the kernel options**// for including it in the kernel.
  
-To include one of these programs as a loadable module, select the corresponding kernel option in the OpenWrt configuration (see [[docs:guide-developer:build-system:use-buildsystem#image_configuration|Build Configuration]]). If your favorite kernel module does not appear in the OpenWrt configuration menus, you must add a stanza to one of the files in the package/kernel/linux/modules directory. Here is an example extracted from .../modules/block.mk: +To include one of these programs as a loadable module, select the corresponding kernel option in the OpenWrt configuration (see [[docs:guide-developer:toolchain:use-buildsystem#image_configuration|Build Configuration]]). If your favorite kernel module does not appear in the OpenWrt configuration menus, you must add a stanza to one of the files in the package/kernel/linux/modules directory. Here is an example extracted from .../modules/block.mk: 
-<code>+<code make>
 define KernelPackage/loop define KernelPackage/loop
   SUBMENU:=$(BLOCK_MENU)   SUBMENU:=$(BLOCK_MENU)
Line 596: Line 664:
 </code> </code>
  
-Changes to the *.mk files are not automatically picked up by the build system. To force re-reading the meta data either touch the kernel package Makefile using ''touch package/kernel/linux/Makefile'' (on older revisions ''touch package/kernel/Makefile'') or to delete the ''tmp/'' directory of the buildroot.+Changes to the *.mk files are not automatically picked up by the build system. To force re-reading the metadata, either touch the kernel package Makefile using ''touch package/kernel/linux/Makefile'' (on older revisions ''touch package/kernel/Makefile'') or to delete the ''tmp/'' directory of the buildroot.
  
-You can also add kernel modules which are //not// part of the linux source distribution. In this case, a kernel module appears in the package/ directory, just as any other package does. The package/Makefile uses <code>KernelPackage/xxx</code> definitions in place of <code>Package/xxx</code> +You can also add kernel modules which are //not// part of the linux source distribution. In this case, a kernel module appears in the package/ directory, just as any other package does. The package/Makefile uses ''KernelPackage/xxx'' definitions in place of ''Package/xxx''
-For example, here is package/madwifi/Makefile: + 
-<code>+For example, here is ''package/madwifi/Makefile''
 +<code make>
 # #
 # Copyright (C) 2006 OpenWrt.org # Copyright (C) 2006 OpenWrt.org
Line 740: Line 809:
 $(eval $(call KernelPackage,madwifi)) $(eval $(call KernelPackage,madwifi))
 </code> </code>
 +----
 +=== The use of MODPARAMS ===
 +If a module require some special param to be passed on Autoload, it's available MODPARAMS using the following syntax:
 +<code>MODPARAMS.module_ko:=example_param1=example_value example_param2=example_value2</code>
  
 +For example here is ''package/kernel/cryptodev-linux/Makefile'':
 +<code make>
 +define KernelPackage/cryptodev
 + SUBMENU:=Cryptographic API modules
 + TITLE:=Driver for cryptographic acceleration
 + URL:=http://cryptodev-linux.org/
 + VERSION:=$(LINUX_VERSION)+$(PKG_VERSION)-$(BOARD)-$(PKG_RELEASE)
 + DEPENDS:=+kmod-crypto-authenc +kmod-crypto-hash
 + FILES:=$(PKG_BUILD_DIR)/cryptodev.$(LINUX_KMOD_SUFFIX)
 + AUTOLOAD:=$(call AutoLoad,50,cryptodev)
 + MODPARAMS.cryptodev:=cryptodev_verbosity=-1
 +endef
 +</code>
 +----
 +=== Make a Kernel Module required for boot ====
 +
 +Some modules may be required for the correct operation of the device. One example would be an ethernet driver required for the correct operation of the switch on the device.\\
 +
 +To flag a Kernel Module this way it's needed to append ''1'' to ''AUTOLOAD'' at the end.\\
 +
 +This cause the module file to get placed in /etc/modules-boot.d/ instead of /etc/modules.d/, modules-boot.d is processed by procd init before launching preinit and correctly works both in a normal boot and in a failsafe boot. All of this is with the assumption that the module is installed in the firmware and not with OPKG on a loaded system as **it needs to be present before /overlay is mounted**. (OPKG installed module are present only in after /overlay is mounted)
 +
 +For example here is ''phy-realtek'' in ''package/kernel/linux/modules/netdevices.mk'':
 +<code make>
 +define KernelPackage/phy-realtek
 +   SUBMENU:=$(NETWORK_DEVICES_MENU)
 +   TITLE:=Realtek Ethernet PHY driver
 +   KCONFIG:=CONFIG_REALTEK_PHY
 +   DEPENDS:=+kmod-libphy
 +   FILES:=$(LINUX_DIR)/drivers/net/phy/realtek.ko
 +   AUTOLOAD:=$(call AutoLoad,18,realtek,1)
 +endef
 +</code>
 ===== File installation macros ===== ===== File installation macros =====
  
-INSTALL_DIR, INSTALL_BIN, INSTALL_DATA are used for creating a directory, copying an executable, or a data file. +x is set on the target file for INSTALL_BIN, independent of it'mode on the host.+INSTALL_DIR, INSTALL_BIN, INSTALL_DATA are used for creating a directory, copying an executable, or copying a data file. +x is set on the target file for INSTALL_BIN, independent of its mode on the host.
  
 From the big document: From the big document:
Line 761: Line 867:
 install -m0600 install -m0600
 </code> </code>
 +
  
 ===== Packaging a service ===== ===== Packaging a service =====
  
-If you want to install a service(something that should start/stop at boot time, that has a /etc/init.d/blah script), you should make sure that the init.d script can be run on the host.  At image build time, all init.d scripts found are run on the host, looking for the START=20/STOP=99 lines. This is what installs the symlinks in /etc/rc.d.+If you want to install a service (something that should start/stop at boot time, that has a /etc/init.d/blah script), read the [[docs:techref:initscripts|Init Scripts]] section of the Technical Reference and the [[docs:guide-developer:procd-init-scripts|Procd init scripts]] section of the Developer's Guide. A key point is to make sure that the init.d script can be run on the host.  At image build time, all init.d scripts found are run on the host, looking for the START=20/STOP=99 lines. This is what installs the symlinks in /etc/rc.d.
  
 Packages have default postinst/prerm scripts that will run ''/etc/init.d/foo enable'' (creating the symlinks) or ''/etc/init.d/foo disable'' (removing the symlinks) when they are installed/removed by opkg. Packages have default postinst/prerm scripts that will run ''/etc/init.d/foo enable'' (creating the symlinks) or ''/etc/init.d/foo disable'' (removing the symlinks) when they are installed/removed by opkg.
  
-Very basic example of a suitable init.d script+Very basic example of a suitable init.d script. Please note that the newer style version does not work properly with interpreted executables (i.e. scripts). That is because start-stop-daemon is used by service_stop() in a way that it makes it confuse the script name with the interpreter name.
  
-:!: **procd** style init is used in some init.d scripts since: https://dev.openwrt.org/changeset/38023 +:!: **procd** style init is used in some init.d scripts since [[commit>?p=openwrt/openwrt.git;a=commit;h=f87409440298121ae1fbd718a17267cc180438e4|this commit]]
-See [[docs:guide-developer:procd-init-scripts]] for more details on that+See [[docs:guide-developer:procd-init-scripts]] for more details on that.
  
 <code bash> <code bash>
Line 813: Line 920:
 </code> </code>
  
-Also see [[docs:guide-developer:config-scripting|Configuration in scripts]] on how to access UCI configuration information from an init.d script, for instance to set command-line parameters or to generate a config file for your service.+See [[docs:guide-developer:config-scripting|Configuration in scripts]] for details on how to access UCI configuration information from an init.d script, for instance to set command-line parameters or to generate a config file for your service. 
 + 
 ===== How To Submit Patches to OpenWrt ===== ===== How To Submit Patches to OpenWrt =====
-Packages are maintained in a separate repository to reduce maintennance overhead.  The general guidelines for OpenWrt still apply, but see the README in the packages repository for latest information.+ 
 +Packages are maintained in a separate repository to reduce maintenance overhead.  The general guidelines for OpenWrt still apply, but see the README in the packages repository for latest information.
  
   * https://github.com/openwrt/packages   * https://github.com/openwrt/packages
-  * https://dev.openwrt.org/wiki/SubmittingPatches+  * [[:submitting-patches|https://dev.openwrt.org/wiki/SubmittingPatches]]
  
-See https://lists.openwrt.org/pipermail/openwrt-devel/2014-June/025810.html for the original announcement of this change+See [[https://web.archive.org/web/20170629071358/https://lists.openwrt.org/pipermail/openwrt-devel/2014-June/025810.html|the original announcement]] of this change.
  • Last modified: 2020/03/05 00:46
  • by adamkpickering