From 80abc3bc4a73f3ba6ffd40b1a03de0cc4d01e3c9 Mon Sep 17 00:00:00 2001 From: MoroccanMalinois Date: Thu, 5 Jan 2017 01:11:05 +0000 Subject: [PATCH] Build wallet with Android NDK --- CMakeLists.txt | 18 ++++++++++-- Makefile | 4 +++ cmake/test-static-assert.cpp | 34 ++++++++++++++++++++++ contrib/epee/include/console_handler.h | 2 +- external/db_drivers/liblmdb/CMakeLists.txt | 5 ++++ external/unbound/compat/getentropy_linux.c | 6 ++++ src/common/int-util.h | 14 ++++++++- src/crypto/CMakeLists.txt | 11 +++++++ src/crypto/oaes_lib.c | 6 ++-- src/crypto/slow-hash.c | 11 ++++++- 10 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 cmake/test-static-assert.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 87a53c36..3d325187 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -375,6 +375,13 @@ else() set(STATIC_ASSERT_FLAG "-Dstatic_assert=_Static_assert") endif() + try_compile(STATIC_ASSERT_CPP_RES "${CMAKE_CURRENT_BINARY_DIR}/static-assert" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-static-assert.cpp" COMPILE_DEFINITIONS "-std=c++11") + if(STATIC_ASSERT_CPP_RES) + set(STATIC_ASSERT_CPP_FLAG "") + else() + set(STATIC_ASSERT_CPP_FLAG "-Dstatic_assert=_Static_assert") + endif() + option(COVERAGE "Enable profiling for test coverage report" 0) if(COVERAGE) @@ -410,7 +417,7 @@ else() endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${ARCH_FLAG} ${COVERAGE_FLAGS} ${PIC_FLAG}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${ARCH_FLAG} ${COVERAGE_FLAGS} ${PIC_FLAG}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_CPP_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${ARCH_FLAG} ${COVERAGE_FLAGS} ${PIC_FLAG}") # With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that # is fixed in the code (Issue #847), force compiler to be conservative. @@ -494,6 +501,13 @@ else() endif(ARM) + if(ANDROID AND NOT BUILD_GUI_DEPS STREQUAL "ON") + #From Android 5: "only position independent executables (PIE) are supported" + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_CXX_FLAGS} -fPIE -pie") + endif() + if(APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_HAS_TR1_TUPLE=0") endif() @@ -580,7 +594,7 @@ endif() include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) if(MINGW) set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi) -elseif(APPLE OR FREEBSD OR OPENBSD) +elseif(APPLE OR FREEBSD OR OPENBSD OR ANDROID) set(EXTRA_LIBRARIES "") elseif(DRAGONFLY) find_library(COMPAT compat) diff --git a/Makefile b/Makefile index 777769f1..e6517eba 100644 --- a/Makefile +++ b/Makefile @@ -70,6 +70,10 @@ release-static-armv7: mkdir -p build/release cd build/release && cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release ../.. && $(MAKE) +release-static-android: + mkdir -p build/release + cd build/release && cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON ../.. && $(MAKE) + release-static-armv8: mkdir -p build/release cd build/release && cmake -D BUILD_TESTS=OFF -D ARCH="armv8-a" -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release ../.. && $(MAKE) diff --git a/cmake/test-static-assert.cpp b/cmake/test-static-assert.cpp new file mode 100644 index 00000000..0c6dfb15 --- /dev/null +++ b/cmake/test-static-assert.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2014-2016, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +static_assert(1, "FAIL"); +int main(int argc, char *argv[]) { + return 0; +} diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/console_handler.h index 2ad92b3f..554a4848 100644 --- a/contrib/epee/include/console_handler.h +++ b/contrib/epee/include/console_handler.h @@ -133,7 +133,7 @@ namespace epee bool wait_stdin_data() { #if !defined(WIN32) - #ifdef __OpenBSD__ + #if defined(__OpenBSD__) || defined(__ANDROID__) int stdin_fileno = fileno(stdin); #else int stdin_fileno = ::fileno(stdin); diff --git a/external/db_drivers/liblmdb/CMakeLists.txt b/external/db_drivers/liblmdb/CMakeLists.txt index 00b203e9..3d55f0ea 100644 --- a/external/db_drivers/liblmdb/CMakeLists.txt +++ b/external/db_drivers/liblmdb/CMakeLists.txt @@ -30,6 +30,11 @@ if(FREEBSD) add_definitions(-DMDB_DSYNC=O_SYNC) endif() +if(ANDROID) + add_definitions("-DANDROID=1") +endif() + + set (lmdb_sources mdb.c midl.c) diff --git a/external/unbound/compat/getentropy_linux.c b/external/unbound/compat/getentropy_linux.c index 37d86a8f..b8d4a2bd 100644 --- a/external/unbound/compat/getentropy_linux.c +++ b/external/unbound/compat/getentropy_linux.c @@ -30,7 +30,13 @@ #ifdef HAVE_SYS_SYSCTL_H #include #endif +#ifdef __ANDROID__ +#include +#define statvfs statfs +#define fstatvfs fstatfs +#else #include +#endif #include #include #include diff --git a/src/common/int-util.h b/src/common/int-util.h index e9eddee9..9ac20e58 100644 --- a/src/common/int-util.h +++ b/src/common/int-util.h @@ -36,6 +36,10 @@ #include #include +#if defined(__ANDROID__) +#include +#endif + #if defined(_MSC_VER) #include @@ -138,16 +142,24 @@ static inline uint32_t ident32(uint32_t x) { return x; } static inline uint64_t ident64(uint64_t x) { return x; } #ifndef __OpenBSD__ +# if defined(__ANDROID__) && defined(__swap32) && !defined(swap32) +# define swap32 __swap32 +# elif !defined(swap32) static inline uint32_t swap32(uint32_t x) { x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8); return (x << 16) | (x >> 16); } +# endif +# if defined(__ANDROID__) && defined(__swap64) && !defined(swap64) +# define swap64 __swap64 +# elif !defined(swap64) static inline uint64_t swap64(uint64_t x) { x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8); x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16); return (x << 32) | (x >> 32); } -#endif +# endif +#endif /* __OpenBSD__ */ #if defined(__GNUC__) #define UNUSED __attribute__((unused)) diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index 9d83caca..1e037a07 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -89,3 +89,14 @@ if (ARM) PROPERTY COMPILE_DEFINITIONS "NO_OPTIMIZED_MULTIPLY_ON_ARM") endif() endif() + +# Because of the way Qt works on android with JNI, the code does not live in the main android thread +# So this code runs with a 1 MB default stack size. +# This will force the use of the heap for the allocation of the scratchpad +if (ANDROID) + if( BUILD_GUI_DEPS ) + add_definitions(-DFORCE_USE_HEAP=1) + endif() +endif() + + diff --git a/src/crypto/oaes_lib.c b/src/crypto/oaes_lib.c index f054a16f..0afec621 100644 --- a/src/crypto/oaes_lib.c +++ b/src/crypto/oaes_lib.c @@ -39,8 +39,8 @@ #include #endif -// FreeBSD, and OpenBSD also don't need timeb.h -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) +// ANDROID, FreeBSD, and OpenBSD also don't need timeb.h +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__ANDROID__) #include #else #include @@ -499,7 +499,7 @@ static void oaes_get_seed( char buf[RANDSIZ + 1] ) #else static uint32_t oaes_get_seed(void) { - #if !defined(__FreeBSD__) && !defined(__OpenBSD__) + #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__ANDROID__) struct timeb timer; struct tm *gmTimer; char * _test = NULL; diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c index 66d9ca5d..43b9619f 100644 --- a/src/crypto/slow-hash.c +++ b/src/crypto/slow-hash.c @@ -1052,7 +1052,6 @@ STATIC INLINE void xor_blocks(uint8_t* a, const uint8_t* b) void cn_slow_hash(const void *data, size_t length, char *hash) { - uint8_t long_state[MEMORY]; uint8_t text[INIT_SIZE_BYTE]; uint8_t a[AES_BLOCK_SIZE]; uint8_t b[AES_BLOCK_SIZE]; @@ -1070,6 +1069,13 @@ void cn_slow_hash(const void *data, size_t length, char *hash) hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein }; +#ifndef FORCE_USE_HEAP + uint8_t long_state[MEMORY]; +#else + uint8_t *long_state = NULL; + long_state = (uint8_t *)malloc(MEMORY); +#endif + hash_process(&state.hs, data, length); memcpy(text, state.init, INIT_SIZE_BYTE); @@ -1129,6 +1135,9 @@ void cn_slow_hash(const void *data, size_t length, char *hash) memcpy(state.init, text, INIT_SIZE_BYTE); hash_permutation(&state.hs); extra_hashes[state.hs.b[0] & 3](&state, 200, hash); +#ifdef FORCE_USE_HEAP + free(long_state); +#endif } #endif /* !aarch64 || !crypto */