X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/4a834421b0600e62f0110302c0d50c52be0b282e..3bf3252489e083b1a67dbdfb156db68075a8f496:/docs/build.tex?ds=sidebyside diff --git a/docs/build.tex b/docs/build.tex index fed0ca281..6828a2318 100644 --- a/docs/build.tex +++ b/docs/build.tex @@ -39,17 +39,17 @@ with the latest compilers, latest kernels and latest applications. So let's take a look at OpenWrt and see how this all works. -\subsubsection{Download openwrt} +\subsubsection{Download OpenWrt} This article refers to the "Kamikaze" branch of OpenWrt, which can be downloaded via subversion using the following command: \begin{Verbatim} -$ svn co https://svn.openwrt.org/openwrt/trunk kamikaze +$ svn checkout svn://svn.openwrt.org/openwrt/trunk kamikaze \end{Verbatim} -Additionally, ther is a trac interface on \href{https://dev.openwrt.org/}{https://dev.openwrt.org/} -which can be used to monitor svn commits and browse the sources. +Additionally, there is a trac interface on \href{https://dev.openwrt.org/}{https://dev.openwrt.org/} +which can be used to monitor svn commits and browse the source repository. \subsubsection{The directory structure} @@ -65,25 +65,25 @@ There are four key directories in the base: \texttt{tools} and \texttt{toolchain} refer to common tools which will be used to build the firmware image, the compiler, and the C library. -The result of this is three new directories, \texttt{tool\_build}, which is a temporary -directory for building the target independent tools, \texttt{toolchain\_build\_\textit{}} +The result of this is three new directories, \texttt{build\_dir/host}, which is a temporary +directory for building the target independent tools, \texttt{build\_dir/toolchain-\textit{}*} which is used for building the toolchain for a specific architecture, and -\texttt{staging\_dir\_\textit{}} where the resulting toolchain is installed. +\texttt{staging\_dir/toolchain-\textit{}*} where the resulting toolchain is installed. You will not need to do anything with the toolchain directory unless you intend to add a new version of one of the components above. \begin{itemize} - \item \texttt{tool\_build} - \item \texttt{toolchain\_build\_\textit{}} + \item \texttt{build\_dir/host} + \item \texttt{build\_dir/toolchain-\textit{}*} \end{itemize} \texttt{package} is for exactly that -- packages. In an OpenWrt firmware, almost everything is an \texttt{.ipk}, a software package which can be added to the firmware to provide new features or removed to save space. Note that packages are also maintained outside of the main -trunk and can be obtained from subversion at the following location: +trunk and can be obtained from subversion using the package feeds system: \begin{Verbatim} -$ svn co https://svn.openwrt.org/openwrt/packages ../packages +$ ./scripts/feeds update \end{Verbatim} Those packages can be used to extend the functionality of the build system and need to be @@ -91,30 +91,31 @@ symlinked into the main trunk. Once you do that, the packages will show up in th configuration. From kamikaze you would do something like this: \begin{Verbatim} -$ ls -kamikaze packages -$ ln -s packages/net/nmap kamikaze/package/nmap +$ ./scripts/feeds search nmap +Search results in feed 'packages': +nmap Network exploration and/or security auditing utility + +$ ./scripts/feeds install nmap \end{Verbatim} To include all packages, issue the following command: \begin{Verbatim} -$ ln -s packages/*/* kamikaze/package/ +$ make package/symlinks \end{Verbatim} - \texttt{target} refers to the embedded platform, this contains items which are specific to a specific embedded platform. Of particular interest here is the "\texttt{target/linux}" -directory which is broken down by platform and contains the kernel config and patches -to the kernel for a particular platform. There's also the "\texttt{target/image}" directory +directory which is broken down by platform \textit{} and contains the patches to the +kernel, profile config, for a particular platform. There's also the "\texttt{target/image}" directory which describes how to package a firmware for a specific platform. -Both the target and package steps will use the directory "\texttt{build\_\textit{}}" +Both the target and package steps will use the directory "\texttt{build\_dir/\textit{}}" as a temporary directory for compiling. Additionally, anything downloaded by the toolchain, target or package steps will be placed in the "\texttt{dl}" directory. \begin{itemize} - \item \texttt{build\_\textit{}} + \item \texttt{build\_dir/\textit{}} \item \texttt{dl} \end{itemize} @@ -143,7 +144,15 @@ Similar to the linux kernel config, almost every option has three choices, \end{itemize} After you've finished with the menu configuration, exit and when prompted, save your -configuration changes. To begin compiling the firmware, type "\texttt{make}". By default +configuration changes. + +If you want, you can also modify the kernel config for the selected target system. +simply run "\texttt{make kernel\_menuconfig}" and the build system will unpack the kernel sources +(if necessary), run menuconfig inside of the kernel tree, and then copy the kernel config +to \texttt{target/linux/\textit{}/config} so that it is preserved over +"\texttt{make clean}" calls. + +To begin compiling the firmware, type "\texttt{make}". By default OpenWrt will only display a high level overview of the compile process and not each individual command. @@ -164,7 +173,7 @@ of noise caused by the compile output. To see the full output, run the command "\texttt{make V=99}". During the build process, buildroot will download all sources to the "\texttt{dl}" -directory and will start patching and compiling them in the "\texttt{build\_\textit{}}" +directory and will start patching and compiling them in the "\texttt{build\_dir/\textit{}}" directory. When finished, the resulting firmware will be in the "\texttt{bin}" directory and packages will be in the "\texttt{bin/packages}" directory. @@ -173,12 +182,12 @@ and packages will be in the "\texttt{bin/packages}" directory. 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: +in OpenWrt you'll find several things: \begin{itemize} \item \texttt{package/\textit{}/Makefile} \item \texttt{package/\textit{}/patches} - \item \texttt{package/\textit{}/files} + \item \texttt{package/\textit{}/files} \end{itemize} The patches directory is optional and typically contains bug fixes or optimizations to @@ -195,13 +204,6 @@ simplifies the entire ordeal. Here for example, is \texttt{package/bridge/Makefile}: \begin{Verbatim}[frame=single,numbers=left] -# -# Copyright (C) 2006 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -# $Id: Makefile 5624 2006-11-23 00:29:07Z nbd $ include $(TOPDIR)/rules.mk @@ -222,12 +224,14 @@ define Package/bridge SECTION:=net CATEGORY:=Base system TITLE:=Ethernet bridging configuration utility - DESCRIPTION:=\ - Manage ethernet bridging: a way to connect networks together to \\\ - form a larger network. URL:=http://bridge.sourceforge.net/ endef +define Package/bridge/description + Manage ethernet bridging: + a way to connect networks together to form a larger network. +endef + define Build/Configure $(call Build/Configure/Default, \ --with-linux-headers="$(LINUX_DIR)" \ @@ -289,7 +293,7 @@ directly as the Nth argument to \texttt{BuildPackage}. \begin{itemize} \item \texttt{SECTION} \\ - The type of package (currently unused) + The section of package (currently unused) \item \texttt{CATEGORY} \\ Which menu it appears in menuconfig: Network, Sound, Utilities, Multimedia ... \item \texttt{TITLE} \\ @@ -299,7 +303,12 @@ directly as the Nth argument to \texttt{BuildPackage}. \item \texttt{MAINTAINER} (optional) \\ Who to contact concerning the package \item \texttt{DEPENDS} (optional) \\ - Which packages must be built/installed before this package. To reference a dependency defined in the same Makefile, use \textit{}. If defined as an external package, use \textit{+}. For a kernel version dependency use: \textit{@LINUX\_2\_} + Which packages must be built/installed before this package. To reference a dependency defined in the + same Makefile, use \textit{}. If defined as an external package, use + \textit{+}. For a kernel version dependency use: \textit{@LINUX\_2\_} + \item \texttt{BUILDONLY} (optional) \\ + Set this option to 1 if you do NOT want your package to appear in menuconfig. + This is useful for packages which are only used as build dependencies. \end{itemize} \textbf{\texttt{Package/\textit{}/conffiles} (optional):} \\ @@ -313,10 +322,42 @@ directly as the Nth argument to \texttt{BuildPackage}. 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 "\texttt{\$(call Build/Configure/Default,\textit{})}" as above to - pass in additional arguments for a standard configure script. The first list of arguments will be passed to the configure script like that: $--arg 1$ $--arg 2$. The second list contains arguments that should be defined before running the configure script such as autoconf or compiler specific variables. + pass in additional arguments for a standard configure script. The first list of arguments will be passed + to the configure script like that: \texttt{--arg 1} \texttt{--arg 2}. The second list contains arguments that should be + defined before running the configure script such as autoconf or compiler specific variables. + + To make it easier to modify the configure command line, you can either extend or completely override the following variables: + \begin{itemize} + \item \texttt{CONFIGURE\_ARGS} \\ + Contains all command line arguments (format: \texttt{--arg 1} \texttt{--arg 2}) + \item \texttt{CONFIGURE\_VARS} \\ + Contains all environment variables that are passed to ./configure (format: \texttt{NAME="value"}) + \end{itemize} \textbf{\texttt{Build/Compile} (optional):} \\ How to compile the source; in most cases you should leave this undefined. + + As with \texttt{Build/Configure} there are two variables that allow you to override + the make command line environment variables and flags: + \begin{itemize} + \item \texttt{MAKE\_FLAGS} \\ + Contains all command line arguments (typically variable overrides like \texttt{NAME="value"} + \item \texttt{MAKE\_VARS} \\ + Contains all environment variables that are passed to the make command + \end{itemize} + +\textbf{\texttt{Build/InstallDev} (optional):} \\ + If your package provides a library that needs to be made available to other packages, + you can use the \texttt{Build/InstallDev} template to copy it into the staging directory + which is used to collect all files that other packages might depend on at build time. + When it is called by the build system, two parameters are passed to it. \texttt{\$(1)} points to + the regular staging dir, typically \texttt{staging\_dir/\textit{ARCH}}, while \texttt{\$(2)} points + to \texttt{staging\_dir/host}. The host staging dir is only used for binaries, which are + to be executed or linked against on the host and its \texttt{bin/} subdirectory is included + in the \texttt{PATH} which is passed down to the build system processes. + Please use \texttt{\$(1)} and \texttt{\$(2)} here instead of the build system variables + \texttt{\$(STAGING\_DIR)} and \texttt{\$(STAGING\_DIR\_HOST)}, because the build system behavior + when staging libraries might change in the future to include automatic uninstallation. \textbf{\texttt{Package/\textit{}/install}:} \\ A set of commands to copy files out of the compiled source and into the ipkg @@ -345,6 +386,103 @@ After you have created your \texttt{package/\textit{}/Makefile}, the new p will automatically show in the menu the next time you run "make menuconfig" and if selected will be built automatically the next time "\texttt{make}" is run. +\subsection{Creating binary packages} + +You might want to create binary packages and include them in the resulting images as packages. +To do so, you can use the following template, which basically sets to nothing the Configure and +Compile templates. + +\begin{Verbatim}[frame=single,numbers=left] + +include $(TOPDIR)/rules.mk + +PKG_NAME:=binpkg +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=binpkg-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://server +PKG_MD5SUM:=9b7dc52656f5cbec846a7ba3299f73bd +PKG_CAT:=zcat + +include $(INCLUDE_DIR)/package.mk + +define Package/binpkg + SECTION:=net + CATEGORY:=Network + TITLE:=Binary package +endef + +define Package/bridge/description + Binary package +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/bridge/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/* $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,bridge)) +\end{Verbatim} + +Provided that the tarball which contains the binaries reflects the final +directory layout (/usr, /lib ...), it becomes very easy to get your package +look like one build from sources. + +Note that using the same technique, you can easily create binary pcakages +for your proprietary kernel modules as well. + +\subsection{Creating kernel modules packages} + +The OpenWrt distribution makes the distinction between two kind of kernel modules, those coming along with the mainline kernel, and the others available as a separate project. We will see later that a common template is used for both of them. + +For kernel modules that are part of the mainline kernel source, the makefiles are located in \textit{package/kernel/modules/*.mk} and they appear under the section "Kernel modules" + +For external kernel modules, you can add them to the build system just like if they were software packages by defining a KernelPackage section in the package makefile. + +Here for instance the Makefile for the I2C subsytem kernel modules : + +\begin{Verbatim}[frame=single,numbers=left] + +I2CMENU:=I2C Bus + +define KernelPackage/i2c-core + TITLE:=I2C support + DESCRIPTION:=Kernel modules for i2c support + SUBMENU:=$(I2CMENU) + KCONFIG:=CONFIG_I2C_CORE CONFIG_I2C_DEV + FILES:=$(MODULES_DIR)/kernel/drivers/i2c/*.$(LINUX_KMOD_SUFFIX) + AUTOLOAD:=$(call AutoLoad,50,i2c-core i2c-dev) +endef +$(eval $(call KernelPackage,i2c-core)) +\end{Verbatim} + +To group kernel modules under a common description in menuconfig, you might want to define a \textit{MENU} variable on top of the kernel modules makefile. + +\begin{itemize} + \item \texttt{TITLE} \\ + The name of the module as seen via menuconfig + \item \texttt{DESCRIPTION} \\ + The description as seen via help in menuconfig + \item \texttt{SUBMENU} \\ + The sub menu under which this package will be seen + \item \texttt{KCONFIG} \\ + Kernel configuration option dependency. For external modules, remove it. + \item \texttt{FILES} \\ + Files you want to inlude to this kernel module package, separate with spaces. + \item \texttt{AUTOLOAD} \\ + Modules that will be loaded automatically on boot, the order you write them is the order they would be loaded. +\end{itemize} + +After you have created your \texttt{package/kernel/modules/\textit{}.mk}, the new kernel modules package +will automatically show in the menu under "Kernel modules" next time you run "make menuconfig" and if selected +will be built automatically the next time "\texttt{make}" is run. \subsection{Conventions} @@ -378,14 +516,14 @@ shortcuts you can take. Instead of waiting for make to get to your package, you run one of the following: \begin{itemize} - \item \texttt{make package/\textit{}-clean V=99} - \item \texttt{make package/\textit{}-install V=99} + \item \texttt{make package/\textit{}/clean V=99} + \item \texttt{make package/\textit{}/install V=99} \end{itemize} -Another nice trick is that if the source directory under \texttt{build\_\textit{}} +Another nice trick is that if the source directory under \texttt{build\_dir/\textit{}} is newer than the package directory, it won't clobber it by unpacking the sources again. If you were working on a patch you could simply edit the sources under the -\texttt{build\_\textit{}/\textit{}} directory and run the install command above, +\texttt{build\_dir/\textit{}/\textit{}} directory and run the install command above, when satisfied, copy the patched sources elsewhere and diff them with the unpatched sources. A warning though - if you go modify anything under \texttt{package/\textit{}} it will remove the old sources and unpack a fresh copy. @@ -393,8 +531,65 @@ it will remove the old sources and unpack a fresh copy. Other useful targets include: \begin{itemize} - \item \texttt{make package/\textit{}-prepare V=99} - \item \texttt{make package/\textit{}-compile V=99} - \item \texttt{make package/\textit{}-configure V=99} + \item \texttt{make package/\textit{}/prepare V=99} + \item \texttt{make package/\textit{}/compile V=99} + \item \texttt{make package/\textit{}/configure V=99} \end{itemize} + +\subsection{Using build environments} +OpenWrt provides a means of building images for multiple configurations +which can use multiple targets in one single checkout. These \emph{environments} +store a copy of the .config file generated by \texttt{make menuconfig} and the contents +of the \texttt{./files} folder. +The script \texttt{./scripts/env} is used to manage these environments, it uses +\texttt{git} (which needs to be installed on your system) as backend for version control. + +The command +\begin{Verbatim} + ./scripts/env help +\end{Verbatim} +produces a short help text with a list of commands. + +To create a new environment named \texttt{current}, run the following command +\begin{Verbatim} + ./scripts/env new current +\end{Verbatim} +This will move your \texttt{.config} file and \texttt{./files} (if it exists) to +the \texttt{env/} subdirectory and create symlinks in the base folder. + +After running make menuconfig or changing things in files/, your current state will +differ from what has been saved before. To show these changes, use: +\begin{Verbatim} + ./scripts/env diff +\end{Verbatim} + +If you want to save these changes, run: +\begin{Verbatim} + ./scripts/env save +\end{Verbatim} +If you want to revert your changes to the previously saved copy, run: +\begin{Verbatim} + ./scripts/env revert +\end{Verbatim} + +If you want, you can now create a second environment using the \texttt{new} command. +It will ask you whether you want to make it a clone of the current environment (e.g. +for minor changes) or if you want to start with a clean version (e.g. for selecting +a new target). + +To switch to a different environment (e.g. \texttt{test1}), use: +\begin{Verbatim} + ./scripts/env switch test1 +\end{Verbatim} + +To rename the current branch to a new name (e.g. \texttt{test2}), use: +\begin{Verbatim} + ./scripts/env rename test2 +\end{Verbatim} + +If you want to get rid of environment switching and keep everything in the base directory +again, use: +\begin{Verbatim} + ./scripts/env clear +\end{Verbatim}