| Both sides previous revision Previous revision Next revision | Previous revision |
| docs:guide-developer:packages [2020/07/13 13:20] – [Host tools required] Added a lot more detail on host tool packaging detly | docs:guide-developer:packages [2024/05/22 20:59] (current) – fix make target for package bam |
|---|
| ====== 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 |
| 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: | Here, for example, is package/bridge/Makefile: |
| |
| <code make> | <code make> |
| 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 |
| |
| ===== 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 |
| * ''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 |
| * ''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. |
| |
| 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 [[commit>?p=openwrt/openwrt.git;a=commit;h=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: |
| </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 "fixes" to 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> |
| |
| 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 |
| |
| * 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 repair, then 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 === |
| 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''s (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 ==== |
| </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''. |
| 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> |
| |
| </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 ==== |
| 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 ==== |
| </code> | </code> |
| Examples: px5g, px5g-standalone, usbutils, debootstrap, gcc, | Examples: px5g, px5g-standalone, usbutils, debootstrap, gcc, |
| | |
| | |
| ===== BuildPackage defines ===== | ===== BuildPackage defines ===== |
| | |
| | |
| == Package/ == | == Package/ == |
| |
| * 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) == |
| 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) == |
| "$(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) == |
| 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 'install' itself. | something to the "install" argument, don't forget the "install" itself. |
| |
| == 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) == |
| == 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 installation, have 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. | 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 removal, have 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 ===== |
| |
| 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 ====== |
| | <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. | |
| |
| |
| ''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 ===== |
| |
| :!: 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 ==== |
| * [[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/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. | * [[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. |
| | |
| |
| == BUILD == | == BUILD == |
| |
| 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 `./patches` in 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 == |
| |
| ===== 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: |
| |
| </code> | </code> |
| |
| Above you can see examples for various type config parameters. | Above, you can see examples for various types of config parameters. |
| | Finally, you can check your configuration parameters in your Makefile in the following way |
| And 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_''): |
| (Note that you can reference to the parameters value with it name prefixed with CONFIG_) | |
| |
| <code make> | <code make> |
| endif | endif |
| </code> | </code> |
| | |
| | |
| ===== 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 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. |
| |
| ==== 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" |
| |
| </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. |
| | So, any built objects in your local git tree (for example, a 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 |
| 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 present, however, 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 |
| |
| 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 |
| |
| |
| ===== 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 make> | <code make> |
| define KernelPackage/loop | define KernelPackage/loop |
| </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 ''KernelPackage/xxx'' definitions in place of ''Package/xxx''. |
| |
| 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> | For example, here is ''package/madwifi/Makefile'': |
| For example, here is package/madwifi/Makefile: | |
| <code make> | <code make> |
| # | # |
| $(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's 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: |
| 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. 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. | 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> |
| </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 maintenance 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. |