How to build and install cmocka?

Step into directory containing sources and create build sub-directory.

Step into build directory and execute

$ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
$ make

Installing

$ sudo make install

Download cmocka

cmocka at GitHub

cmocka

Advertisements

How to create self-extracting script for Android?

This is useful for consistent updating RIL, applications and configuration file.

Idea is to add compressed binary at the end of executable shell script file.

Step 1

On the build machine create payload directory and copy files into it.

Step 2

Create script installer in that directory which should do installation of components on target platform.

Step 3

Move one level up from payload directory and create decompress script with following content:

#!/system/bin/sh
echo “”
echo “Self Extracting Installer”
echo “”

# Creates temporary directory.
export TMPDIR=`mktemp -d selfextract.XXXXXX`

# Searches for marker of beginning of binary data.
ARCHIVE=`sed -n ‘/^__ARCHIVE_BELOW__/=’ $0`

# Adds 1 to get next line after the marker.
let ARCHIVE=$ARCHIVE+1

# Extracts binary data into temporary directory.
tail -n+$ARCHIVE $0 | tar xv -C $TMPDIR

# Stores current directory, goes to the temporary
# directory and starts the install script.
CDIR=`pwd`
cd $TMPDIR
./installer

# Returns back and removes temporary directory.
cd $CDIR
rm -rf $TMPDIR

# Prevents executing binary data.
exit 0

# No extra lines should be added after the marker.
__ARCHIVE_BELOW__

Step 4

Create build script having following content:

#!/bin/sh
# Compresses payload data.
cd payload
tar cf ../payload.tar ./*
cd ..

if [ -e “payload.tar” ]; then
# Data aren’t compressed due to lack of gunzip on target platform.
# Concatenates the decompressing script with binary data.
cat decompress payload.tar > selfextract.bsx
else
echo “payload.tar does not exist”
exit 1
fi

echo “selextract.bsx created”
exit 0

Step 5

Execute build script. Make sure that selfextract.bsx file is created.

Step 6

Copy selfextract.bsx file to target device, change file mode by

# chmod 755 selfextract.bsx

and execute it by

# ./selfextract.bsx

Make sure that files were updated successfully.

Read in more details

Bash Self-Extracting Script

How to make a self-extracting shell script from a TAR archive

Use grep to report back only line numbers

Sed Command in Linux/Unix with examples

Alternative to awk

The main differences from the solution proposed in referenced articles are:

  • sed utility is used instead of awk because the latter is not included in Android distribution by default;
  • compressing by gzip is not used because gunzip utility is not included as well.

How to build Android-x86

Setup procedure

  • Create a build account and define password
sudo useradd -m build
sudo passwd
  • Fully update your environment
sudo apt update
sudo apt upgrade
  • Install all required packages (google build environment spec.)
sudo apt install openjdk-8-jdk git git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip dosfstools
  • Install python-mako
sudo apt install python-mako
  • Install geniso and syslinux
sudo apt install geniso syslinux
  • As build user install google REPO tool
 curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
 chmod a+x ~/bin/repo
  • Init GIT repo
 git config --global build@mail.com
 git config --global user.email build@mail.com
 git config --global user.name build
  • Clone android sources
$ repo init -u http://scm.osdn.net/gitroot/android-x86/manifest -b oreo-x86
$ repo sync --no-tags --no-clone-bundle
  • Cloning other branch
$ repo init -u http://scm.osdn.net/gitroot/android-x86/manifest -b $branch
$ repo sync --no-tags --no-clone-bundle

Build procedure

  • Set source environment and helper functions
source build/envsetup.sh
  • Configure target architecture
 lunch android_x86_64-userdebug
  • Initiate build process. In our case we use 8 CPU cores and building an ISO image installable on VirtualBox
m -j8 iso_img 2>&1 | tee compile-01.log

Alternatively you can use following scripts build.sh which takes parameter and use it to construct image name

./prebuilts/sdk/tools/jack-admin kill-server
export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4g"
./prebuilts/sdk/tools/jack-admin start-server
 
source build/envsetup.sh
 
lunch android_x86_64-userdebug
 
m -j8 iso_img

# removes all other builds with the same label
rm android_x86_64_7.1_cougar_*_$1.iso

mv out/target/product/x86_64/android_x86_64.iso android_x86_64_7.1_cougar_$(date +'%y%m%d_%H%M%S')_$1.iso

and clean.sh cleaning output directory

source build/envsetup.sh
make clobber

If an error happened like “error: ro.build.fingerprint cannot exceed 91 bytes: Android-x86” do following

  • Edit build/tools/post_process_props.py
# See PROP_VALUE_MAX in system_properties.h.
# The constant in system_properties.h includes the terminating NUL,
# so we decrease the value by 1 here.
#PROP_VALUE_MAX = 91
PROP_VALUE_MAX = 127
  • Edit bionic/libc/include/sys/system_properties.h
//#define PROP_VALUE_MAX  92
#define PROP_VALUE_MAX  128
  • Edit frameworks/native/cmds/installd/installd_deps.h
//constexpr size_t kPropertyValueMax = 92u;
constexpr size_t kPropertyValueMax = 128u;
  • Do clean rebuild.

Build Issues

Default Jack server resources on 8-gig or less

 Stop Jack server: ./prebuilts/sdk/tools/jack-admin kill-server
 export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4g"
 Start jack server: ./prebuilts/sdk/tools/jack-admin start-server

 

How to add new C-application to Android build

Take as an example linmuxcfg application having single c-file.

Step 1

Create Android.mk file

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_CFLAGS += -Wall -Werror -Wextra -Wbad-function-cast  -Wmissing-prototypes
LOCAL_CFLAGS += -Wsign-compare -Wmissing-declarations -Wmissing-field-initializers
LOCAL_CFLAGS += -I../../kernel/include
LOCAL_CFLAGS += -DFS_DEVNUM=239 -DFS_DEVNAME='"linmuxcfg"'

LOCAL_MODULE := linmuxcfg
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := linmuxcfg.c

include $(BUILD_EXECUTABLE)

Step 2

Put the application into folder packages/apps relative the root of Android build chain.

Example

packages/apps/Linmuxcfg

Step 3

Add program (line linmuxcfg) into Android build script:

  • Android 8
    • ./build/make/target/product/base.mk
  • Android 7.1

Step 4

Execute make program_name or rebuild Android (the application will be build automatically). Find its binary in build chain by means of find -name program_name.

Example

make linmuxcfg
find -name linmuxcfg

Android Build System

How to get gateway address for IPv6 on Android

From command line execute

# route -n -A inet6

From returned strings select one having “UG” combination in the “flags” column.

Routing table for IPv6 on Android
Routing table for IPv6 on Android.

To do that programmatically open file /proc/net/ipv6_route (see screenshot above). Read it line by line, parse and select entry having flag “gateway” set.
Entries have following format

addr6p                   prerix_len saddr6p                        slen naddr6p                          metric   use      refcnt   iflags      iface
00000000000000000000000000000000 00 00000000000000000000000000000000 00 fe80000000000000ccaccc820e7ef078 00000400 00000000 00000000 00450003     ppp0

Read value of the “iflags” column and check for RTF_GATEWAY. Flags are defined in the “linux/route.h” header as

/* Keep this in sync with /usr/src/linux/include/linux/route.h */
#define RTF_UP          0x0001          /* route usable                 */
#define RTF_GATEWAY     0x0002          /* destination is a gateway     */
#define RTF_HOST        0x0004          /* host entry (net otherwise)   */
#define RTF_REINSTATE   0x0008          /* reinstate route after tmout  */
#define RTF_DYNAMIC     0x0010          /* created dyn. (by redirect)   */
#define RTF_MODIFIED    0x0020          /* modified dyn. (by redirect)  */
#define RTF_MTU         0x0040          /* specific MTU for this route  */
#ifndef RTF_MSS
#define RTF_MSS         RTF_MTU         /* Compatibility :-(            */
#endif
#define RTF_WINDOW      0x0080          /* per route window clamping    */
#define RTF_IRTT        0x0100          /* Initial round trip time      */
#define RTF_REJECT      0x0200          /* Reject route

Code sample

char naddr6p[33];
int num, iflags;
//  Parse rows and get attributes. An example of routing table entry:
//  addr6p                   prerix_len saddr6p                        slen naddr6p                          metric   use      refcnt   iflags      iface
//  00000000000000000000000000000000 00 00000000000000000000000000000000 00 fe80000000000000ccaccc820e7ef078 00000400 00000000 00000000 00450003     ppp0
num = sscanf(t, "%*32s %*02x %*32s %*02x %32s %*08x %*08x %*08x %08x %*s\n", naddr6p, &iflags);

if (num == 2 && (iflags & RTF_GATEWAY)) {
    ...
}

Continue reading