More work to ship libretroshare as standalone lib

Improved CMake support
Initial work on packaging libretroshare as an Android library AAR
Deal properly with Android API level which miss largefile support
  instead of relying on build system trickery
This commit is contained in:
Gioacchino Mazzurco 2022-01-10 15:40:22 +01:00
parent e62b847234
commit c0e10ee2fa
No known key found for this signature in database
GPG key ID: A1FBCA3872E87051
24 changed files with 690 additions and 64 deletions

View file

@ -0,0 +1,117 @@
## To prepare an image suitable as base for Gitlab CI use
## image name must match gitlab repository name, you can play just with the tag
## the part after :
# export CI_IMAGE_NAME="registry.gitlab.com/retroshare/retroshare:android_arm_base"
# docker build --squash --tag "${CI_IMAGE_NAME}" \
# --build-arg QT_INSTALLER_JWT_TOKEN="your qt JWT token goes here" .
#
# To build Android ARMv8 (64 bit) package pass also
# export CI_IMAGE_NAME="registry.gitlab.com/retroshare/retroshare:android_arm64_base"
# --build-arg ANDROID_NDK_ARCH=arm64 --build-arg ANDROID_PLATFORM_VER=21
## --squash is very important in case of GitlabCI shared runners as they are
## limited to 25GB disk size
## To push it to gitlab CI registry you need first to login and the to push
# docker login registry.gitlab.com
# docker push ${CI_IMAGE_NAME}
## To extract the generated APK easily you can run after the build complete
# docker cp \
# $(docker create --rm ${CI_IMAGE_NAME}):/retroshare-service-android-build/android-build/build/outputs/apk/debug/android-build-debug.apk \
# /tmp/RetroShare_Android_Service.apk
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
ENV APT_UNAT="--assume-yes --quiet"
RUN apt-get update $APT_UNAT && apt-get upgrade --show-upgraded $APT_UNAT && \
apt-get clean $APT_UNAT
RUN apt-get install --no-install-recommends $APT_UNAT \
bash build-essential bzip2 cmake curl chrpath doxygen \
git p7zip python qt5-default qttools5-dev tclsh unzip wget zip
# Dependencies to create Android pkg
RUN apt-get install --no-install-recommends $APT_UNAT \
openjdk-8-jre openjdk-8-jdk openjdk-8-jdk-headless gradle
ARG FRESHCLONE=0
ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git
ARG REPO_BRANCH=master
ARG REPO_DEPTH="--depth 2000"
RUN git clone $REPO_DEPTH $REPO_URL -b $REPO_BRANCH && cd RetroShare && \
git fetch --tags
ENV PREPARE_TOOLCHAIN="/RetroShare/build_scripts/Android/prepare-toolchain-clang.sh"
ENV NATIVE_LIBS_TOOLCHAIN_PATH="/android-toolchain/"
ARG ANDROID_PLATFORM_VER=16
ARG ANDROID_NDK_ARCH=arm
ENV ANDROID_SDK_PATH="/opt/android-sdk"
ENV ANDROID_HOME="$ANDROID_SDK_PATH"
ENV ANDROID_SDK_ROOT="$ANDROID_SDK_PATH"
ENV ANDROID_NDK_PATH="/opt/android-ndk"
ENV ANDROID_NDK_ROOT="$ANDROID_NDK_PATH"
ENV PATH="$PATH:$ANDROID_HOME/tools"
ENV PATH="$PATH:$ANDROID_HOME/platform-tools"
ENV JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64/"
RUN mkdir /bCache
WORKDIR /bCache
## Quick HACK to ease development
#COPY prepare-toolchain-clang.sh $PREPARE_TOOLCHAIN
RUN $PREPARE_TOOLCHAIN install_android_sdk
RUN $PREPARE_TOOLCHAIN install_android_ndk
RUN $PREPARE_TOOLCHAIN
ARG QT_INSTALLER_JWT_TOKEN
RUN $PREPARE_TOOLCHAIN install_qt_android
# Avoid Qt account details leak into the image
RUN rm -f /root/.local/share/Qt/qtaccount.ini
# Shrink image by removing unneeded Qt components
RUN rm -r \
$NATIVE_LIBS_TOOLCHAIN_PATH/Qt/Docs/ \
$NATIVE_LIBS_TOOLCHAIN_PATH/Qt/Examples/ \
$NATIVE_LIBS_TOOLCHAIN_PATH/Qt/Tools/
RUN mkdir /jsonapi-generator-build
WORKDIR /jsonapi-generator-build/
RUN qmake ../RetroShare/jsonapi-generator/src/ \
CONFIG+=no_retroshare_plugins \
CONFIG+=no_retroshare_service CONFIG+=no_retroshare_gui \
CONFIG+=rs_jsonapi CONFIG+=no_rs_sam3_libsam3 && \
make -j$(nproc)
RUN mkdir /retroshare-service-android-build
WORKDIR /retroshare-service-android-build
ARG RS_SERVICE_QMAKE_EXTRA_OPTS
RUN $($PREPARE_TOOLCHAIN get_qt_dir | head -n 1)/bin/qmake ../RetroShare \
-spec android-clang \
CONFIG+=retroshare_service CONFIG+=rs_jsonapi \
RS_UPNP_LIB=miniupnpc \
JSONAPI_GENERATOR_EXE=/jsonapi-generator-build/jsonapi-generator \
NATIVE_LIBS_TOOLCHAIN_PATH=$NATIVE_LIBS_TOOLCHAIN_PATH \
CONFIG+=no_retroshare_gui CONFIG+=no_rs_service_webui_terminal_password \
CONFIG+=no_rs_service_terminal_login \
CONFIG+=no_rs_sam3 CONFIG+=no_rs_sam3_libsam3 \
$RS_SERVICE_QMAKE_EXTRA_OPTS
RUN make -j$(nproc)
RUN make install INSTALL_ROOT=/retroshare-service-android-build/android-build/
RUN $($PREPARE_TOOLCHAIN get_qt_dir | head -n 1)/bin/androiddeployqt \
--input retroshare-service/src/android-libretroshare-service.so-deployment-settings.json \
--output android-build --android-platform android-$ANDROID_PLATFORM_VER \
--jdk $JAVA_HOME --gradle
RUN rm -rf /bCache
# Clean apt cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

View file

@ -0,0 +1,400 @@
= RetroShare development on Android
// SPDX-FileCopyrightText: RetroShare Team <contact@retroshare.cc>
// SPDX-License-Identifier: CC-BY-SA-4.0
Compiling an application for Android is not as easy as one would imagine,
expecially one like RetroShare that has a big codebase and is not well
documented. This document is aimed to empower the reader so she can hopefully
succed or at least have a significant help in compiling her own RetroShare APK
installable on Android.
== Preparing The Environement
First of all setup your Qt for Android development environement following the
guide on the link:http://doc.qt.io/qt-5/androidgs.html[Qt for android web site].
At this point you should have Android SDK, Android NDK, and Qt for Android
working fine, and you should be capable of executing on an Android emulator or
on your Android phone Qt for Android examples.
But RetroShare is not as simple to compile as those examples. The good news is
that Android NDK ships all the necessary to build a custom toolchain that is
suitable to build RetroShare.
In order to build the toolchain with needed libraries RetroShare provides the
+android-prepare-toolchain.sh+ script; before you execute it you should define
some variables the script cannot determine in an easy and reliable manner by
itself in your terminal.
[source,bash]
-------------------------------------------------------------------------------
## The path where Android NDK is installed in your system
export ANDROID_NDK_PATH="/opt/android-ndk/"
## The path where your fresh compiled toolchain will be installed, make sure
## the parent exists
export NATIVE_LIBS_TOOLCHAIN_PATH="${HOME}/Builds/android-toolchains/retroshare-android/"
## The CPU architecture of the Android device you want to target
export ANDROID_NDK_ARCH="arm"
## The Android API level the Android device you want to target
export ANDROID_PLATFORM_VER="16"
## The number of core that yout host CPU have (just to speed up compilation) set
## it to 1 if unsure
export HOST_NUM_CPU=1
./android-prepare-toolchain.sh
-------------------------------------------------------------------------------
== Preparing Qt Creator
Now that your environement is set up you should configure Qt Creator for Android
following the
link:http://doc.qt.io/qtcreator/creator-developing-android.html[official guide].
At the end of this step your Qt Creator should recognize the Android compiler
and the Qt for Android kit.
Your Kit is now ready to use. Now you can open RetroShare as a Qt Creator
project and in the Projects left menu add the newly created kit if not already
present, so you can select it on the build type selection button down on the
left.
Now you need to set properly a few options like `JSONAPI_GENERATOR_EXE` and
disable some of RetroShare modules like `retroshare-gui` that are not available
on Android so you will have to go to
_Qt Creator left pane -> Projects -> Build and Run -> Android SOMESTUFF kit ->
Build Steps -> qmake -> Additional arguments_ +
and add the following configurations (change `Your_Path` according to your
deployment)
[source,makefile]
-------------------------------------------------------------------------------
CONFIG+=retroshare_service CONFIG+=rs_jsonapi CONFIG+=no_keywords
RS_UPNP_LIB=miniupnpc
JSONAPI_GENERATOR_EXE=Your_Path/jsonapi-generator/src/jsonapi-generator
NATIVE_LIBS_TOOLCHAIN_PATH=Your_Path/retroshare-android-16-arm/
CONFIG+=no_retroshare_gui CONFIG+=no_rs_service_webui_terminal_password
CONFIG+=no_rs_service_terminal_login
CONFIG+=no_rs_sam3 CONFIG+=no_rs_sam3_libsam3
-------------------------------------------------------------------------------
TIP: Some versions of QtCreator try to find the Android SDK in
`/opt/android/sdk`. A workaround to this is to make a symbolic link there
pointing to your SDK installation path, like
+mkdir -p /opt/android/sdk && ln -s /home/user/android-sdk-linux
/opt/android/sdk+
== Quircks
=== Protected Apps
On some Android devices like +Huawei ALE-L21+ background applications are
killed when screen is turned off unless they are in the _protected app_ list.
At moment seems apps developers don't have a way to have the application
_protected_ by default, unless the phone vendor decide the app is _popular_ so
the user have to enable _protection_ for RetroShare manually on those mobile
phones. +
{empty} +
To enable enable _protection_: +Android menu -> Settings -> Privacy & security
-> Protected apps -> RetroShare+ +
{empty} +
Other devices may offer similar _features_ please report them.
=== APK signature mismatch
If you try to install a RetroShare APK that comes from a different source
(eg: if you try to upgrade from F-Droid when you originally installed an APK
build by yourself) Android will prevent that from happening. In that case the
only solution is to uninstall the app and then install the new APK but if you do
it also the application data and your precious cryptographic keys, friend list
etc. will be lost forever.
To avoid that you can attempt to manually backup and then restore from the
command-line (`adb backup` seems not working either) to change the app source
without erasing the appliation data.
CAUTION: Following steps require root access on your Android device
.Backup RetroShare Android application data
[source,bash]
--------------------------------------------------------------------------------
export ORIG_DIR="/data/data/org.retroshare.android.qml_app"
export BACKUP_DIR="org.retroshare.android.qml_app.backup"
adb root
adb shell am force-stop org.retroshare.android.qml_app
sleep 1s
mkdir ${BACKUP_DIR}
# Avoid adb pull failing
adb shell rm ${ORIG_DIR}/files/.retroshare/libresapi.sock
adb pull ${ORIG_DIR}/files/ ${BACKUP_DIR}/files/
--------------------------------------------------------------------------------
After this you should be able to uninstall the old APK with your preferred
method, as example from the command-line.
.Uninstall RetroShare Android from the command-line
[source,bash]
--------------------------------------------------------------------------------
adb uninstall org.retroshare.android.qml_app
--------------------------------------------------------------------------------
Now you can install a different signature APK and then restore the application
data with the following commands.
[source,bash]
--------------------------------------------------------------------------------
export ORIG_DIR="/data/data/org.retroshare.android.qml_app"
export BACKUP_DIR="org.retroshare.android.qml_app.backup"
adb root
## Launch the app to make sure the parent directory exists and has proper owner
adb shell monkey -p org.retroshare.android.qml_app -c android.intent.category.LAUNCHER 1
sleep 1s
adb shell am force-stop org.retroshare.android.qml_app
sleep 1s
APP_OWNER="$(adb shell busybox ls -lnd ${ORIG_DIR} | awk '{print $3":"$4}')"
adb shell rm -rf ${ORIG_DIR}/files
adb push ${BACKUP_DIR}/files/ ${ORIG_DIR}/files/
adb shell busybox chown -R ${APP_OWNER} ${ORIG_DIR}/files/
--------------------------------------------------------------------------------
Opening RetroShare android app now should show your old profile.
== Debugging with GDB
If building RetroShare Android package seems tricky, setting up a functional
debugging environement for it feels like black magic. This section is meant to
help you doing it with less headache and hopefully in a reproducible way.
Unfortunately at the time of the last update to this guide, Qt build system
strips debugging symbols from the package and from the buildroot also if you
compile with debugging enabled. Fiddling with `qmake` configurations and
variables like `CONFIG+=debug`, `CONFIG+=force_debug_info` or `QMAKE_STRIP`
either as commandline arguments or inside retroshare `.pro` and `.pri` files is
uneffective. IMHO Qt should handle this on itself so it is probably worth
reporting a bug to them. So to workaround this problem you need to fiddle a bit
with the Android NDK. In my case I always keep +Debug+ or +Release+ suffix in
my build directory name depending on what kind of build it is, so I use this
information and modify `llvm-strip` in a way that it will strip only if stripped
file path doesn't contain +Debug+.
.Modify llvm-strip inside Android NDK
--------------------------------------------------------------------------------
## Set ANDROID_NDK_PATH to your Android NDK installation path
export ANDROID_NDK_PATH="/opt/android-ndk/"
## Define a convenience variable with llvm-strip path
export ANDROID_NDK_LLVM_STRIP="${ANDROID_NDK_PATH}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip"
## If not existing yer create a backup of the original llvm-strip
[ -f "${ANDROID_NDK_LLVM_STRIP}.back" ] ||
cp "${ANDROID_NDK_LLVM_STRIP}" "${ANDROID_NDK_LLVM_STRIP}.back"
## Create a new llvm-strip that does nothing if the argument path contains Debug
cat > "${ANDROID_NDK_LLVM_STRIP}" << LLVMSTRIPTRICK
#!/bin/bash
echo "\${2}" | grep -q Debug ||
"${ANDROID_NDK_LLVM_STRIP}.back" --strip-all "\${2}"
LLVMSTRIPTRICK
## Eventually you can revert back simply by running
# `mv "${ANDROID_NDK_LLVM_STRIP}.back" "${ANDROID_NDK_LLVM_STRIP}"`
--------------------------------------------------------------------------------
To attach to the `retroshare-service` running on Android you need also to pull a
debugging sysroot out of your device first, RetroShare sources provides an
helper script to do that.
.Prepare debugging sysroot with helper script
[source,bash]
--------------------------------------------------------------------------------
## Set RetroShare source path
export RS_SOURCE_DIR="${HOME}/Development/rs-develop"
## Optionally set your device ID first available will be used, you can run
## `adb devices` to list available devices.
#export ANDROID_SERIAL="YT013PSPGK"
## Optionally set a path where to save the debugging sysroot otherwise default
## is used.
#export DEBUG_SYSROOT="${HOME}/Builds/debug_sysroot/${ANDROID_SERIAL}/"
## Run the helper script
${RS_SOURCE_DIR}/build_scripts/Android/pull_sysroot.sh
--------------------------------------------------------------------------------
.Prepare Android NDK GDB configurations
[source,bash]
--------------------------------------------------------------------------------
## Optionally set Qt version variable consistently with your installation
export QT_VERSION="5.12.7"
## Optionally set Qt architecture variable consistently with Android device
export QT_ARCH="arm64_v8a"
## Optionally set Qt path variable consistently with your installation
export QT_DIR="/opt/Qt-${QT_VERSION}/${QT_VERSION}/"
## Optionally set RetroShare buildroot path
export RS_BUILD_DIR="${HOME}/Builds/RetroShare-Android_for_${QT_ARCH}_Clang_Qt_${QT_VERSION//./_}_android_${QT_ARCH}-Debug/"
## Optionally set gdb config file path
export GDB_CONFIGS_FILE="${HOME}/Builds/gdb_configs_${QT_ARCH}"
## Generate Android NDK GDB configuration
${RS_SOURCE_DIR}/build_scripts/Android/generate_gdb_init_commands.sh
--------------------------------------------------------------------------------
You will need to run the following steps everytime you want to debug
`retroshare-service` on Android.
Make sure `retroshare-service` is running on your connected Android device.
.Run GDB server on your Android device from your host console
[source,bash]
--------------------------------------------------------------------------------
${RS_SOURCE_DIR}/build_scripts/Android/start_gdbserver.sh
--------------------------------------------------------------------------------
.Run Android NDK GDB on your workstation and attach
[source,bash]
--------------------------------------------------------------------------------
## Start NDK gdb
${ANDROID_NDK_PATH}/prebuilt/linux-x86_64/bin/gdb
## Instruct GDB how and where to find debugging symbols
(gdb) source $GDB_CONFIGS_FILE
## Connect to the gdbserver running on the phone
(gdb) target remote 127.0.01:5039
## Have fun debugging
(gdb)
--------------------------------------------------------------------------------
== Debugging with Qt Creator
WARNING: As of the last update to this guide, debugging retroshare-service
running on Android via Qt creator doesn't wrok even with all the trickery
explained in this section, you better learn how to debug with GDB reading
carefully previous section.
Qt Creator actually support debugging only for the foreground activity, so to
debug what's happening in the core extra trickery is needed.
- Run the App in Debug mode from QtCreator "Start Debugging" button
- Enable QtCreator debugger console view Menu->Window->Debugger Log
- Run +show solib-search-path+ in the QtCreator GDB console
- Take note of the output you get in the right pane of the console
- Thanks https://stackoverflow.com/a/31164313 for the idea
TIP: QtCreator GDB console seems a bit buggy and easly trigger timeout
message when a command is run, in that case attempt to run the command while the
debugging is paused or at breakpoint, or with other similar tricks.
CAUTION: Following steps require root access on your Android device
Now on your phone yuo need to authorize root access to applications, then once
you plug your sacrifical Android phone run this commands
.Run gdbserver as root on Android phone
[source,bash]
--------------------------------------------------------------------------------
## Open a shell from your workstation on the connected Android phone
adb shell
## take the note of the phone IP address
ip address show
## Gain root permissions on the shell
su
## Attach with gdbserver and listen on one TCP port
gdbserver :4567 --attach $(pgrep org.retroshare.android.qml_app:rs)
--------------------------------------------------------------------------------
.Prepare and run Android NDK GDB on your workstation
[source,bash]
--------------------------------------------------------------------------------
## Setup some convenience variables
NDK_GDB="${ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gdb"
RS_BUILD_PATH="${HOME}/Builds/RetroShare-Android_for_armeabi_v7a_GCC_4_9_Qt_5_9_2_android_armv7-Debug/"
## Start Android NDK GDB of your phone architecture passing the executable
$NDK_GDB $RS_BUILD_PATH/retroshare-android-service/src/libretroshare-android-service.so
## Instruct GDB how and where to find debugging symbols
(gdb) set auto-solib-add on
(gdb) set solib-search-path THE:BIG:LIST:OF:DIRECTORIES:YOU:TAKE:NOTE:BEFORE
## Connect to the gdbserver running on the phone
(gdb) target remote $PHONE_IP:4567
## Have fun debugging
(gdb)
--------------------------------------------------------------------------------
TIP: Some time WiFi power saving on Android mess with the GDB connection,
to prevent that from appening open another +adb shell+ and live +ping+ toward
your work-station running
== Embedding into other Android packages
As showed by https://elrepo.io/[elRepo.io] developers it is possible and quite
easy to embed `retroshare-service` into other Android packages see description
https://gitlab.com/elRepo.io/elRepo.io-android/-/blob/master/README.adoc
And implementation details
https://gitlab.com/elRepo.io/elRepo.io-android/-/blob/master/android/app/build.gradle
== Furter Readings
- link:http://doc.qt.io/qt-5/android-support.html[]
- link:https://developer.android.com/ndk/guides/libs.html[]
- link:retroshare://forum?name=Compiling%20nogui%20for%20android&id=8fd22bd8f99754461e7ba1ca8a727995&msgid=4e0f92330600bba9cf978f384f4b7b2f2ca64eff[]
- link:retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136[]
- link:https://groups.google.com/forum/#!topic/android-developers/srATPaL0aRU[]
- link:https://stackoverflow.com/questions/31638986/protected-apps-setting-on-huawei-phones-and-how-to-handle-it[]
- link:https://tthtlc.wordpress.com/2012/09/19/how-to-do-remote-debugging-via-gdbserver-running-inside-the-android-phone/[]
- link:https://source.android.com/devices/tech/debug/[]
- link:https://source.android.com/devices/tech/debug/gdb[]
- link:https://fw4spl-org.github.io/fw4spl-blog/2015/07/27/Native-debugging-on-Android-with-QtCreator.html[]
- link:https://fragglet.livejournal.com/19646.html[]
- link:https://github.com/android-ndk/ndk/issues/773[How to build without using standalone toolchain?]
== License
Copyright (C) 2016-2021 Gioacchino Mazzurco <gio@eigenlab.org> +
Copyright (C) 2020-2021 Asociación Civil Altermundi <info@altermundi.net> +
This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.
image::https://i.creativecommons.org/l/by-sa/4.0/88x31.png[Creative Commons License, link=http://creativecommons.org/licenses/by-sa/4.0/]

View file

@ -0,0 +1,85 @@
#!/bin/bash
# Script to prepare Android NDK GDB configurations to debug retroshare-service
#
# Copyright (C) 2020 Gioacchino Mazzurco <gio@eigenlab.org>
# Copyright (C) 2020 Asociación Civil Altermundi <info@altermundi.net>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the
# Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>
## Define default value for variable, take two arguments, $1 variable name,
## $2 default variable value, if the variable is not already define define it
## with default value.
function define_default_value()
{
VAR_NAME="${1}"
DEFAULT_VALUE="${2}"
[ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}"
}
define_default_value QT_VERSION "5.12.4"
define_default_value QT_ARCH "arm64_v8a"
define_default_value QT_DIR "/opt/Qt-${QT_VERSION}/${QT_VERSION}/"
define_default_value ANDROID_SERIAL "$(adb devices | head -n 2 | tail -n 1 | awk '{print $1}')"
define_default_value RS_BUILD_DIR "${HOME}/Builds/RetroShare-Android_for_${QT_ARCH}_Clang_Qt_${QT_VERSION//./_}_android_${QT_ARCH}-Debug/"
define_default_value RS_SOURCE_DIR "${HOME}/Development/rs-develop/"
define_default_value DEBUG_SYSROOT "${HOME}/Builds/debug_sysroot/${ANDROID_SERIAL}/"
define_default_value GDB_CONFIGS_FILE "${HOME}/Builds/gdb_configs_${QT_ARCH}"
scanDir()
{
find "$1" -type d -not -path '*/\.git/*' | tr '\n' ':' >> $GDB_CONFIGS_FILE
}
putSeparator()
{
echo >> $GDB_CONFIGS_FILE
echo >> $GDB_CONFIGS_FILE
}
echo "set sysroot ${DEBUG_SYSROOT}" > $GDB_CONFIGS_FILE
putSeparator
echo "set auto-solib-add on" >> $GDB_CONFIGS_FILE
echo -n "set solib-search-path " >> $GDB_CONFIGS_FILE
scanDir "${RS_BUILD_DIR}"
scanDir "${DEBUG_SYSROOT}"
scanDir "${QT_DIR}/android_${QT_ARCH}/lib/"
scanDir "${QT_DIR}/android_${QT_ARCH}/plugins/"
scanDir "${QT_DIR}/android_${QT_ARCH}/qml/"
putSeparator
echo -n "directory " >> $GDB_CONFIGS_FILE
scanDir ${RS_SOURCE_DIR}/jsonapi-generator/src
scanDir ${RS_SOURCE_DIR}/libbitdht/src
scanDir ${RS_SOURCE_DIR}/openpgpsdk/src
scanDir ${RS_SOURCE_DIR}/libretroshare/src
scanDir ${RS_SOURCE_DIR}/retroshare-service/src
scanDir ${RS_SOURCE_DIR}/supportlibs/rapidjson/include/
scanDir ${RS_SOURCE_DIR}/supportlibs/restbed/source/
scanDir ${RS_SOURCE_DIR}/supportlibs/udp-discovery-cpp/
scanDir ${RS_SOURCE_DIR}/supportlibs/restbed/dependency/asio/asio/include/
scanDir ${RS_SOURCE_DIR}/supportlibs/restbed/dependency/catch/include/
putSeparator
## see https://stackoverflow.com/questions/28972367/gdb-backtrace-without-stopping
echo "catch signal SIGSEGV" >> $GDB_CONFIGS_FILE
echo "commands
bt
continue
end" >> $GDB_CONFIGS_FILE
putSeparator
echo GDB_CONFIGS_FILE=$GDB_CONFIGS_FILE

View file

@ -0,0 +1,920 @@
#!/bin/bash
# Script to prepare RetroShare Android package building toolchain
#
# Copyright (C) 2016-2021 Gioacchino Mazzurco <gio@eigenlab.org>
# Copyright (C) 2020-2021 Asociación Civil Altermundi <info@altermundi.net>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the
# Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>
#
# SPDX-FileCopyrightText: Retroshare Team <contact@retroshare.cc>
# SPDX-License-Identifier: AGPL-3.0-only
## Define default value for variable, take two arguments, $1 variable name,
## $2 default variable value, if the variable is not already define define it
## with default value.
function define_default_value()
{
VAR_NAME="${1}"
DEFAULT_VALUE="${2}"
[ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" || true
}
## You are supposed to provide the following variables according to your system setup
define_default_value ANDROID_NDK_PATH "/opt/android-ndk/"
define_default_value ANDROID_NDK_ARCH "arm"
define_default_value ANDROID_PLATFORM_VER "16"
define_default_value NATIVE_LIBS_TOOLCHAIN_PATH "${HOME}/Builds/android-toolchains/retroshare-android-${ANDROID_PLATFORM_VER}-${ANDROID_NDK_ARCH}/"
define_default_value HOST_NUM_CPU $(nproc)
define_default_value ANDROID_SDK_INSTALL "false"
define_default_value ANDROID_SDK_TOOLS_VERSION "3859397"
define_default_value ANDROID_SDK_TOOLS_SHA256 444e22ce8ca0f67353bda4b85175ed3731cae3ffa695ca18119cbacef1c1bea0
define_default_value ANDROID_SDK_VERSION "29.0.3"
define_default_value ANDROID_NDK_INSTALL "false"
define_default_value ANDROID_NDK_VERSION "r21"
define_default_value ANDROID_NDK_SHA256 b65ea2d5c5b68fb603626adcbcea6e4d12c68eb8a73e373bbb9d23c252fc647b
define_default_value BZIP2_SOURCE_VERSION "1.0.6"
define_default_value BZIP2_SOURCE_SHA256 a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd
define_default_value OPENSSL_SOURCE_VERSION "1.1.1c"
define_default_value OPENSSL_SOURCE_SHA256 f6fb3079ad15076154eda9413fed42877d668e7069d9b87396d0804fdb3f4c90
define_default_value SQLITE_SOURCE_YEAR "2018"
define_default_value SQLITE_SOURCE_VERSION "3250200"
define_default_value SQLITE_SOURCE_SHA256 da9a1484423d524d3ac793af518cdf870c8255d209e369bd6a193e9f9d0e3181
define_default_value SQLCIPHER_SOURCE_VERSION "4.4.3"
define_default_value SQLCIPHER_SOURCE_SHA256 b8df69b998c042ce7f8a99f07cf11f45dfebe51110ef92de95f1728358853133
define_default_value LIBUPNP_SOURCE_VERSION "1.8.4"
define_default_value LIBUPNP_SOURCE_SHA256 976c3e4555604cdd8391ed2f359c08c9dead3b6bf131c24ce78e64d6669af2ed
define_default_value QT_ANDROID_VIA_INSTALLER "false"
define_default_value QT_VERSION "5.12.11"
define_default_value QT_INSTALLER_VERSION "4.1.1"
define_default_value QT_INSTALLER_SHA256 1266ffd0d1b0e466244e3bc8422975c1aa9d96745b6bb28d422f7f92df11f34c
define_default_value QT_INSTALLER_JWT_TOKEN ""
define_default_value QT_INSTALL_PATH "${NATIVE_LIBS_TOOLCHAIN_PATH}/Qt/"
define_default_value QT_ANDROID_INSTALLER_SHA256 a214084e2295c9a9f8727e8a0131c37255bf724bfc69e80f7012ba3abeb1f763
define_default_value RESTBED_SOURCE_REPO "https://github.com/Corvusoft/restbed.git"
define_default_value RESTBED_SOURCE_VERSION f74f9329dac82e662c1d570b7cd72c192b729eb4
define_default_value UDP_DISCOVERY_CPP_SOURCE "https://github.com/truvorskameikin/udp-discovery-cpp.git"
define_default_value UDP_DISCOVERY_CPP_VERSION "develop"
define_default_value XAPIAN_SOURCE_VERSION "1.4.7"
define_default_value XAPIAN_SOURCE_SHA256 13f08a0b649c7afa804fa0e85678d693fd6069dd394c9b9e7d41973d74a3b5d3
define_default_value RAPIDJSON_SOURCE_VERSION "1.1.0"
define_default_value RAPIDJSON_SOURCE_SHA256 bf7ced29704a1e696fbccf2a2b4ea068e7774fa37f6d7dd4039d0787f8bed98e
define_default_value MINIUPNPC_SOURCE_VERSION "2.1.20190625"
define_default_value MINIUPNPC_SOURCE_SHA256 8723f5d7fd7970de23635547700878cd29a5c2bb708b5e5475b2d1d2510317fb
# zlib and libpng versions walks toghether
define_default_value ZLIB_SOURCE_VERSION "1.2.11"
define_default_value ZLIB_SOURCE_SHA256 4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066
define_default_value LIBPNG_SOURCE_VERSION "1.6.37"
define_default_value LIBPNG_SOURCE_SHA256 505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca
define_default_value LIBJPEG_SOURCE_VERSION "9d"
define_default_value LIBJPEG_SOURCE_SHA256 6c434a3be59f8f62425b2e3c077e785c9ce30ee5874ea1c270e843f273ba71ee
define_default_value TIFF_SOURCE_VERSION "4.2.0"
define_default_value TIFF_SOURCE_SHA256 eb0484e568ead8fa23b513e9b0041df7e327f4ee2d22db5a533929dfc19633cb
define_default_value CIMG_SOURCE_VERSION "2.9.7"
define_default_value CIMG_SOURCE_SHA256 595dda9718431a123b418fa0db88e248c44590d47d9b1646970fa0503e27fa5c
define_default_value PHASH_SOURCE_REPO "https://gitlab.com/g10h4ck/pHash.git"
define_default_value PHASH_SOURCE_VERSION origin/android-ndk
define_default_value MVPTREE_SOURCE_REPO "https://github.com/starkdg/mvptree.git"
define_default_value MVPTREE_SOURCE_VERSION origin/master
define_default_value REPORT_DIR "$(pwd)/$(basename ${NATIVE_LIBS_TOOLCHAIN_PATH})_build_report/"
define_default_value RS_SRC_DIR "$(realpath $(dirname $BASH_SOURCE)/../../)"
cArch=""
eABI=""
cmakeABI=""
case "${ANDROID_NDK_ARCH}" in
"arm")
cArch="${ANDROID_NDK_ARCH}"
eABI="eabi"
;;
"arm64")
cArch="aarch64"
eABI=""
;;
"x86")
cArch="i686"
eABI=""
;;
"x86_64")
echo "ANDROID_NDK_ARCH=${ANDROID_NDK_ARCH} not supported yet"
exit -1
cArch="??"
eABI=""
esac
export SYSROOT="${NATIVE_LIBS_TOOLCHAIN_PATH}/sysroot/"
export PREFIX="${SYSROOT}/usr/"
export CC="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang"
export CXX="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang++"
export AR="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ar"
export RANLIB="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ranlib"
# Used to instruct cmake to explicitely ignore host libraries
export HOST_IGNORE_PREFIX="/usr/"
## $1 filename, $2 sha256 hash
function check_sha256()
{
echo ${2} "${1}" | sha256sum -c &> /dev/null
}
## $1 filename, $2 sha256 hash, $3 url
function verified_download()
{
FILENAME="$1"
SHA256="$2"
URL="$3"
check_sha256 "${FILENAME}" "${SHA256}" ||
{
rm -rf "${FILENAME}"
wget -O "${FILENAME}" "$URL" ||
{
echo "Failed downloading ${FILENAME} from $URL"
exit 1
}
check_sha256 "${FILENAME}" "${SHA256}" ||
{
echo "SHA256 mismatch for ${FILENAME} from ${URL} expected sha256 ${SHA256} got $(sha256sum ${FILENAME} | awk '{print $1}')"
exit 1
}
}
}
# This function is the result of reading and testing many many stuff be very
# careful editing it
function andro_cmake()
{
# Using android.toolchain.cmake as documented here
# https://developer.android.com/ndk/guides/cmake seens to break more things then
# it fixes :-\
cmakeProc=""
case "${ANDROID_NDK_ARCH}" in
"arm")
cmakeProc="armv7-a"
;;
"arm64")
cmakeProc="aarch64"
;;
"x86")
cmakeProc="i686"
;;
"x86_64")
cmakeProc="x86_64"
;;
*)
echo "Unhandled NDK architecture ${ANDROID_NDK_ARCH}"
exit -1
;;
esac
_hi="$HOST_IGNORE_PREFIX"
cmake \
-DCMAKE_SYSTEM_PROCESSOR=$cmakeProc \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_PREFIX_PATH="${PREFIX}" \
-DCMAKE_SYSTEM_PREFIX_PATH="${PREFIX}" \
-DCMAKE_INCLUDE_PATH="${PREFIX}/include" \
-DCMAKE_SYSTEM_INCLUDE_PATH="${PREFIX}/include" \
-DCMAKE_LIBRARY_PATH="${PREFIX}/lib" \
-DCMAKE_SYSTEM_LIBRARY_PATH="${PREFIX}/lib" \
-DCMAKE_INSTALL_PREFIX="${PREFIX}" \
-DCMAKE_IGNORE_PATH="$_hi/include;$_hi/lib;$_hi/lib64" \
$@
# It is probably ok to do not touch CMAKE_PROGRAM_PATH and
# CMAKE_SYSTEM_PROGRAM_PATH
}
function git_source_get()
{
sourceDir="$1" ; shift #$1
sourceRepo="$1" ; shift #$2
sourceVersion="$1" ; shift #$3
# extra paramethers are treated as submodules
[ -d "$sourceDir" ] &&
{
pushd "$sourceDir"
actUrl="$(git remote get-url origin)"
[ "$actUrl" != "$sourceRepo" ] && rm -rf "${sourceDir}"
popd
} || true
[ -d $sourceDir ] || git clone "$sourceRepo" "$sourceDir"
pushd $sourceDir
git fetch --all
git reset --hard ${sourceVersion}
while [ "$1" != "" ] ; do
git submodule update --init "$1"
pushd "$1"
git reset --hard
shift
popd
done
popd
}
declare -A TASK_REGISTER
function task_register()
{
TASK_REGISTER[$1]=true
}
function task_unregister()
{
# we may simply wipe them but we could benefit from keeping track of
# unregistered tasks too
TASK_REGISTER[$1]=false
}
function task_logfile()
{
echo "$REPORT_DIR/$1.log"
}
function task_run()
{
mTask="$1" ; shift
[ "${TASK_REGISTER[$mTask]}" != "true" ] &&
{
echo "Attempt to run not registered task $mTask $@"
return -1
}
logFile="$(task_logfile $mTask)"
if [ -f "$logFile" ] ; then
echo "Task $mTask already run more details at $logFile"
else
date | tee > "$logFile"
$mTask $@ |& tee --append "$logFile"
mRetval="${PIPESTATUS[0]}"
echo "Task $mTask return ${mRetval} more details at $logFile"
date | tee --append "$logFile"
return ${mRetval}
fi
}
function task_zap()
{
rm -f "$(task_logfile $1)"
}
DUPLICATED_INCLUDES_LIST_FILE="${REPORT_DIR}/duplicated_includes_list"
DUPLICATED_INCLUDES_DIR="${REPORT_DIR}/duplicated_includes/"
task_register install_android_sdk
install_android_sdk()
{
tFile="sdk-tools-linux-${ANDROID_SDK_TOOLS_VERSION}.zip"
verified_download "${tFile}" "${ANDROID_SDK_TOOLS_SHA256}" \
"https://dl.google.com/android/repository/${tFile}"
unzip "${tFile}"
mkdir -p "$ANDROID_SDK_PATH"
rm -rf "$ANDROID_SDK_PATH/tools/"
mv --verbose tools/ "$ANDROID_SDK_PATH/tools/"
# Install Android SDK
yes | $ANDROID_SDK_PATH/tools/bin/sdkmanager --licenses && \
$ANDROID_SDK_PATH/tools/bin/sdkmanager --update
$ANDROID_SDK_PATH/tools/bin/sdkmanager "platforms;android-$ANDROID_PLATFORM_VER"
$ANDROID_SDK_PATH/tools/bin/sdkmanager "build-tools;$ANDROID_SDK_VERSION"
}
task_register install_android_ndk
install_android_ndk()
{
tFile="android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip"
verified_download "${tFile}" "${ANDROID_NDK_SHA256}" \
"https://dl.google.com/android/repository/${tFile}"
unzip "${tFile}"
mkdir -p "$ANDROID_NDK_PATH"
rm -rf "$ANDROID_NDK_PATH"
mv --verbose "android-ndk-${ANDROID_NDK_VERSION}/" "$ANDROID_NDK_PATH/"
}
## More information available at https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.html
task_register bootstrap_toolchain
bootstrap_toolchain()
{
rm -rf "${NATIVE_LIBS_TOOLCHAIN_PATH}"
${ANDROID_NDK_PATH}/build/tools/make_standalone_toolchain.py --verbose \
--arch ${ANDROID_NDK_ARCH} --install-dir ${NATIVE_LIBS_TOOLCHAIN_PATH} \
--api ${ANDROID_PLATFORM_VER}
# Avoid problems with arm64 some libraries installing on lib64
ln -s "${PREFIX}/lib/" "${PREFIX}/lib64"
pushd "${PREFIX}/include/"
find . -not -type d > "${DUPLICATED_INCLUDES_LIST_FILE}"
popd
}
## This avoid <cmath> include errors due to -isystem and -I ordering issue
task_register deduplicate_includes
deduplicate_includes()
{
while read delFile ; do
mNewPath="${DUPLICATED_INCLUDES_DIR}/$delFile"
mkdir --verbose --parents "$(dirname "$mNewPath")"
mv --verbose "${PREFIX}/include/$delFile" "$mNewPath"
done < "${DUPLICATED_INCLUDES_LIST_FILE}"
}
task_register reduplicate_includes
reduplicate_includes()
{
pushd "${DUPLICATED_INCLUDES_DIR}"
find . -not -type d | while read delFile ; do
mv --verbose "${delFile}" "${PREFIX}/include/$delFile"
done
popd
}
# $1 optional prefix prepended only if return value is not empty
# $2 optional suffix appended only if return value is not empty
task_register get_qt_arch
get_qt_arch()
{
local QT_VERSION_COMP="$(echo $QT_VERSION | awk -F. '{print $1*1000000+$2*1000+$3}')"
local QT_ARCH=""
# Qt >= 5.15.0 ships all Android architectures toghether
[ "$QT_VERSION_COMP" -lt "5015000" ] &&
{
case "${ANDROID_NDK_ARCH}" in
"arm")
QT_ARCH="armv7"
;;
"arm64")
QT_ARCH="arm64_v8a"
;;
"x86")
QT_ARCH="x86"
;;
esac
echo "$1$QT_ARCH$2"
}
}
task_register get_qt_dir
get_qt_dir()
{
echo "${QT_INSTALL_PATH}/${QT_VERSION}/android$(get_qt_arch _)/"
}
## More information available at https://wiki.qt.io/Online_Installer_4.x
task_register install_qt_android
install_qt_android()
{
[ "$QT_INSTALLER_JWT_TOKEN" == "" ] &&
{
echo "To run Qt installer QT_INSTALLER_JWT_TOKEN environement variable \
need to be set to a valid JWT token see https://wiki.qt.io/Online_Installer_4.x"
return -1
}
QT_VERSION_CODE="$(echo $QT_VERSION | tr -d .)"
QT_INSTALLER="qt-unified-linux-x86_64-${QT_INSTALLER_VERSION}-online.run"
tMajDotMinVer="$(echo $QT_INSTALLER_VERSION | awk -F. '{print $1"."$2}')"
verified_download $QT_INSTALLER $QT_INSTALLER_SHA256 \
"https://master.qt.io/archive/online_installers/${tMajDotMinVer}/${QT_INSTALLER}"
chmod a+x ${QT_INSTALLER}
QT_QPA_PLATFORM=minimal ./${QT_INSTALLER} \
install qt.qt5.${QT_VERSION_CODE}.android$(get_qt_arch _) \
--accept-licenses --accept-obligations --confirm-command \
--default-answer --no-default-installations \
--root "${QT_INSTALL_PATH}"
}
## More information available at retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136
task_register build_bzlib
build_bzlib()
{
B_dir="bzip2-${BZIP2_SOURCE_VERSION}"
rm -rf $B_dir
verified_download $B_dir.tar.gz $BZIP2_SOURCE_SHA256 \
http://distfiles.gentoo.org/distfiles/bzip2-${BZIP2_SOURCE_VERSION}.tar.gz
tar -xf $B_dir.tar.gz
cd $B_dir
sed -i "/^CC=.*/d" Makefile
sed -i "/^AR=.*/d" Makefile
sed -i "/^RANLIB=.*/d" Makefile
sed -i "/^LDFLAGS=.*/d" Makefile
sed -i "s/^all: libbz2.a bzip2 bzip2recover test/all: libbz2.a bzip2 bzip2recover/" Makefile
make -j${HOST_NUM_CPU}
make install PREFIX=${PREFIX}
# sed -i "/^CC=.*/d" Makefile-libbz2_so
# make -f Makefile-libbz2_so -j${HOST_NUM_CPU}
# cp libbz2.so.1.0.6 ${SYSROOT}/usr/lib/libbz2.so
cd ..
}
## More information available at http://doc.qt.io/qt-5/opensslsupport.html
task_register build_openssl
build_openssl()
{
B_dir="openssl-${OPENSSL_SOURCE_VERSION}"
rm -rf $B_dir
verified_download $B_dir.tar.gz $OPENSSL_SOURCE_SHA256 \
https://www.openssl.org/source/$B_dir.tar.gz
tar -xf $B_dir.tar.gz
cd $B_dir
## We link openssl statically to avoid android silently sneaking in his own
## version of libssl.so (we noticed this because it had some missing symbol
## that made RS crash), the crash in some android version is only one of the
## possible problems the fact that android insert his own binary libssl.so pose
## non neglegible security concerns.
oBits="32"
[[ ${ANDROID_NDK_ARCH} =~ .*64.* ]] && oBits=64
ANDROID_NDK="${ANDROID_NDK_PATH}" PATH="${SYSROOT}/bin/:${PATH}" \
./Configure linux-generic${oBits} -fPIC --prefix="${PREFIX}" \
--openssldir="${SYSROOT}/etc/ssl"
# sed -i 's/LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \\/LIBNAME=$$i \\/g' Makefile
# sed -i '/LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \\/d' Makefile
# Avoid documentation build which is unneded and time consuming
echo "exit 0; " > util/process_docs.pl
make -j${HOST_NUM_CPU}
make install
rm -f ${PREFIX}/lib/libssl.so*
rm -f ${PREFIX}/lib/libcrypto.so*
cd ..
}
task_register build_sqlite
build_sqlite()
{
B_dir="sqlite-autoconf-${SQLITE_SOURCE_VERSION}"
rm -rf $B_dir
verified_download $B_dir.tar.gz $SQLITE_SOURCE_SHA256 \
https://www.sqlite.org/${SQLITE_SOURCE_YEAR}/$B_dir.tar.gz
tar -xf $B_dir.tar.gz
cd $B_dir
./configure --with-pic --prefix="${PREFIX}" --host=${cArch}-linux
make -j${HOST_NUM_CPU}
make install
rm -f ${PREFIX}/lib/libsqlite3.so*
cd ..
}
task_register build_sqlcipher
build_sqlcipher()
{
task_run build_sqlite
B_dir="sqlcipher-${SQLCIPHER_SOURCE_VERSION}"
rm -rf $B_dir
T_file="${B_dir}.tar.gz"
verified_download $T_file $SQLCIPHER_SOURCE_SHA256 \
https://github.com/sqlcipher/sqlcipher/archive/v${SQLCIPHER_SOURCE_VERSION}.tar.gz
tar -xf $T_file
cd $B_dir
# case "${ANDROID_NDK_ARCH}" in
# "arm64")
# # SQLCipher config.sub is outdated and doesn't recognize newer architectures
# rm config.sub
# autoreconf --verbose --install --force
# automake --add-missing --copy --force-missing
# ;;
# esac
./configure --with-pic --build=$(sh ./config.guess) \
--host=${cArch}-linux \
--prefix="${PREFIX}" --with-sysroot="${SYSROOT}" \
--enable-tempstore=yes \
--disable-tcl --disable-shared \
CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="${PREFIX}/lib/libcrypto.a"
make -j${HOST_NUM_CPU}
make install
cd ..
}
task_register build_libupnp
build_libupnp()
{
B_dir="pupnp-release-${LIBUPNP_SOURCE_VERSION}"
B_ext=".tar.gz"
B_file="${B_dir}${B_ext}"
rm -rf $B_dir
verified_download $B_file $LIBUPNP_SOURCE_SHA256 \
https://github.com/mrjimenez/pupnp/archive/release-${LIBUPNP_SOURCE_VERSION}${B_ext}
tar -xf $B_file
cd $B_dir
./bootstrap
## liupnp must be configured as static library because if not the linker will
## look for libthreadutils.so.6 at runtime that cannot be packaged on android
## as it supports only libname.so format for libraries, thus resulting in a
## crash at startup.
./configure --with-pic --enable-static --disable-shared --disable-samples \
--disable-largefile \
--prefix="${PREFIX}" --host=${cArch}-linux
make -j${HOST_NUM_CPU}
make install
cd ..
}
task_register build_rapidjson
build_rapidjson()
{
B_dir="rapidjson-${RAPIDJSON_SOURCE_VERSION}"
D_file="${B_dir}.tar.gz"
verified_download $D_file $RAPIDJSON_SOURCE_SHA256 \
https://github.com/Tencent/rapidjson/archive/v${RAPIDJSON_SOURCE_VERSION}.tar.gz
tar -xf $D_file
cp -r "${B_dir}/include/rapidjson/" "${PREFIX}/include/rapidjson"
}
task_register build_restbed
build_restbed()
{
S_dir="restbed"
B_dir="${S_dir}-build"
git_source_get "$S_dir" "$RESTBED_SOURCE_REPO" "${RESTBED_SOURCE_VERSION}" \
"dependency/asio" "dependency/catch"
rm -rf "$B_dir"; mkdir "$B_dir"
pushd "$B_dir"
andro_cmake -DBUILD_TESTS=OFF -DBUILD_SSL=OFF -B. -H../${S_dir}
make -j${HOST_NUM_CPU}
make install
popd
}
task_register build_udp-discovery-cpp
build_udp-discovery-cpp()
{
S_dir="udp-discovery-cpp"
[ -d $S_dir ] || git clone $UDP_DISCOVERY_CPP_SOURCE $S_dir
cd $S_dir
git checkout $UDP_DISCOVERY_CPP_VERSION
cd ..
B_dir="udp-discovery-cpp-build"
rm -rf ${B_dir}; mkdir ${B_dir}; cd ${B_dir}
andro_cmake -B. -H../$S_dir
make -j${HOST_NUM_CPU}
cp libudp-discovery.a "${PREFIX}/lib/"
cp ../$S_dir/*.hpp "${PREFIX}/include/"
cd ..
}
task_register build_xapian
build_xapian()
{
B_dir="xapian-core-${XAPIAN_SOURCE_VERSION}"
D_file="$B_dir.tar.xz"
verified_download $D_file $XAPIAN_SOURCE_SHA256 \
https://oligarchy.co.uk/xapian/${XAPIAN_SOURCE_VERSION}/$D_file
rm -rf $B_dir
tar -xf $D_file
cd $B_dir
B_endiannes_detection_failure_workaround="ac_cv_c_bigendian=no"
B_large_file=""
[ "${ANDROID_PLATFORM_VER}" -lt "24" ] && B_large_file="--disable-largefile"
./configure ${B_endiannes_detection_failure_workaround} ${B_large_file} \
--with-pic \
--disable-backend-inmemory --disable-backend-remote \
--disable--backend-chert --enable-backend-glass \
--host=${cArch}-linux --enable-static --disable-shared \
--prefix="${PREFIX}" --with-sysroot="${SYSROOT}"
make -j${HOST_NUM_CPU}
make install
cd ..
}
task_register build_miniupnpc
build_miniupnpc()
{
S_dir="miniupnpc-${MINIUPNPC_SOURCE_VERSION}"
B_dir="miniupnpc-${MINIUPNPC_SOURCE_VERSION}-build"
D_file="$S_dir.tar.gz"
verified_download $D_file $MINIUPNPC_SOURCE_SHA256 \
http://miniupnp.free.fr/files/${D_file}
rm -rf $S_dir $B_dir
tar -xf $D_file
mkdir $B_dir
cd $B_dir
andro_cmake \
-DUPNPC_BUILD_STATIC=TRUE \
-DUPNPC_BUILD_SHARED=FALSE \
-DUPNPC_BUILD_TESTS=FALSE \
-DUPNPC_BUILD_SAMPLE=FALSE \
-B. -S../$S_dir
make -j${HOST_NUM_CPU}
make install
cd ..
}
task_register build_zlib
build_zlib()
{
S_dir="zlib-${ZLIB_SOURCE_VERSION}"
B_dir="zlib-${ZLIB_SOURCE_VERSION}-build"
D_file="$S_dir.tar.xz"
verified_download $D_file $ZLIB_SOURCE_SHA256 \
http://www.zlib.net/${D_file}
rm -rf $S_dir $B_dir
tar -xf $D_file
mkdir $B_dir
cd $B_dir
andro_cmake -B. -S../$S_dir
make -j${HOST_NUM_CPU}
make install
rm -f ${PREFIX}/lib/libz.so*
cd ..
}
task_register build_libpng
build_libpng()
{
task_run build_zlib
S_dir="libpng-${LIBPNG_SOURCE_VERSION}"
B_dir="libpng-${LIBPNG_SOURCE_VERSION}-build"
D_file="$S_dir.tar.xz"
verified_download $D_file $LIBPNG_SOURCE_SHA256 \
https://download.sourceforge.net/libpng/${D_file}
rm -rf $S_dir $B_dir
tar -xf $D_file
# libm is part of bionic An android
sed -i -e 's/find_library(M_LIBRARY m)/set(M_LIBRARY "")/' $S_dir/CMakeLists.txt
# Disable hardware acceleration as they are problematic for Android
# compilation and are not supported by all phones, it is necessary to fiddle
# with CMakeLists.txt as libpng 1.6.37 passing it as cmake options seems not
# working properly
# https://github.com/imagemin/optipng-bin/issues/97
# https://github.com/opencv/opencv/issues/7600
echo "add_definitions(-DPNG_ARM_NEON_OPT=0)" >> $S_dir/CMakeLists.txt
mkdir $B_dir
pushd $B_dir
HW_OPT="OFF"
# [ "$ANDROID_PLATFORM_VER" -ge "22" ] && HW_OPT="ON"
andro_cmake \
-DPNG_SHARED=OFF \
-DPNG_STATIC=ON \
-DPNG_TESTS=OFF \
-DPNG_HARDWARE_OPTIMIZATIONS=$HW_OPT \
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
-B. -S../$S_dir
make -j${HOST_NUM_CPU}
make install
popd
}
task_register build_libjpeg
build_libjpeg()
{
S_dir="jpeg-${LIBJPEG_SOURCE_VERSION}"
D_file="jpegsrc.v${LIBJPEG_SOURCE_VERSION}.tar.gz"
verified_download $D_file $LIBJPEG_SOURCE_SHA256 \
https://www.ijg.org/files/$D_file
rm -rf $S_dir
tar -xf $D_file
cd $S_dir
./configure --with-pic --prefix="${PREFIX}" --host=${cArch}-linux
make -j${HOST_NUM_CPU}
make install
rm -f ${PREFIX}/lib/libjpeg.so*
cd ..
}
task_register build_tiff
build_tiff()
{
S_dir="tiff-${TIFF_SOURCE_VERSION}"
B_dir="${S_dir}-build"
D_file="tiff-${TIFF_SOURCE_VERSION}.tar.gz"
verified_download $D_file $TIFF_SOURCE_SHA256 \
https://download.osgeo.org/libtiff/${D_file}
rm -rf $S_dir $B_dir
tar -xf $D_file
mkdir $B_dir
# Disable tools building, not needed for retroshare, and depending on some
# OpenGL headers not available on Android
echo "" > $S_dir/tools/CMakeLists.txt
# Disable tests building, not needed for retroshare, and causing linker
# errors
echo "" > $S_dir/test/CMakeLists.txt
# Disable extra tools building, not needed for retroshare, and causing
# linker errors
echo "" > $S_dir/contrib/CMakeLists.txt
# Disable more unneded stuff
echo "" > $S_dir/build/CMakeLists.txt
echo "" > $S_dir/html/CMakeLists.txt
echo "" > $S_dir/man/CMakeLists.txt
echo "" > $S_dir/port/CMakeLists.txt
# Change to static library build
sed -i 's\add_library(tiff\add_library(tiff STATIC\' \
$S_dir/libtiff/CMakeLists.txt
cd $B_dir
#TODO: build dependecies to support more formats
andro_cmake \
-Dlibdeflate=OFF -Djbig=OFF -Dlzma=OFF -Dzstd=OFF -Dwebp=OFF \
-Djpeg12=OFF \
-Dcxx=OFF \
-B. -S../$S_dir
make -j${HOST_NUM_CPU}
make install
cd ..
}
task_register build_cimg
build_cimg()
{
task_run build_libpng
task_run build_libjpeg
task_run build_tiff
S_dir="CImg-${CIMG_SOURCE_VERSION}"
D_file="CImg_${CIMG_SOURCE_VERSION}.zip"
verified_download $D_file $CIMG_SOURCE_SHA256 \
https://cimg.eu/files/${D_file}
unzip -o $D_file
cp --archive --verbose "$S_dir/CImg.h" "$PREFIX/include/"
}
task_register build_phash
build_phash()
{
task_run build_cimg
S_dir="pHash"
B_dir="${S_dir}-build"
git_source_get "$S_dir" "$PHASH_SOURCE_REPO" "${PHASH_SOURCE_VERSION}"
rm -rf $B_dir; mkdir $B_dir ; pushd $B_dir
andro_cmake -DPHASH_DYNAMIC=OFF -DPHASH_STATIC=ON -B. -H../pHash
make -j${HOST_NUM_CPU}
make install
popd
}
task_register fetch_jni_hpp
fetch_jni_hpp()
{
local rDir="supportlibs/jni.hpp/"
[ "$(ls "${RS_SRC_DIR}/${rDir}" | wc -l)" -gt "4" ] ||
git -C ${RS_SRC_DIR} submodule update --init ${rDir}
}
task_register build_mvptree
build_mvptree()
{
S_dir="mvptree"
B_dir="${S_dir}-build"
git_source_get "$S_dir" "$MVPTREE_SOURCE_REPO" "${MVPTREE_SOURCE_VERSION}"
rm -rf $B_dir; mkdir $B_dir ; pushd $B_dir
andro_cmake -B. -H../${S_dir}
make -j${HOST_NUM_CPU}
make install
popd
}
task_register build_libretroshare
build_libretroshare()
{
S_dir="/home/gio/Development/rs-develop/libretroshare"
B_dir="libretroshare-build"
# -DCMAKE_SYSTEM_NAME="Android" \
# -DCMAKE_ANDROID_NDK="$ANDROID_NDK_PATH" \
# -DCMAKE_SYSTEM_VERSION=$ANDROID_PLATFORM_VER \
# -D RS_FORUM_DEEP_INDEX=ON -D RS_JSON_API=ON \
rm -rf $B_dir; mkdir $B_dir ; pushd $B_dir
andro_cmake -B. -H${S_dir} -DCMAKE_BUILD_TYPE=Release \
-D RS_ANDROID=ON -D RS_WARN_DEPRECATED=OFF -D RS_WARN_LESS=ON \
-D RS_LIBRETROSHARE_STATIC=OFF -D RS_LIBRETROSHARE_SHARED=ON \
-D RS_BRODCAST_DISCOVERY=ON -D RS_EXPORT_JNI_ONLOAD=ON
make -j${HOST_NUM_CPU}
make install
popd
}
task_register get_native_libs_toolchain_path
get_native_libs_toolchain_path()
{
echo ${NATIVE_LIBS_TOOLCHAIN_PATH}
}
task_register build_default_toolchain
build_default_toolchain()
{
task_run bootstrap_toolchain || return $?
task_run build_bzlib || return $?
task_run build_openssl || return $?
task_run build_sqlcipher || return $?
task_run build_rapidjson || return $?
# task_run build_restbed || return $?
# task_run build_udp-discovery-cpp || return $?
task_run build_xapian || return $?
task_run build_miniupnpc || return $?
task_run build_phash || return $?
# task_run fetch_jni_hpp || return $?
task_run build_libretroshare || return $?
# task_run deduplicate_includes || return $?
task_run get_native_libs_toolchain_path || return $?
}
if [ "$1" == "" ]; then
rm -rf "$REPORT_DIR"
mkdir -p "$REPORT_DIR"
cat "$0" > "$REPORT_DIR/build_script"
env > "$REPORT_DIR/build_env"
build_default_toolchain
else
# do not delete report directory in this case so we can reuse material
# produced by previous run, like deduplicated includes
mkdir -p "$REPORT_DIR"
while [ "$1" != "" ] ; do
task_zap $1
task_run $1 || exit $?
shift
done
fi

View file

@ -0,0 +1,90 @@
#!/bin/bash
# Script to pull debugging sysroot from Android devices
#
# Copyright (C) 2020 Gioacchino Mazzurco <gio@eigenlab.org>
# Copyright (C) 2020 Asociación Civil Altermundi <info@altermundi.net>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the
# Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>
<<"ASCIIDOC"
Pull files from Android device to prepare a debugging sysroot
Inspired by:
https://fw4spl-org.github.io/fw4spl-blog/2015/07/27/Native-debugging-on-Android-with-QtCreator.html
The goal is to have a local copy of the sysroot of the connected device.
For that we use the command `adb pull <remote_dir_or_file> <local_dir_or_file>`
We will get a copy of:
- `/system/lib/`
- `/vendor/lib/`
- `libc.so`
- `libcutils.so`
As well as the binaries `linker` and `app_process`
IMPORTANT:
from one device to another, the remote file `app_process` can be a binary file
or a symlink to a binary file - which is NOT ok for us.
That's so we will try to pull every known possible variants of `app_process`,
e.g. `app_process32` or `app_process_init`
ASCIIDOC
## Define default value for variable, take two arguments, $1 variable name,
## $2 default variable value, if the variable is not already define define it
## with default value.
function define_default_value()
{
VAR_NAME="${1}"
DEFAULT_VALUE="${2}"
[ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}"
}
define_default_value ANDROID_SERIAL "$(adb devices | head -n 2 | tail -n 1 | awk '{print $1}')"
define_default_value DEBUG_SYSROOT "${HOME}/Builds/debug_sysroot/${ANDROID_SERIAL}/"
rm -rf "${DEBUG_SYSROOT}"
for mDir in "/system/lib/" "/vendor/lib/"; do
mkdir -p "${DEBUG_SYSROOT}/${mDir}"
# adb pull doesn't behave like rsync dirA/ dirB/ so avoid nesting the
# directory by deleting last one before copying
rmdir "${DEBUG_SYSROOT}/${mDir}"
adb pull "${mDir}" "${DEBUG_SYSROOT}/${mDir}"
done
# Retrieve the specific binaries - some of these adb commands will fail, since
# some files may not exist, but that's ok.
mkdir -p "${DEBUG_SYSROOT}/system/bin/"
for mBin in "/system/bin/linker" "/system/bin/app_process" \
"/system/bin/app_process_init" "/system/bin/app_process32" \
"/system/bin/app_process64" ; do
adb pull "${mBin}" "${DEBUG_SYSROOT}/${mBin}"
done
# Verify which variants of the specific binaries could be pulled
echo
echo "Found the following specific binaries:"
echo
ls -1 "${DEBUG_SYSROOT}/system/bin/"*
ls -1 "${DEBUG_SYSROOT}/system/lib/libc.so"*
ls -1 "${DEBUG_SYSROOT}/system/lib/libcutils.so"*
echo
echo DEBUG_SYSROOT="${DEBUG_SYSROOT}"

View file

@ -0,0 +1,116 @@
#!/bin/bash
# Script to start gdbserver on Android device and attach to retroshare-service
#
# Copyright (C) 2020 Gioacchino Mazzurco <gio@eigenlab.org>
# Copyright (C) 2020 Asociación Civil Altermundi <info@altermundi.net>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the
# Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>
<<"ASCIIDOC"
Start gdbserver on Android device and attach it to the retroshare service
process
Inspired by:
https://fw4spl-org.github.io/fw4spl-blog/2015/07/27/Native-debugging-on-Android-with-QtCreator.html
ASCIIDOC
## Define default value for variable, take two arguments, $1 variable name,
## $2 default variable value, if the variable is not already define define it
## with default value.
function define_default_value()
{
VAR_NAME="${1}"
DEFAULT_VALUE="${2}"
[ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" || true
}
define_default_value ANDROID_APK_PACKAGE "org.retroshare.service"
define_default_value ANDROID_PROCESS_NAME "org.retroshare.service:rs"
define_default_value ANDROID_INSTALL_PATH ""
define_default_value LIB_GDB_SERVER_PATH ""
define_default_value ANDROID_SERIAL "$(adb devices | head -n 2 | tail -n 1 | awk '{print $1}')"
define_default_value GDB_SERVER_PORT 5039
adb_ushell()
{
adb shell run-as ${ANDROID_APK_PACKAGE} $@
}
[ -z "${ANDROID_INSTALL_PATH}" ] &&
{
ANDROID_INSTALL_PATH="$(adb_ushell pm path "${ANDROID_APK_PACKAGE}")"
ANDROID_INSTALL_PATH="$(dirname ${ANDROID_INSTALL_PATH#"package:"})"
[ -z "${ANDROID_INSTALL_PATH}" ] &&
cat <<EOF
Cannot find install path for ${ANDROID_APK_PACKAGE} make sure it is installed,
or manually specify ANDROID_INSTALL_PATH
EOF
}
## If not passed as environement variable try to determine gdbserver path
## shipped withing APK
[ -z "${LIB_GDB_SERVER_PATH}" ] &&
{
for mUsualPath in \
"${ANDROID_INSTALL_PATH}/lib/libgdbserver.so" \
"${ANDROID_INSTALL_PATH}/lib/arm64/libgdbserver.so"
do
adb_ushell ls "${mUsualPath}" &&
export LIB_GDB_SERVER_PATH="${mUsualPath}" && break
done
}
[ -z "${LIB_GDB_SERVER_PATH}" ] &&
{
cat <<EOF
libgdbserver.so not found in any of the usual path attempting to look for it
with find, it will take a little more time. Take note of the discovered path and
define LIB_GDB_SERVER_PATH on your commandline at next run to avoid waiting
again.
EOF
tFile="$(mktemp)"
adb_ushell find ${ANDROID_INSTALL_PATH} -type f -name 'libgdbserver.so' | \
tee "${tFile}"
LIB_GDB_SERVER_PATH="$(head -n 1 "${tFile}")"
rm "${tFile}"
}
[ -z "${LIB_GDB_SERVER_PATH}" ] &&
{
echo "Cannot find libgdbserver.so, are you sure your package ships it?"
exit -1
}
mPid="$(adb_ushell ps | grep ${ANDROID_PROCESS_NAME} | awk '{print $2}')"
[ -z "${mPid}" ] &&
{
echo "Failed ${ANDROID_PROCESS_NAME} PID retrival are you sure it is running?"
exit -2
}
## Establish port forwarding so we can connect to gdbserver with gdb
adb forward tcp:${GDB_SERVER_PORT} tcp:${GDB_SERVER_PORT}
((adb_ushell ${LIB_GDB_SERVER_PATH} 127.0.0.1:${GDB_SERVER_PORT} --attach ${mPid})&)