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 two things:
package/Makefile
package/patches
The patches directory is optional and typically contains bug fixes or optimizations to reduce the size of the executable.
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.
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 ipkgPKG_VERSION
-The upstream version number that we're downloadingPKG_RELEASE
-The version of this package MakefilePKG_BUILD_DIR
-Where to compile the packagePKG_SOURCE
-The filename of the original sourcesPKG_SOURCE_URL
-Where to download the sources fromPKG_MD5SUM
-A checksum to validate the downloadPKG_CAT
-How to decompress the sources (zcat, bzcat, unzip)PKG_BUILD_DEPENDS
-Packages that need to be built before this package, but are not required at runtime. Uses the same syntax as DEPENDS below.
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)
.
At the bottom of the file is where the real magic happens,
"BuildPackage" is a macro setup by the earlier include statements.
BuildPackage
only takes one argument directly – the name of the
package to be built, in this case "bridge". All other information is
taken from the define blocks. This is a way of providing a level of
verbosity, it's inherently clear what the DESCRIPTION
variable in
Package/bridge
is, which wouldn't be the case if we passed this
information directly as the Nth argument to BuildPackage.
Package/
matches the argument passed to buildroot, this describes the
package the `menuconfig` and `ipkg` entries. Within `Package/` you can
define the following variables:
SECTION
- The type of package (currently unused)CATEGORY
- Which menu it appears in menuconfigTITLE
- A short description of the packageDESCRIPTION
- (deprecated) A long description of the packageURL
- Where to find the original softwareMAINTAINER
- (optional) Who to contact concerning the packageDEPENDS
- (optional) Which packages must be built/installed before this package. See below for the syntax. Package/conffiles (optional)
A list of config files installed by this package, one file per line.
Package/description
A free text description of the package
Build/Prepare
(optional)
: A set of commands to unpack and patch the sources. You may safely
leave this undefined.
Build/Configure
(optional)
: You can leave this undefined if the source doesn't use configure or
has a normal config script, otherwise you can put your own commands
here or use $(call Build/Configure/Default,)
as above to pass in
additional arguments for a standard configure script.
Build/Compile
(optional)
: How to compile the source; in most cases you should leave this
undefined.
Package/install
: A set of commands to copy files out of the compiled source and into
the ipkg
which is represented by the $(1)
directory.
Package/preinst
: The actual text of the script which is to be executed before
installation. Dont forget to include the #!/bin/sh
. If you need to
abort installation have the script return false.
Package/postinst
: The actual text of the script which is to be executed after
installation. Dont forget to include the #!/bin/sh.
Package/prerm
: The actual text of the script which is to be executed before
removal. Dont forget to include the #!/bin/sh
. If you need to abort
removal have the script return false.
Package/postrm
: The actual text of the script which is to be executed after removal.
Dont 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 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.
Various types of dependencies can be specified, which require a bit of explanation for their differences.
+<foo> Package will depend on package <foo> and will select it when
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:<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 @.
@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.
Some typical config symbols for (conditional) dependencies are:
TARGET_<foo> Target <foo> is selected
TARGET_<foo>_<bar> If the target <foo> has subtargets, subtarget
<foo> is selected. If not, profile <foo> is selected. This is in
addition to TARGET_<foo>
TARGET_<foo>_<bar>_<baz> Target <foo> with subtarget <bar> and
profile <baz> is selected.
LINUX_3_X Linux version used is 3.x.*
LINUX_2_6_X Linux version used is 2.6.x.* (:1: only used for backfire
and earlier)
LINUX_2_4 Linux version is 2.4 ( only used in backfire and earlier,
and only for target brcm-2.4)
USE_UCLIBC, USE_GLIBC, USE_EGLIBC To (not) depend on a certain libc.
BROKEN Package doesn't build or work, and should only be visible if
"Show broken targets/packages" is selected. Prevents the package from
failing builds by accidentally selecting it.
IPV6 IPv6 support in packages is selected.
All variables in your pre/post install/removal scripts should have
double ($$
) instead of a single ($
) string characters. This will
inform make
to not interpret the value as a variable, but rather
just ignore the string and replace the double $$
by a single $
.
After you've created your package Makefile
, the new package will
automatically show in the menu the next time you run make menuconfig
and if selected will be built automatically the next time make
is
run.
DESCRIPTION
is obsolete, use Package/PKG_NAME/description
.