aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2017-08-23 21:19:23 +0200
committerRiccardo Spagni <ric@spagni.net>2017-08-23 21:19:24 +0200
commit1ce573afe230ff166e31564f642455b7042c660f (patch)
tree93731da5e48c2de4d8cbb8056b4b463757377e77
parentc68c31777693ae75b59c0d24c44195a97bbf0c1c (diff)
parent6730b63018b6486a082afb9e3761b19665f50e86 (diff)
downloadmonzero-gui-1ce573afe230ff166e31564f642455b7042c660f.tar.gz
monzero-gui-1ce573afe230ff166e31564f642455b7042c660f.tar.xz
monzero-gui-1ce573afe230ff166e31564f642455b7042c660f.zip
Merge pull request #786
6730b63 Add dockerfile for android NDK build (MoroccanMalinois)
-rw-r--r--android/README.md53
-rw-r--r--android/docker/Dockerfile108
-rw-r--r--android/docker/android.mk.patch61
-rw-r--r--android/docker/androiddeployqt.patch62
4 files changed, 284 insertions, 0 deletions
diff --git a/android/README.md b/android/README.md
new file mode 100644
index 00000000..b05c260a
--- /dev/null
+++ b/android/README.md
@@ -0,0 +1,53 @@
+Copyright (c) 2014-2017, The Monero Project
+
+
+## Current status : ALPHA
+
+ - Minimum Android 5.0 (api level 21)
+ - Modal dialogs can appear in background giving the feeling that the application is frozen (Work around : turn screen off/on or switch to another app and back)
+
+## Build using Docker
+
+# Base environnement
+
+ cd monero/utils/build_scripts
+ docker build -f android32.Dockerfile -t monero-android .
+ cd ..
+
+# Build GUI
+
+ cd android/docker
+ docker build -t monero-gui-android .
+ docker create -it --name monero-gui-android monero-gui-android bash
+
+# Get the apk
+
+ docker cp monero-gui-android:/opt/android/monero-core/build/release/bin/bin/QtApp-debug.apk .
+
+## Deployment
+
+- Using ADB (Android debugger bridge) :
+
+ First, see section [Enable adb debugging on your device](https://developer.android.com/studio/command-line/adb.html#Enabling)
+ The only place where we are allowed to play is `/data/local/tmp`. So :
+
+ adb push /opt/android/monero-core/build/release/bin/bin/QtApp-debug.apk /data/local/tmp
+ adb shell pm install -r /data/local/tmp/QtApp-debug.apk
+
+ - Troubleshooting:
+
+ adb devices -l
+ adb logcat
+
+ if using adb inside docker, make sure you did "docker run -v /dev/bus/usb:/dev/bus/usb --privileged"
+
+- Using a web server
+
+ mkdir /usr/tmp
+ cp QtApp-debug.apk /usr/tmp
+ docker run -d -v /usr/tmp:/usr/share/nginx/html:ro -p 8080:80 nginx
+
+ Now it should be accessible through a web browser at
+
+ http://<your.local.ip>:8080/QtApp-debug.apk
+
diff --git a/android/docker/Dockerfile b/android/docker/Dockerfile
new file mode 100644
index 00000000..5f1b1e53
--- /dev/null
+++ b/android/docker/Dockerfile
@@ -0,0 +1,108 @@
+FROM monero-android
+
+#INSTALL JAVA
+RUN echo "deb http://ftp.fr.debian.org/debian/ jessie-backports main contrib non-free" >> /etc/apt/sources.list
+RUN dpkg --add-architecture i386 \
+ && apt-get update \
+ && apt-get install -y libc6:i386 libncurses5:i386 libstdc++6:i386 libz1:i386 \
+ && apt-get install -y -t jessie-backports ca-certificates-java openjdk-8-jdk-headless openjdk-8-jre-headless ant
+ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
+ENV PATH $JAVA_HOME/bin:$PATH
+
+#Get Qt
+ENV QT_VERSION 5.8
+
+RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} \
+ && cd qt5 \
+ && perl init-repository
+
+## Note: Need to use libc++ but Qt does not provide mkspec for libc++.
+## Their support of it is quite recent and they claim they don't use it by default
+## [only because it produces bigger binary objects](https://bugreports.qt.io/browse/QTBUG-50724).
+
+#Create new mkspec for clang + libc++
+RUN cp -r qt5/qtbase/mkspecs/android-clang qt5/qtbase/mkspecs/android-clang-libc \
+ && cd qt5/qtbase/mkspecs/android-clang-libc \
+ && sed -i '16i ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH' qmake.conf \
+ && sed -i '17i ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include' qmake.conf \
+ && echo "QMAKE_LIBS_PRIVATE = -lc++_shared -llog -lz -lm -ldl -lc -lgcc " >> qmake.conf \
+ && echo "QMAKE_CFLAGS -= -mfpu=vfp " >> qmake.conf \
+ && echo "QMAKE_CXXFLAGS -= -mfpu=vfp " >> qmake.conf \
+ && echo "QMAKE_CFLAGS += -mfpu=vfp4 " >> qmake.conf \
+ && echo "QMAKE_CXXFLAGS += -mfpu=vfp4 " >> qmake.conf
+
+ENV ANDROID_API android-21
+
+#ANDROID SDK TOOLS
+RUN echo y | $ANDROID_SDK_ROOT/tools/android update sdk --no-ui --all --filter platform-tools
+RUN echo y | $ANDROID_SDK_ROOT/tools/android update sdk --no-ui --all --filter ${ANDROID_API}
+RUN echo y | $ANDROID_SDK_ROOT/tools/android update sdk --no-ui --all --filter build-tools-25.0.1
+
+ENV CLEAN_PATH $JAVA_HOME/bin:/usr/cmake-3.6.3-Linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+
+#build Qt
+RUN cd qt5 && PATH=${CLEAN_PATH} ./configure -developer-build -release \
+ -xplatform android-clang-libc \
+ -android-ndk-platform ${ANDROID_API} \
+ -android-ndk $ANDROID_NDK_ROOT \
+ -android-sdk $ANDROID_SDK_ROOT \
+ -opensource -confirm-license \
+ -prefix ${WORKDIR}/Qt-${QT_VERSION} \
+ -nomake tests -nomake examples \
+ -skip qtserialport \
+ -skip qtconnectivity \
+ -skip qttranslations \
+ -skip qtgamepad -skip qtscript -skip qtdoc
+
+# build Qt tools : gnustl_shared.so is hard-coded in androiddeployqt
+# replace it with libc++_shared.so
+COPY androiddeployqt.patch qt5/qttools/androiddeployqt.patch
+RUN cd qt5/qttools \
+ && git apply androiddeployqt.patch \
+ && cd .. \
+ && PATH=${CLEAN_PATH} make -j4 \
+ && PATH=${CLEAN_PATH} make install
+
+# Get iconv and ZBar
+ENV ICONV_VERSION 1.14
+RUN git clone https://github.com/ZBar/ZBar.git \
+ && curl -s -O http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz \
+ && tar -xzf libiconv-${ICONV_VERSION}.tar.gz \
+ && cd libiconv-${ICONV_VERSION} \
+ && CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ ./configure --build=x86_64-linux-gnu --host=arm-eabi --prefix=${WORKDIR}/libiconv --disable-rpath
+
+ENV PATH $ANDROID_SDK_ROOT/tools:$ANDROID_SDK_ROOT/platform-tools:${WORKDIR}/Qt-${QT_VERSION}/bin:$PATH
+
+#Build libiconv.a and libzbarjni.a
+COPY android.mk.patch ZBar/android.mk.patch
+RUN cd ZBar \
+ && git apply android.mk.patch \
+ && echo \
+"APP_ABI := armeabi-v7a \n\
+APP_STL := c++_shared \n\
+TARGET_PLATFORM := ${ANDROID_API} \n\
+TARGET_ARCH_ABI := armeabi-v7a \n\
+APP_CFLAGS += -target armv7-none-linux-androideabi -fexceptions -fstack-protector-strong -fno-limit-debug-info -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove -fno-omit-frame-pointer -fno-stack-protector\n"\
+ >> android/jni/Application.mk \
+ && cd android \
+ && android update project --path . -t "${ANDROID_API}" \
+ && CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ ant -Dndk.dir=${ANDROID_NDK_ROOT} -Diconv.src=${WORKDIR}/libiconv-${ICONV_VERSION} zbar-clean zbar-ndk-build
+
+#Can't directly call build.sh because of env variables
+RUN git clone https://github.com/monero-project/monero-core.git \
+ && cd monero-core \
+ && git submodule update \
+ && CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ BOOST_ROOT=/opt/android/boost_1_62_0 BOOST_LIBRARYDIR=${WORKDIR}/boost_${BOOST_VERSION}/android32/lib/ OPENSSL_ROOT_DIR=${WORKDIR}/openssl/ ./get_libwallet_api.sh release-android
+
+RUN cp openssl/lib* ${ANDROID_NDK_ROOT}/platforms/${ANDROID_API}/arch-arm/usr/lib
+RUN cp boost_${BOOST_VERSION}/android32/lib/lib* ${ANDROID_NDK_ROOT}/platforms/${ANDROID_API}/arch-arm/usr/lib
+RUN cp ZBar/android/obj/local/armeabi-v7a/lib* ${ANDROID_NDK_ROOT}/platforms/${ANDROID_API}/arch-arm/usr/lib
+
+ENV PATH $ANDROID_SDK_ROOT/tools:$ANDROID_SDK_ROOT/platform-tools:${WORKDIR}/Qt-${QT_VERSION}/bin:$CLEAN_PATH
+
+# NB : zxcvbn-c needs to build a local binary and Qt don't care about these environnement variable
+RUN cd monero-core \
+ && CC="gcc" CXX="g++" ./build.sh release-android \
+ && cd build \
+ && make deploy
+
diff --git a/android/docker/android.mk.patch b/android/docker/android.mk.patch
new file mode 100644
index 00000000..9fd7f172
--- /dev/null
+++ b/android/docker/android.mk.patch
@@ -0,0 +1,61 @@
+diff --git a/android/jni/Android.mk b/android/jni/Android.mk
+index e442b07..158afd5 100644
+--- a/android/jni/Android.mk
++++ b/android/jni/Android.mk
+@@ -12,14 +12,18 @@ LOCAL_PATH := $(ICONV_SRC)
+
+ LOCAL_MODULE := libiconv
+
++LOCAL_ARM_MODE := arm
++LOCAL_CPP_FEATURES := exceptions rtti features
+ LOCAL_CFLAGS := \
+ -Wno-multichar \
+ -D_ANDROID \
+- -DLIBDIR="c" \
++ -DLIBDIR="\".\"" \
+ -DBUILDING_LIBICONV \
+ -DBUILDING_LIBCHARSET \
+ -DIN_LIBRARY
+
++LOCAL_CFLAGS += -fno-stack-protector
++
+ LOCAL_SRC_FILES := \
+ lib/iconv.c \
+ libcharset/lib/localcharset.c \
+@@ -30,13 +34,14 @@ LOCAL_C_INCLUDES := \
+ $(ICONV_SRC)/libcharset \
+ $(ICONV_SRC)/libcharset/include
+
+-include $(BUILD_SHARED_LIBRARY)
++include $(BUILD_STATIC_LIBRARY)
+
+ LOCAL_LDLIBS := -llog -lcharset
+
+ # libzbarjni
+ include $(CLEAR_VARS)
+
++
+ LOCAL_PATH := $(MY_LOCAL_PATH)
+ LOCAL_MODULE := zbarjni
+ LOCAL_SRC_FILES := ../../java/zbarjni.c \
+@@ -71,6 +76,17 @@ LOCAL_C_INCLUDES := ../include \
+ ../zbar \
+ $(ICONV_SRC)/include
+
+-LOCAL_SHARED_LIBRARIES := libiconv
++LOCAL_STATIC_LIBRARIES := libiconv
++LOCAL_ARM_MODE := arm
++LOCAL_CPP_FEATURES := exceptions rtti features
++
++LOCAL_CFLAGS := \
++ -Wno-multichar \
++ -D_ANDROID \
++ -DLIBDIR="\".\"" \
++ -DBUILDING_LIBICONV \
++ -DBUILDING_LIBCHARSET \
++ -DIN_LIBRARY
++
+
+-include $(BUILD_SHARED_LIBRARY)
+\ No newline at end of file
++include $(BUILD_STATIC_LIBRARY)
diff --git a/android/docker/androiddeployqt.patch b/android/docker/androiddeployqt.patch
new file mode 100644
index 00000000..b0657677
--- /dev/null
+++ b/android/docker/androiddeployqt.patch
@@ -0,0 +1,62 @@
+diff --git a/src/androiddeployqt/main.cpp b/src/androiddeployqt/main.cpp
+index 8a8e591..71d693e 100644
+--- a/src/androiddeployqt/main.cpp
++++ b/src/androiddeployqt/main.cpp
+@@ -1122,7 +1122,7 @@ bool updateLibsXml(const Options &options)
+
+ QString libsPath = QLatin1String("libs/") + options.architecture + QLatin1Char('/');
+
+- QString qtLibs = QLatin1String("<item>gnustl_shared</item>\n");
++ QString qtLibs = QLatin1String("<item>c++_shared</item>\n");
+ QString bundledInLibs;
+ QString bundledInAssets;
+ foreach (Options::BundledFile bundledFile, options.bundledFiles) {
+@@ -2519,6 +2519,39 @@ bool installApk(const Options &options)
+ return true;
+ }
+
++bool copyStl(Options *options)
++{
++ if (options->deploymentMechanism == Options::Debug && !options->installApk)
++ return true;
++
++ if (options->verbose)
++ fprintf(stdout, "Copying LIBC++ STL library\n");
++
++ QString filePath = options->ndkPath
++ + QLatin1String("/sources/cxx-stl/llvm-libc++")
++ + QLatin1String("/libs/")
++ + options->architecture
++ + QLatin1String("/libc++_shared.so");
++ if (!QFile::exists(filePath)) {
++ fprintf(stderr, "LIBC STL library does not exist at %s\n", qPrintable(filePath));
++ return false;
++ }
++
++ QString destinationDirectory =
++ options->deploymentMechanism == Options::Debug
++ ? options->temporaryDirectoryName + QLatin1String("/lib")
++ : options->outputDirectory + QLatin1String("/libs/") + options->architecture;
++
++ if (!copyFileIfNewer(filePath, destinationDirectory
++ + QLatin1String("/libc++_shared.so"), options->verbose)) {
++ return false;
++ }
++
++ if (options->deploymentMechanism == Options::Debug && !deployToLocalTmp(options, QLatin1String("/lib/libc++_shared.so")))
++ return false;
++
++ return true;
++}
+ bool copyGnuStl(Options *options)
+ {
+ if (options->deploymentMechanism == Options::Debug && !options->installApk)
+@@ -2870,7 +2903,7 @@ int main(int argc, char *argv[])
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Read dependencies\n", options.timer.elapsed());
+
+- if (options.deploymentMechanism != Options::Ministro && !copyGnuStl(&options))
++ if (options.deploymentMechanism != Options::Ministro && !copyStl(&options))
+ return CannotCopyGnuStl;
+
+ if (Q_UNLIKELY(options.timing))