How to compile Apache NuttX RTOS on Android with Termux (incomplete)...
Install Termux from F-Droid, because the Google Play version is outdated...
Launch Termux on Android and enter...
pkg upgrade
pkg update
Install SSH Server, so that it's easier to enter the install commands later...
## Install SSH Server
pkg install openssh
## Set the SSH Password
passwd
## Start SSH Server. To kill SSH Server: `pkill sshd`
sshd
## Find the IP address x.x.x.x of our Android Device
ifconfig
Alternatively, install Dropbear (because SSHD didn't work for me)...
## Install Dropbear
pkg install dropbear
## Set the SSH Password
passwd
## Start Dropbear. To kill Dropbear: `pkill dropbear`
dropbear
## Find the IP address x.x.x.x of our Android Device
ifconfig
From our Desktop Computer, ssh to our Android Device...
ssh x.x.x.x -p 8022
In the SSH Session, install the NuttX Build Tools on Android Termux...
pkg install binutils clang git make \
bison flex gettext texinfo \
gperf automake libtool pkg-config \
util-linux
## Kconfig doesn't exist for Arm64 Android, need to build ourselves
pushd $TMPDIR
git clone https://bitbucket.org/nuttx/tools.git
cd tools
cd kconfig-frontends
./configure --enable-mconf --disable-nconf --disable-gconf --disable-qconf
ln -s /data/data/com.termux/files/usr/bin/aclocal /data/data/com.termux/files/usr/bin/aclocal-1.15
ln -s /data/data/com.termux/files/usr/bin/automake /data/data/com.termux/files/usr/bin/automake-1.15
make
## `make install` won't work because Android Termux uses its own PATH
cp frontends/conf/.libs/kconfig-conf /data/data/com.termux/files/usr/bin
cp frontends/mconf/.libs/kconfig-mconf /data/data/com.termux/files/usr/bin
cp frontends/kconfig /data/data/com.termux/files/usr/bin
cp utils/kconfig-tweak /data/data/com.termux/files/usr/bin
cp libs/parser/.libs/libkconfig-parser-4.11.0.so /data/data/com.termux/files/usr/lib/
popd
Assume we're building NuttX for Arm64 PinePhone.
Termux on Android is based on aarch64-linux-android-gcc
, which isn't supported by the Precompiled GCC Toolchain. So we need to compile the GCC Toolchain ourselves.
Install GCC Arm64 Toolchain aarch64-none-elf-gcc
from Source Code...
## Download GCC Toolchain Source Code.
## Copied from https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
cd $HOME
mkdir gcc
cd gcc
curl -O -L https://developer.arm.com/-/media/Files/downloads/gnu/12.2.rel1/srcrel/arm-gnu-toolchain-src-snapshot-12.2.rel1.tar.xz
tar xf ../arm-gnu-toolchain-src-snapshot-12.2.rel1.tar.xz
## Build MPC ourselves because the older version fails with clang
curl -O -L https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz
tar xf mpc-1.1.0.tar.gz
pushd mpc-1.1.0
./configure \
--disable-shared \
--enable-static \
--prefix=$HOME/gcc \
--with-gmp=$HOME/gcc \
--with-mpfr=$HOME/gcc
make
make install
popd
## Build GCC Toolchain for `aarch64-none-elf`
## TODO: Change the target for your NuttX Device
## Refer to the Linaro ABE Example Manifests at https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
pushd arm-gnu-toolchain-src-snapshot-12.2.rel1
./configure \
--target=aarch64-none-elf \
--enable-static \
--prefix=$HOME/gcc \
--with-gmp=$HOME/gcc \
--with-mpfr=$HOME/gcc \
--disable-shared \
--disable-nls \
--disable-threads \
--disable-tls \
--enable-checking=release \
--enable-languages=c,c++ \
--with-newlib \
--with-gnu-as \
--with-gnu-ld
make
## Or `make -j 8` if your Android Device can handle it.
## Don't try `make -j`, it will crash your Android Device!
make install
popd
(Based on the Linaro ABE Example Manifest for aarch64-none-elf
)
GCC Build fails with this error...
make[3]: Entering directory '/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1/build-aarch64-unknown-linux-gnu/libcpp'
test -f config.h || (rm -f stamp-h1 && make stamp-h1)
g++ -std=c++11 -I../.././libcpp -I. -I../.././libcpp/../include -I../.././libcpp/include -g -O2 -W -Wall -Wno-narrowing -Wwrite-strings -Wmissing-format-attribute -pedantic -Wno-long-long -fno-exceptions -fno-rtti -I../.././libcpp -I. -I../.././libcpp/../include -I../.././libcpp/include -c -o lex.o -MT lex.o -MMD -MP -MF .deps/lex.Tpo ../.././libcpp/lex.cc
../.././libcpp/lex.cc:1289:7: warning: use of the 'likely' attribute is a C++20 extension [-Wc++20-attribute-extensions]
ATTR_LIKELY case kind::NONE:
^~~~~~~~~~~
../.././libcpp/system.h:427:25: note: expanded from macro 'ATTR_LIKELY'
# define ATTR_LIKELY [[likely]]
~~^~~~~~~~
../.././libcpp/lex.cc:4241:6: error: use of undeclared identifier 'fputc_unlocked'
fputc (NODE_NAME (token->val.node.node)[i], fp);
^
../.././libcpp/system.h:95:28: note: expanded from macro 'fputc'
# define fputc(C, Stream) fputc_unlocked (C, Stream)
^
../.././libcpp/lex.cc:4247:2: error: use of undeclared identifier 'fputc_unlocked'
fputc ('"', fp);
^
../.././libcpp/system.h:95:28: note: expanded from macro 'fputc'
# define fputc(C, Stream) fputc_unlocked (C, Stream)
^
../.././libcpp/lex.cc:4250:2: error: use of undeclared identifier 'fputc_unlocked'
fputc ('"', fp);
^
../.././libcpp/system.h:95:28: note: expanded from macro 'fputc'
# define fputc(C, Stream) fputc_unlocked (C, Stream)
^
1 warning and 3 errors generated.
make[3]: *** [Makefile:227: lex.o] Error 1
make[3]: Leaving directory '/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1/build-aarch64-unknown-linux-gnu/libcpp'
make[2]: *** [Makefile:3110: all-build-libcpp] Error 2
make[2]: Leaving directory '/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1'
make[1]: *** [Makefile:26855: stage1-bubble] Error 2
make[1]: Leaving directory '/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1'
make: *** [Makefile:1072: all] Error 2
Because fputc_unlocked
isn't defined on Android Termux. (See this)
To fix it: Edit gcc/system.h
and undefine fputc
at the end of the file...
// Existing code
...
#endif /* ! GCC_SYSTEM_H */
// Add this to the end of the file
#undef fputc
And rerun make -j
.
We might need to fix this warning...
gcc -c -g -O2 -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -Wmissing-format-attribute -Wno-overlength-strings -pedantic -Wno-long-long -DHAVE_CONFIG_H -I. -I../.././fixincludes -I../include -I../.././fixincludes/../include ../.././fixincludes/fixincl.c
../.././fixincludes/fixincl.c:1255:8: warning: call to undeclared function 'fputc_unlocked'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
fputc ('\n', out_fp);
^
../.././fixincludes/system.h:78:28: note: expanded from macro 'fputc'
# define fputc(C, Stream) fputc_unlocked (C, Stream)
TODO: GCC Toolchain Build fails with another error...
make[2]: Entering directory '/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1/host-aarch64-unknown-linux-gnu/gcc'
/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1/host-aarch64-unknown-linux-gnu/gcc/xgcc -B/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1/host-aarch64-unknown-linux-gnu/gcc/ -dumpspecs > tmp-specs
"/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1/host-aarch64-unknown-linux-gnu/gcc/xgcc": error: Android 5.0 and later only support position-independent executables (-fPIE).
make[2]: *** [Makefile:2185: specs] Error 1
make[2]: Leaving directory '/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1/host-aarch64-unknown-linux-gnu/gcc'
TODO: To fix this, edit host-aarch64-unknown-linux-gnu/gcc/Makefile
. Change...
NO_PIE_CFLAGS = -fno-PIE
NO_PIE_FLAG = -no-pie
To...
NO_PIE_CFLAGS = -fPIE
NO_PIE_FLAG = -fPIE
Rebuild...
pushd host-aarch64-unknown-linux-gnu/gcc
make clean
make -j 8
popd
make
Fails with this error...
checking for aarch64-none-elf-gcc... /data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1/host-aarch64-unknown-linux-gnu/gcc/xgcc -B/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1/host-aarch64-unknown-linux-gnu/gcc/ -B/data/data/com.termux/files/home/gcc/aarch64-none-elf/bin/ -B/data/data/com.termux/files/home/gcc/aarch64-none-elf/lib/ -isystem /data/data/com.termux/files/home/gcc/aarch64-none-elf/include -isystem /data/data/com.termux/files/home/gcc/aarch64-none-elf/sys-include
checking for suffix of object files... configure: error: in `/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1/aarch64-none-elf/libgcc':
configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details
make[1]: *** [Makefile:13954: configure-target-libgcc] Error 1
make[1]: Leaving directory '/data/data/com.termux/files/home/gcc/arm-gnu-toolchain-src-snapshot-12.2.rel1'
make: *** [Makefile:1030: all] Error 2
TODO: xgcc
has been compiled successfully. How do we turn it into aarch64-none-elf-gcc
?
~/.../host-aarch64-unknown-linux-gnu/gcc $ ./xgcc --help
Usage: xgcc [options] file...
Options:
-pass-exit-codes Exit with highest error code from a phase.
--help Display this information.
--target-help Display target specific command line options (including assembler and linker options).
--help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...].
Display specific types of command line options.
(Use '-v --help' to display command line options of sub-processes).
--version Display compiler version information.
-dumpspecs Display all of the built in spec strings.
-dumpversion Display the version of the compiler.
-dumpmachine Display the compiler's target processor.
-foffload=<targets> Specify offloading targets.
-print-search-dirs Display the directories in the compiler's search path.
-print-libgcc-file-name Display the name of the compiler's companion library.
-print-file-name=<lib> Display the full path to library <lib>.
-print-prog-name=<prog> Display the full path to compiler component <prog>.
-print-multiarch Display the target's normalized GNU triplet, used as
a component in the library path.
-print-multi-directory Display the root directory for versions of libgcc.
-print-multi-lib Display the mapping between command line options and
multiple library search directories.
-print-multi-os-directory Display the relative path to OS libraries.
-print-sysroot Display the target libraries directory.
-print-sysroot-headers-suffix Display the sysroot suffix used to find headers.
-Wa,<options> Pass comma-separated <options> on to the assembler.
-Wp,<options> Pass comma-separated <options> on to the preprocessor.
-Wl,<options> Pass comma-separated <options> on to the linker.
-Xassembler <arg> Pass <arg> on to the assembler.
-Xpreprocessor <arg> Pass <arg> on to the preprocessor.
-Xlinker <arg> Pass <arg> on to the linker.
-save-temps Do not delete intermediate files.
-save-temps=<arg> Do not delete intermediate files.
-no-canonical-prefixes Do not canonicalize paths when building relative
prefixes to other gcc components.
-pipe Use pipes rather than intermediate files.
-time Time the execution of each subprocess.
-specs=<file> Override built-in specs with the contents of <file>.
-std=<standard> Assume that the input sources are for <standard>.
--sysroot=<directory> Use <directory> as the root directory for headers
and libraries.
-B <directory> Add <directory> to the compiler's search paths.
-v Display the programs invoked by the compiler.
-### Like -v but options quoted and commands not executed.
-E Preprocess only; do not compile, assemble or link.
-S Compile only; do not assemble or link.
-c Compile and assemble, but do not link.
-o <file> Place the output into <file>.
-pie Create a dynamically linked position independent
executable.
-shared Create a shared library.
-x <language> Specify the language of the following input files.
Permissible languages include: c c++ assembler none
'none' means revert to the default behavior of
guessing the language based on the file's extension.
Options starting with -g, -f, -m, -O, -W, or --param are automatically
passed on to the various sub-processes invoked by xgcc. In order to pass
other options on to these processes the -W<letter> options must be used.
For bug reporting instructions, please see:
<https://gcc.gnu.org/bugs/>.
~/.../host-aarch64-unknown-linux-gnu/gcc $ ./xgcc -dumpmachine
aarch64-none-elf
TODO: Add aarch64-none-elf-gcc
to PATH. ~/.bashrc
doesn't exist on Android Termux.
Download NuttX...
cd $HOME
mkdir nuttx
cd nuttx
git clone https://github.com/apache/nuttx nuttx
git clone https://github.com/apache/nuttx-apps apps
Configure NuttX...
cd nuttx
tools/configure.sh pinephone:lvgl
Build NuttX...
make
Which fails because the GCC Arm64 Toolchain aarch64-none-elf-gcc
is not installed...
~/nuttx/nuttx $ make
sh: aarch64-none-elf-gcc: inaccessible or not found
ERROR: aarch64-none-elf-gcc failed: 127
command: aarch64-none-elf-gcc -MT ./builtin_list.c.data.data.com.termux.files.home.nuttx.apps.builtin.o -M '-fno-common' '-Wall' '-Wstrict-prototypes' '-Wshadow' '-Wundef' '-Werror' '-Os' '-fno-strict-aliasing' '-fomit-frame-pointer' '-ffunction-sections' '-fdata-sections' '-g' '-march=armv8-a' '-mtune=cortex-a53' '-isystem' '/data/data/com.termux/files/home/nuttx/nuttx/include' '-D__NuttX__' '-D__KERNEL__' '-pipe' '-I' '/data/data/com.termux/files/home/nuttx/apps/graphics/lvgl' '-I' '/data/data/com.termux/files/home/nuttx/apps/include' ./builtin_list.c
make[2]: *** [/data/data/com.termux/files/home/nuttx/apps/Application.mk:250: .depend] Error 1
make[1]: *** [Makefile:56: /data/data/com.termux/files/home/nuttx/apps/builtin_depend] Error 2
make: *** [tools/Unix.mk:594: pass2dep] Error 2
Remember give extra power to Android Termux to speed it up...
- Termux > App Info > App Battery Usage > Unrestricted
If the GCC Toolchain fails to build, try another distro on top of Termux...