[FE training-materials-updates] buildroot-make: new chapter

Thomas Petazzoni thomas.petazzoni at free-electrons.com
Thu May 7 15:54:33 CEST 2015


Repository : git://git.free-electrons.com/training-materials.git

On branch  : master
Link       : http://git.free-electrons.com/training-materials/commit/?id=19fb5626358b0d2f6d079ee2d4e34f4941f30a3b

>---------------------------------------------------------------

commit 19fb5626358b0d2f6d079ee2d4e34f4941f30a3b
Author: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
Date:   Thu May 7 15:54:10 2015 +0200

    buildroot-make: new chapter
    
    Signed-off-by: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>


>---------------------------------------------------------------

19fb5626358b0d2f6d079ee2d4e34f4941f30a3b
 Makefile                                 |   1 +
 slides/buildroot-make/buildroot-make.tex | 196 +++++++++++++++++++++++++++++++
 2 files changed, 197 insertions(+)

diff --git a/Makefile b/Makefile
index 507b7d9..93d30a8 100644
--- a/Makefile
+++ b/Makefile
@@ -292,6 +292,7 @@ BUILDROOT_SLIDES = \
 		buildroot-kernel \
 		buildroot-rootfs \
 		buildroot-download \
+		buildroot-make \
 		buildroot-new-packages \
 		buildroot-advanced-packages \
 		buildroot-analysis \
diff --git a/slides/buildroot-make/buildroot-make.tex b/slides/buildroot-make/buildroot-make.tex
new file mode 100644
index 0000000..db67d40
--- /dev/null
+++ b/slides/buildroot-make/buildroot-make.tex
@@ -0,0 +1,196 @@
+\section{GNU Make 101}
+
+\begin{frame}{Introduction}
+  \begin{itemize}
+  \item Buildroot being implemented in {\bf GNU Make}, it is quite
+    important to know the basics of this language
+    \begin{itemize}
+    \item Basics of {\em make} rules
+    \item Defining and referencing variables
+    \item Conditions
+    \item Defining and using functions
+    \item Useful {\em make} functions
+    \end{itemize}
+  \item This does not aim at replacing a full course o {\em GNU Make}
+  \item \url{http://www.gnu.org/software/make/manual/make.html}
+  \item \url{http://www.nostarch.com/gnumake}
+  \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Basics of {\em make} rules}
+  \begin{itemize}
+  \item At their core, {\em Makefiles} are simply defining {\bf rules}
+    to create {\bf targets} from {\bf prerequisites} using {\bf recipe
+      commands}
+    \begin{block}{}
+\begin{verbatim}
+TARGET ...: PREREQUISITES ...
+         RECIPE
+         ...
+\end{verbatim}
+    \end{block}
+  \item {\bf target}: name of a file that is generated. Can also be an
+    arbitrary action, like \code{clean}, in which case it's a {\bf
+      phony target}
+  \item {\bf prerequisites}: list of files or other targets that are
+    needed as dependencies of building the current target.
+  \item {\bf recipe}: list of shell commands to create the target from
+    the prerequisites
+  \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Rule example}
+
+\begin{block}{Makefile}
+\begin{minted}[fontsize=\scriptsize]{make}
+clean:
+        rm -rf $(TARGET_DIR) $(BINARIES_DIR) $(HOST_DIR) \
+                $(BUILD_DIR) $(BASE_DIR)/staging \
+                $(LEGAL_INFO_DIR)
+
+distclean: clean
+        [...]
+        rm -rf $(BR2_CONFIG) $(CONFIG_DIR)/.config.old \
+               $(CONFIG_DIR)/.auto.deps
+\end{minted}
+\end{block}
+
+\begin{itemize}
+\item \code{clean} and \code{distclean} are phony targets
+\end{itemize}
+
+\end{frame}
+
+\begin{frame}[fragile]{Defining and referencing variables}
+  \begin{itemize}
+  \item Defining variables is done in different ways:
+    \begin{itemize}
+    \item \code{FOOBAR = value}, a recursively expanded variable
+    \item \code{FOOBAR := value}, a simply expanded variable
+    \item \code{FOOBAR ?= value}, defined only if not already defined
+    \item Multi-line variables are described using \code{define NAME
+        ... endef}:
+      \begin{block}{}
+\begin{verbatim}
+define FOOBAR
+line 1
+line 2
+endef
+\end{verbatim}
+      \end{block}
+    \end{itemize}
+  \item Make variables are referenced using the \code{$(FOOBAR)}
+    syntax.
+  \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Conditions}
+  \begin{itemize}
+  \item With \code{ifeq} or \code{ifneq}
+    \begin{block}{}
+\begin{minted}[fontsize=\tiny]{make}
+ifeq ($(BR2_CCACHE),y)
+CCACHE := $(HOST_DIR)/usr/bin/ccache
+endif
+
+distclean: clean
+ifeq ($(DL_DIR),$(TOPDIR)/dl)
+        rm -rf $(DL_DIR)
+endif
+\end{minted}
+    \end{block}
+  \item With the \code{$(if ...)} make function:
+    \begin{block}{}
+\begin{minted}[fontsize=\tiny]{make}
+HOSTAPD_LIBS += $(if $(BR2_STATIC_LIBS),-lcrypto -lz)
+\end{minted}
+    \end{block}
+  \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Defining and using functions}
+  \begin{itemize}
+  \item Defining a function is exactly like defining a variable:
+    \begin{block}{}
+\begin{minted}[fontsize=\tiny]{make}
+MESSAGE = echo "$(TERM_BOLD)>>> $($(PKG)_NAME) $($(PKG)_VERSION) $(call qstrip,$(1))$(TERM_RESET)"
+
+define legal-license-header # pkg, license-file, {HOST|TARGET}
+        printf "$(LEGAL_INFO_SEPARATOR)\n\t$(1):\
+                $(2)\n$(LEGAL_INFO_SEPARATOR)\n\n\n" >>$(LEGAL_LICENSES_TXT_$(3))
+endef
+\end{minted}
+    \end{block}
+  \item Arguments accessible as \code{$(1)}, \code{$(2)}, etc.
+  \item Called using the \code{$(call func,arg1,arg2)} construct
+    \begin{block}{}
+\begin{minted}[fontsize=\tiny]{make}
+$(BUILD_DIR)/%/.stamp_extracted:
+        [...]
+        @$(call MESSAGE,"Extracting")
+
+define legal-license-nofiles # pkg, {HOST|TARGET}
+        $(call legal-license-header,$(1),unknown license file(s),$(2))
+endef
+\end{minted}
+    \end{block}
+  \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Useful {\em make} functions}
+  \begin{itemize}
+  \item \code{subst} and \code{patsubst} to replace text
+    \begin{block}{}
+\begin{minted}[fontsize=\tiny]{make}
+ICU_SOURCE = icu4c-$(subst .,_,$(ICU_VERSION))-src.tgz
+\end{minted}
+    \end{block}
+  \item \code{filter} and \code{filter-out} to filter entries
+  \item \code{foreach} to implement loops
+\begin{block}{}
+\begin{minted}[fontsize=\tiny]{make}
+$(foreach incdir,$(TI_GFX_HDR_DIRS),
+      $(INSTALL) -d $(STAGING_DIR)/usr/include/$(notdir $(incdir)); \
+      $(INSTALL) -D -m 0644 $(@D)/include/$(incdir)/*.h \
+              $(STAGING_DIR)/usr/include/$(notdir $(incdir))/
+)
+\end{minted}
+\end{block}
+  \item \code{dir}, \code{notdir}, \code{addsuffix}, \code{addprefix}
+    to manipulate file names
+    \begin{block}{}
+\begin{minted}[fontsize=\tiny]{make}
+UBOOT_SOURCE = $(notdir $(UBOOT_TARBALL))
+
+IMAGEMAGICK_CONFIG_SCRIPTS = \
+        $(addsuffix -config,Magick MagickCore MagickWand Wand)
+\end{minted}
+    \end{block}
+  \item And many more, see the {\em GNU Make} manual for details.
+  \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Writing recipes}
+
+  \begin{itemize}
+  \item Recipes are just shell commands
+  \item Each line of shell command in a given recipe is independent
+    from the other: variables are not shared between lines in the
+    recipe
+  \item Need to use a single line, possibly split using $\backslash$,
+    to do complex shell constructs
+  \item Shell variables must be referenced using \code{$$name}.
+    \begin{block}{package/pppd/pppd.mk}
+\begin{minted}[fontsize=\tiny]{make}
+define PPPD_INSTALL_RADIUS
+        ...
+        for m in $(PPPD_RADIUS_CONF); do \
+                $(INSTALL) -m 644 -D $(PPPD_DIR)/pppd/plugins/radius/etc/$$m \
+                        $(TARGET_DIR)/etc/ppp/radius/$$m; \
+        done
+        ...
+endef
+\end{minted}
+\end{block}
+  \end{itemize}
+\end{frame}



More information about the training-materials-updates mailing list