diff options
-rw-r--r-- | .gitignore | 9 | ||||
-rw-r--r-- | Makefile | 16 | ||||
-rw-r--r-- | img/mesa-androidmk.png | bin | 0 -> 61360 bytes | |||
-rw-r--r-- | img/replicant.png | bin | 0 -> 36607 bytes | |||
-rw-r--r-- | slides.tex | 368 | ||||
-rw-r--r-- | txt/android-bp-example | 14 | ||||
-rw-r--r-- | txt/android-mk-example | 15 | ||||
-rw-r--r-- | txt/android-single-package | 2 | ||||
-rw-r--r-- | txt/envsetup-commands | 9 | ||||
-rw-r--r-- | txt/gnulinux-packages | 8 | ||||
-rw-r--r-- | txt/manifest-example | 12 | ||||
-rw-r--r-- | txt/output-folder-example | 9 | ||||
-rw-r--r-- | txt/pkgbuild-example | 15 |
13 files changed, 477 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2e58368 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +output/ +*.aux +*.log +*.nav +*.out +*.pdf +*.snm +*.toc +*.vrb diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..753f1de --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +TEXFLAGS ?= -halt-on-error -output-format pdf -output-directory output --shell-escape +TITLE = slides + +.PHONY: all clean + +all: output/$(TITLE).pdf + +output: + mkdir output + +output/$(TITLE).pdf: $(TITLE).tex output + pdflatex $(TEXFLAGS) '\providecommand\locale{en}\input{$(TITLE).tex}' + pdflatex $(TEXFLAGS) '\providecommand\locale{en}\input{$(TITLE).tex}' + +clean: + rm -rf output svg-inkscape diff --git a/img/mesa-androidmk.png b/img/mesa-androidmk.png Binary files differnew file mode 100644 index 0000000..595e9bd --- /dev/null +++ b/img/mesa-androidmk.png diff --git a/img/replicant.png b/img/replicant.png Binary files differnew file mode 100644 index 0000000..0c33880 --- /dev/null +++ b/img/replicant.png diff --git a/slides.tex b/slides.tex new file mode 100644 index 0000000..e8ed401 --- /dev/null +++ b/slides.tex @@ -0,0 +1,368 @@ +\documentclass[aspectratio=169]{beamer} + +\mode<presentation> { +\usetheme{Madrid} + \setbeamertemplate{authors}{} + % Remove navigation symbols. + \setbeamertemplate{navigation symbols}{} +} + +\usepackage{color} +\usepackage{listings} +%\usepackage[utf8]{inputenc} +%\usepackage{graphicx} +%\usepackage[font=tiny,skip=0pt]{caption} +%\usepackage{array} +%\usepackage{verbatim} + +\graphicspath{{img/}} + +% Use symbols instead of numerals for footnotes. +\renewcommand{\thefootnote}{\fnsymbol{footnote}} +% Reset footnote counter every section. +\makeatletter +\@addtoreset{footnote}{subsection} +\makeatother + +\newcommand{\iconframe}[2] { + \begin{minipage}[t]{2.5em} + \includegraphics[width=\textwidth]{app-icons/#1} + \captionof*{figure}{#2} + \end{minipage} +} + +\title[Android's build system is messier than your distro's]{Android's build system is messier than your distro's} +\author{Denis `GNUtoo' Carikli \and Ricardo `Grim' Cabrita} +\institute[Replicant]{Replicant} +\date{} + + +\begin{document} + + +% # Android's build system is messier than your distro's +% The first step in the development of an Android distribution is coming to terms +% with the Android Open Source Project (AOSP) peculiar build system. Despite +% modular, AOSP's build system is quite complex and unlike those used in most +% other distributions. For instance, it lacks the concept of packages and expects +% sub-projects to be explicitly made compatible with it. +\begin{frame} + \maketitle +\end{frame} + +\lstset{ + basicstyle=\scriptsize\ttfamily, + keywordstyle=\color{blue}, + stringstyle=\color{orange}, + breaklines=true, +} + +% ## AOSP build system internals +% Until version 7 AOSP used a Makefile based system which, in contrast to other +% Make based build systems, didn't rely on recursive Makefiles that find and +% invoke other Makefiles contained in subdirectories. Rather, it used a custom +% script that explores all subdirectories in the source directory in search of +% Android.mk files, which describe how a local module is built and handled. The +% configuration of this system also differed from others such as GNU autotools or +% kernel-style menuconfig, relying instead on variables that are set either as +% part of the shell environment or statically and ahead of time on product and +% device Makefiles. +% As AOSP got larger this system became slow, error prone and hard to scale and +% test. To fix this, the Makefile-based system is getting replaced by Soong. Soong +% replaces Makefiles with Blueprint files, simpler declarative JSON-like +% descriptions of modules, that get translated into a Ninja manifest describing +% the commands that need to be run. This approach takes advantage of Ninja's +% outstanding performance while sparing developers from it's complex build +% language. During the transition period the remaining Makefiles are translated +% to Ninja by Kati instead of being executed directly. +% The transition to Soong solved the performance issue of AOSP's builds but got +% short of taking it closer to the modularity and flexibility found in most +% GNU/Linux distributions. +\section{BuildSystemIntro} + +\begin{frame}[fragile] + \frametitle{The Build System} + Before {\bf Android 7} (2006-2016) + \begin{itemize} + \item Makefile based + \item Finds and joins all {\bf Android.mk} files in one + \item Limited configuration during build + \item Error prone + \item Slow and unscalable + \end{itemize} +\end{frame} + +\begin{frame}[fragile] + \frametitle{The Build System} + Barebones Android.mk file example + \begin{block}{} + \lstinputlisting{txt/android-mk-example} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{The Build System} + From {\bf Android 7} onwards (2016-Now) + \begin{itemize} + \item {\bf Soong Build System} + \item {\bf Blueprint files} are replacing the old {\bf Makefiles} + \item {\bf Blueprint files} are converted to a {\bf Ninja} manifest + \item Remaining {\bf Makefiles} get translated to {\bf Ninja} by {\bf Kati} + \end{itemize} +\end{frame} + +\begin{frame}[fragile] + \frametitle{The Build System} + \begin{itemize} + \item {\bf Blueprint files} are simple to write + \item {\bf Ninja} is fast + \item Addresses performance issues + \item Falls short of addressing the lack of modulatiy and flexibility + \end{itemize} +\end{frame} + +\begin{frame}[fragile] + \frametitle{The Build System} + Barebones Android.bp file example + \begin{block}{} + \lstinputlisting{txt/android-bp-example} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Workflow} + \framesubtitle{Getting the source tree} + Initialize the repository + \begin{block}{} + \begin{lstlisting} +repo init -u https://git.replicant.us/replicant/manifest.git -b replicant-9 + \end{lstlisting} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Workflow} + \framesubtitle{Getting the source tree} + Inside a manifest file + \begin{block}{} + \lstinputlisting{txt/manifest-example} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Workflow} + \framesubtitle{Getting the source tree} + Download the source tree + \begin{block}{} + \begin{lstlisting} +repo sync + \end{lstlisting} + \end{block} + Contemplate disk usage + \begin{block}{} + \begin{lstlisting} +du -h --summarize +124GiB + \end{lstlisting} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Workflow} + \framesubtitle{Configuring the build} + Initialize the build environment + \begin{block}{} + \begin{lstlisting} +source build/envsetup.sh + \end{lstlisting} + \end{block} + \begin{block}{} + \lstinputlisting{txt/envsetup-commands} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Workflow} + \framesubtitle{Configuring the build} + Pick your menu + \begin{block}{} + \begin{lstlisting} +lunch replicant_i9305-userdebug + \end{lstlisting} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Workflow} + \framesubtitle{Build} + Start cooking + \begin{block}{} + \begin{lstlisting} +m bacon + \end{lstlisting} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Workflow} + \framesubtitle{Upload to device} + \begin{block}{} + \begin{lstlisting} +ls out/target/product/i9305 + \end{lstlisting} + \end{block} + \begin{block}{} + \lstinputlisting{txt/output-folder-example} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Workflow} + \framesubtitle{Upload to device} + Flash the images directly through download mode + \begin{block}{} + \begin{lstlisting} +heimdall flash --BOOT boot.img --SYSTEM system.img + \end{lstlisting} + \end{block} + Or install through recovery mode + \begin{block}{} + \begin{lstlisting} +adb sideload replicant-ota-eng.user.zip + \end{lstlisting} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Workflow} + \framesubtitle{Modify a module} + \begin{block}{} + \begin{lstlisting} +cd external/mesa3d +vim src/gallium/drivers/llvmpipe/Android.mk +mma +m snod +heimdall flash --SYSTEM system.img + \end{lstlisting} + \end{block} +\end{frame} + +% ## Building AOSP vs building GNU/Linux distros +% Virtually all GNU/Linux distributions use package managers, which wrap around +% the build system of choice of the software being packaged and bundle it into a +% reusable package that can be installed for direct use and or as a dependency for +% others. These packages can also be delivered and updated via software +% repositories after the initial installation of the distribution. In AOSP, there +% is no package manager. Most software components are built from git repositories +% and bundled into a single image that includes the majority of the distribution. +% Updating a single component thus becomes much harder. +% Besides the core components of AOSP, community distributions tend to use several +% external projects like Mesa and the Linux kernel. These must usually be +% integrated into the build tree as they depend on AOSP's libc. In such cases, +% Google expects the project maintainers to keep their project compatible with +% AOSP's build system, i.e. nowadays they expect the project to have its own +% Blueprint files. +% This contrasts with GNU/Linux distributions, which provide ways to build each +% project in its own native build system and then incorporate it into the distro +% image as an independent package. +\section{ComparisonToOtherDistros} +\begin{frame}[fragile] + \frametitle{Comparison to other distros} + \begin{itemize} + \item Recipe maintenance + \item Software delivery + \end{itemize} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Comparison to other distros} + \framesubtitle{Recipe maintenance} + {\bf GNU/Linux}: Most distros use package managers + \begin{block}{} + \lstinputlisting{txt/pkgbuild-example} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Comparison to other distros} + \framesubtitle{Recipe maintenance} + {\bf Android}: Projects are expected to keep their own Android.mk + \includegraphics[width=\linewidth,height=\textheight,keepaspectratio]{mesa-androidmk} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Comparison to other distros} + \framesubtitle{Recipe maintenance} + \begin{itemize} + \item Control of the build is out of the hands of the distro + \item Troublesome to modify build recipes + \item Disregard for the project's prefered build system + \item Changes to the recipe have to be made upstream least the distro wishes to maintain yet another fork + \end{itemize} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Comparison to other distros} + \framesubtitle{Software delivery} + {\bf GNU/Linux}: Packages are delivered through software repositories + \begin{block}{} + \lstinputlisting{txt/gnulinux-packages} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Comparison to other distros} + \framesubtitle{Software delivery} + {\bf Android}: Entire system is delivered through a single package + \begin{block}{} + \lstinputlisting{txt/android-single-package} + \end{block} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Comparison to other distros} + \framesubtitle{Software delivery} + \begin{itemize} + \item User has to download the entire system in order to update a single component + \item Updates are rarely delivered in a timely manner + \end{itemize} +\end{frame} + + +% ## Replicant's stake +% Replicant, a fully free-software AOSP distribution, is now undergoing intense +% work to make it as sustainable as possible by sharing code with GNU/Linux +% distributions. For instance, Replicant's next release (Replicant 9) is being +% developed on top of mainline Linux and Mesa. +% This comes with the disadvantage of having to deal with the unsuitability of AOSP +% build system to handle external projects. Long hours of development time are +% lost due to the incapability of AOSP to detect changes in projects that haven't +% been converted to Blueprint, such as Linux, Mesa or SwiftShader. +% Replicant is thus seeking to discuss and ultimately decide on a sustainable way +% to go deal with external software components. +% Supporting Blueprint could be advantageous for Replicant, due to its faster +% build times, selective recompilation when source files change on disk and +% ability to support multiple Android versions without convoluted conditional +% cases. However it would be preferable if Android supported some form of packages +% similarly to GNU/Linux distributions. Adding and maintaining Blueprint support +% in all external software components can be incredibly time consuming and could +% even be unsustainable. +\section{Replicant} +\begin{frame}[fragile] + \frametitle{Replicant's stake} + \begin{columns} + \begin{column}{0.2\textwidth} + \includegraphics[width=\textwidth]{replicant} + \end{column} + \begin{column}{0.7\textwidth} + Fully free Android distribution running on several devices\\\bigskip + Now undergoing intense work to make it as sustainable as possible\\\bigskip + Spending a lot of development time on the build system's quirks\\\bigskip + Seeking to discuss on a sustainable way to deal with external software componentes + \end{column} + \end{columns} +\end{frame} + + +\end{document} + diff --git a/txt/android-bp-example b/txt/android-bp-example new file mode 100644 index 0000000..c5a71e2 --- /dev/null +++ b/txt/android-bp-example @@ -0,0 +1,14 @@ +cc_binary { + name: "gzip", + srcs: ["src/test/generic.c"], + shared_libs: ["libz"], + arch: { + arm: { + srcs: ["src/test/arm.c"], + }, + x86: { + srcs: ["src/test/x86.c"], + }, + }, +} + diff --git a/txt/android-mk-example b/txt/android-mk-example new file mode 100644 index 0000000..1478c26 --- /dev/null +++ b/txt/android-mk-example @@ -0,0 +1,15 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := gzip +LOCAL_SRC_FILES := src/test/generic.c +LOCAL_SHARED_LIBRARIES := libz + +ifeq ($(TARGET_ARCH),arm) + LOCAL_SRC_FILES := src/test/arm.c +else + ifeq($(TARGET_ARCH),x86) + LOCAL_SRC_FILES := src/test/x86.c + endif +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/txt/android-single-package b/txt/android-single-package new file mode 100644 index 0000000..951a1aa --- /dev/null +++ b/txt/android-single-package @@ -0,0 +1,2 @@ +du -h replicant-6.0-i9300.zip +269M replicant-6.0-i9300.zip diff --git a/txt/envsetup-commands b/txt/envsetup-commands new file mode 100644 index 0000000..c6c779c --- /dev/null +++ b/txt/envsetup-commands @@ -0,0 +1,9 @@ +- lunch: lunch <product_name>-<build_variant> +- croot: Changes directory to the top of the tree. +- m: Makes from the top of the tree. +- mm: Builds all of the modules in the current directory. +- mmm: Builds all of the modules in the supplied directories. +- cgrep: Greps on all local C/C++ files. +- jgrep: Greps on all local Java files. +- resgrep: Greps on all local res/*.xml files. +- godir: Go to the directory containing a file. diff --git a/txt/gnulinux-packages b/txt/gnulinux-packages new file mode 100644 index 0000000..62a41bd --- /dev/null +++ b/txt/gnulinux-packages @@ -0,0 +1,8 @@ +pacman -Ss mesa +extra/mesa 19.3.0-1 [installed: 19.2.7-1] + An open-source implementation of the OpenGL specification + +pacman -S mesa +(...) +Total Download Size: 20.19 MiB + diff --git a/txt/manifest-example b/txt/manifest-example new file mode 100644 index 0000000..8eae98b --- /dev/null +++ b/txt/manifest-example @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<manifest> + <remote name="aosp" + fetch="https://android.googlesource.com" + revision="refs/tags/android-9.0.0_r44" /> +(...) + <project path="device/samsung/i9305" name="replicant-9/device_samsung_i9305" remote="replicant-9" /> + <project path="external/mesa3d" name="replicant-9/external_mesa3d" remote="replicant-9" /> + <project path="frameworks/base" name="replicant-9/frameworks_base" remote="replicant-9" /> + <project path="packages/apps/Dialer" name="LineageOS/android_packages_apps_Dialer" /> +(...) + diff --git a/txt/output-folder-example b/txt/output-folder-example new file mode 100644 index 0000000..4c70f77 --- /dev/null +++ b/txt/output-folder-example @@ -0,0 +1,9 @@ +(...) +boot.img +replicant-ota-eng.user.zip +ramdisk.img +ramdisk-recovery.img +recovery.img +system.img +userdata.img +(...) diff --git a/txt/pkgbuild-example b/txt/pkgbuild-example new file mode 100644 index 0000000..44a5857 --- /dev/null +++ b/txt/pkgbuild-example @@ -0,0 +1,15 @@ +pkgbase=mesa +pkgname=('vulkan-mesa-layer' 'opencl-mesa' 'vulkan-intel' 'vulkan-radeon' 'libva-mesa-driver' 'mesa-vdpau' 'mesa') +pkgdesc="An open-source implementation of the OpenGL specification" +pkgver=19.3.1 +(...) + +build() { + arch-meson mesa-$pkgver build \ + -D b_lto=false \ + -D platforms=x11,wayland,drm,surfaceless \ + -D dri-drivers=i915,i965,r100,r200,nouveau \ +(...) + meson configure build + ninja -C build +(...) |