aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt7
-rw-r--r--Makefile9
-rw-r--r--README.md9
-rw-r--r--contrib/depends/packages/hidapi.mk1
-rw-r--r--src/blockchain_utilities/CMakeLists.txt20
-rw-r--r--src/blockchain_utilities/blockchain_blackball.cpp2
-rw-r--r--src/blockchain_utilities/blockchain_import.cpp8
-rw-r--r--src/blocks/CMakeLists.txt35
-rw-r--r--src/blocks/blockexports.c87
-rw-r--r--src/blocks/blocks.cpp31
-rw-r--r--src/blocks/blocks.dat0
-rw-r--r--src/blocks/blocks.h14
-rw-r--r--src/cryptonote_config.h1
-rw-r--r--src/cryptonote_core/CMakeLists.txt7
-rw-r--r--src/cryptonote_core/blockchain.cpp29
-rw-r--r--src/cryptonote_core/blockchain.h18
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp4
-rw-r--r--src/cryptonote_core/cryptonote_core.h3
-rw-r--r--src/daemon/CMakeLists.txt21
-rw-r--r--src/daemon/core.h8
-rw-r--r--src/device/CMakeLists.txt7
-rw-r--r--src/device/device.cpp25
-rw-r--r--src/device/device_io_hid.hpp12
-rw-r--r--src/device/device_ledger.cpp11
-rw-r--r--utils/build_scripts/android32.Dockerfile2
-rw-r--r--utils/build_scripts/android64.Dockerfile142
26 files changed, 366 insertions, 147 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ade7a290d..1bffd29b6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -186,7 +186,7 @@ if(NOT MANUAL_SUBMODULES)
string(COMPARE EQUAL "${unboundLocalHead}" "${unboundCheckedHead}" unboundUpToDate)
string(COMPARE EQUAL "${rapidjsonLocalHead}" "${rapidjsonCheckedHead}" rapidjsonUpToDate)
if (NOT miniupnpUpToDate OR NOT unboundUpToDate OR NOT rapidjsonUpToDate)
- message(FATAL_ERROR "Submodules not up to date. Please update with git subdmoule init && git submodule update, or run cmake with -DMANUAL_SUBMODULES=1")
+ message(FATAL_ERROR "Submodules not up to date. Please update with git submodule init && git submodule update, or run cmake with -DMANUAL_SUBMODULES=1")
endif()
endif()
endif()
@@ -199,9 +199,6 @@ set(PER_BLOCK_CHECKPOINT 1)
if(PER_BLOCK_CHECKPOINT)
add_definitions("-DPER_BLOCK_CHECKPOINT")
- set(Blocks "blocks")
-else()
- set(Blocks "")
endif()
list(INSERT CMAKE_MODULE_PATH 0
@@ -677,10 +674,12 @@ else()
add_linker_flag_if_supported(-Wl,-z,noexecstack noexecstack_SUPPORTED)
if (noexecstack_SUPPORTED)
set(LD_SECURITY_FLAGS "${LD_SECURITY_FLAGS} -Wl,-z,noexecstack")
+ set(LD_RAW_FLAGS ${LD_RAW_FLAGS} -z noexecstack)
endif()
add_linker_flag_if_supported(-Wl,-z,noexecheap noexecheap_SUPPORTED)
if (noexecheap_SUPPORTED)
set(LD_SECURITY_FLAGS "${LD_SECURITY_FLAGS} -Wl,-z,noexecheap")
+ set(LD_RAW_FLAGS ${LD_RAW_FLAGS} -z noexecheap)
endif()
# some windows linker bits
diff --git a/Makefile b/Makefile
index a0bf86c0e..40b8839cc 100644
--- a/Makefile
+++ b/Makefile
@@ -103,10 +103,15 @@ release-static-linux-armv7:
mkdir -p $(builddir)/release
cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="linux-armv7" $(topdir) && $(MAKE)
-release-static-android:
+release-static-android-armv7:
mkdir -p $(builddir)/release/translations
cd $(builddir)/release/translations && cmake ../../../translations && $(MAKE)
- cd $(builddir)/release && CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ 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 -D BUILD_TAG="android" -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARM_MODE=ON -D CMAKE_ANDROID_ARCH_ABI="armeabi-v7a" ../.. && $(MAKE)
+ cd $(builddir)/release && CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ 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 -D BUILD_TAG="android-armv7" -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARM_MODE=ON -D CMAKE_ANDROID_ARCH_ABI="armeabi-v7a" ../.. && $(MAKE)
+
+release-static-android-armv8:
+ mkdir -p $(builddir)/release/translations
+ cd $(builddir)/release/translations && cmake ../../../translations && $(MAKE)
+ cd $(builddir)/release && CC=aarch64-linux-android-clang CXX=aarch64-linux-android-clang++ cmake -D BUILD_TESTS=OFF -D ARCH="armv8-a" -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON -D BUILD_TAG="android-armv8" -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARCH_ABI="arm64-v8a" ../.. && $(MAKE)
release-static-linux-armv8:
mkdir -p $(builddir)/release
diff --git a/README.md b/README.md
index bce41f5cf..5da96371a 100644
--- a/README.md
+++ b/README.md
@@ -150,14 +150,13 @@ library archives (`.a`).
| GTest | 1.5 | YES | `libgtest-dev`^ | `gtest` | `gtest-devel` | YES | Test suite |
| Doxygen | any | NO | `doxygen` | `doxygen` | `doxygen` | YES | Documentation |
| Graphviz | any | NO | `graphviz` | `graphviz` | `graphviz` | YES | Documentation |
-| pcsclite | ? | NO | `libpcsclite-dev` | ? | `pcsc-lite pcsc-lite-devel` | NO | Ledger |
[^] On Debian/Ubuntu `libgtest-dev` only includes sources and headers. You must
build the library binary manually. This can be done with the following command ```sudo apt-get install libgtest-dev && cd /usr/src/gtest && sudo cmake . && sudo make && sudo mv libg* /usr/lib/ ```
Debian / Ubuntu one liner for all dependencies
-``` sudo apt update && sudo apt install build-essential cmake pkg-config libboost-all-dev libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libldns-dev libexpat1-dev doxygen graphviz libpcsclite-dev libpgm-dev```
+``` sudo apt update && sudo apt install build-essential cmake pkg-config libboost-all-dev libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libldns-dev libexpat1-dev doxygen graphviz libpgm-dev```
### Cloning the repository
@@ -472,12 +471,14 @@ Then you can run make as usual.
### On Linux for Android (using docker):
- # Build image
+ # Build image (for ARM 32-bit)
docker build -f utils/build_scripts/android32.Dockerfile -t monero-android .
+ # Build image (for ARM 64-bit)
+ docker build -f utils/build_scripts/android64.Dockerfile -t monero-android .
# Create container
docker create -it --name monero-android monero-android bash
# Get binaries
- docker cp monero-android:/opt/android/monero/build/release/bin .
+ docker cp monero-android:/src/build/release/bin .
### Building portable statically linked binaries (Cross Compiling)
diff --git a/contrib/depends/packages/hidapi.mk b/contrib/depends/packages/hidapi.mk
index d4dd80e22..1c43e525a 100644
--- a/contrib/depends/packages/hidapi.mk
+++ b/contrib/depends/packages/hidapi.mk
@@ -13,6 +13,7 @@ $(package)_config_opts_linux+=libudev_LIBS="-L$(host_prefix)/lib -ludev"
$(package)_config_opts_linux+=libudev_CFLAGS=-I$(host_prefix)/include
$(package)_config_opts_linux+=libusb_LIBS="-L$(host_prefix)/lib -lusb-1.0"
$(package)_config_opts_linux+=libusb_CFLAGS=-I$(host_prefix)/include/libusb-1.0
+$(package)_config_opts_linux+=--with-pic
endef
define $(package)_config_cmds
diff --git a/src/blockchain_utilities/CMakeLists.txt b/src/blockchain_utilities/CMakeLists.txt
index 873bf552c..ecd7b754c 100644
--- a/src/blockchain_utilities/CMakeLists.txt
+++ b/src/blockchain_utilities/CMakeLists.txt
@@ -26,6 +26,20 @@
# 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.
+set(blocksdat "")
+if(PER_BLOCK_CHECKPOINT)
+ if(APPLE AND DEPENDS)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} --target=x86_64-apple-darwin11 -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*)
+ elseif(APPLE AND NOT DEPENDS)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*)
+ elseif(LINUX_32)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat)
+ else()
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat)
+ endif()
+ set(blocksdat "blocksdat.o")
+endif()
+
set(blockchain_import_sources
blockchain_import.cpp
bootstrap_file.cpp
@@ -105,7 +119,8 @@ monero_private_headers(blockchain_depth
monero_add_executable(blockchain_import
${blockchain_import_sources}
- ${blockchain_import_private_headers})
+ ${blockchain_import_private_headers}
+ ${blocksdat})
target_link_libraries(blockchain_import
PRIVATE
@@ -117,8 +132,7 @@ target_link_libraries(blockchain_import
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
- ${EXTRA_LIBRARIES}
- ${Blocks})
+ ${EXTRA_LIBRARIES})
if(ARCH_WIDTH)
target_compile_definitions(blockchain_import
diff --git a/src/blockchain_utilities/blockchain_blackball.cpp b/src/blockchain_utilities/blockchain_blackball.cpp
index 00baad7f0..03ff3cdcd 100644
--- a/src/blockchain_utilities/blockchain_blackball.cpp
+++ b/src/blockchain_utilities/blockchain_blackball.cpp
@@ -1233,7 +1233,7 @@ int main(int argc, char* argv[])
std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush;
}
blackballs.push_back(output);
- if (!add_spent_output(cur, output_data(txin.amount, absolute[o])))
+ if (add_spent_output(cur, output_data(txin.amount, absolute[o])))
inc_stat(txn, txin.amount ? "pre-rct-duplicate-rings" : "rct-duplicate-rings");
}
}
diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp
index 134969dc4..9ec768d26 100644
--- a/src/blockchain_utilities/blockchain_import.cpp
+++ b/src/blockchain_utilities/blockchain_import.cpp
@@ -37,7 +37,6 @@
#include "misc_log_ex.h"
#include "bootstrap_file.h"
#include "bootstrap_serialization.h"
-#include "blocks/blocks.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "serialization/binary_utils.h" // dump_binary(), parse_binary()
#include "serialization/json_utils.h" // dump_json()
@@ -759,12 +758,7 @@ int main(int argc, char* argv[])
{
core.disable_dns_checkpoints(true);
-#if defined(PER_BLOCK_CHECKPOINT)
- GetCheckpointsCallback get_checkpoints = blocks::GetCheckpointsData;
-#else
- GetCheckpointsCallback get_checkpoints = nullptr;
-#endif
- if (!core.init(vm, nullptr, nullptr, get_checkpoints))
+ if (!core.init(vm, NULL))
{
std::cerr << "Failed to initialize core" << ENDL;
return 1;
diff --git a/src/blocks/CMakeLists.txt b/src/blocks/CMakeLists.txt
index bedda3b88..ebb5408cc 100644
--- a/src/blocks/CMakeLists.txt
+++ b/src/blocks/CMakeLists.txt
@@ -26,23 +26,20 @@
# 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.
-set(GENERATED_SOURCES "")
+if(APPLE)
+ add_library(blocks STATIC blockexports.c)
+ set_target_properties(blocks PROPERTIES LINKER_LANGUAGE C)
+else()
+ if(LINUX_32)
+ add_custom_command(OUTPUT blocks.o MAIN_DEPENDENCY blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocks.o blocks.dat)
+ add_custom_command(OUTPUT testnet_blocks.o MAIN_DEPENDENCY testnet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/testnet_blocks.o testnet_blocks.dat)
+ add_custom_command(OUTPUT stagenet_blocks.o MAIN_DEPENDENCY stagenet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/stagenet_blocks.o stagenet_blocks.dat)
+ else()
+ add_custom_command(OUTPUT blocks.o MAIN_DEPENDENCY blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocks.o blocks.dat)
+ add_custom_command(OUTPUT testnet_blocks.o MAIN_DEPENDENCY testnet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/testnet_blocks.o testnet_blocks.dat)
+ add_custom_command(OUTPUT stagenet_blocks.o MAIN_DEPENDENCY stagenet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/stagenet_blocks.o stagenet_blocks.dat)
+ endif()
+ add_library(blocks STATIC blocks.o testnet_blocks.o stagenet_blocks.o blockexports.c)
+ set_target_properties(blocks PROPERTIES LINKER_LANGUAGE C)
+endif()
-foreach(BLOB_NAME checkpoints testnet_blocks stagenet_blocks)
- set(OUTPUT_C_SOURCE "generated_${BLOB_NAME}.c")
- list(APPEND GENERATED_SOURCES ${OUTPUT_C_SOURCE})
- set(INPUT_DAT_FILE "${BLOB_NAME}.dat")
- add_custom_command(
- OUTPUT ${OUTPUT_C_SOURCE}
- MAIN_DEPENDENCY ${INPUT_DAT_FILE}
- COMMAND
- cd ${CMAKE_CURRENT_BINARY_DIR} &&
- echo "'#include\t<stddef.h>'" > ${OUTPUT_C_SOURCE} &&
- echo -n "'const\tunsigned\tchar\t${BLOB_NAME}[]={'" >> ${OUTPUT_C_SOURCE} &&
- od -v -An -w1 -tu1 ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE} | sed -e "':a;N;$$!ba;s/\\n/,/g'" >> ${OUTPUT_C_SOURCE} &&
- echo "'};'" >> ${OUTPUT_C_SOURCE} &&
- echo "'const\tsize_t\t${BLOB_NAME}_len\t=\tsizeof(${BLOB_NAME});'" >> ${OUTPUT_C_SOURCE}
- )
-endforeach()
-
-add_library(blocks STATIC blocks.cpp ${GENERATED_SOURCES})
diff --git a/src/blocks/blockexports.c b/src/blocks/blockexports.c
new file mode 100644
index 000000000..0154b0413
--- /dev/null
+++ b/src/blocks/blockexports.c
@@ -0,0 +1,87 @@
+#include <stddef.h>
+
+#if defined(__APPLE__)
+#include <mach-o/getsect.h>
+#ifdef BUILD_SHARED_LIBS
+#if !defined(__LP64__)
+const struct mach_header _mh_execute_header;
+#else
+const struct mach_header_64 _mh_execute_header;
+#endif
+#else
+#if !defined(__LP64__)
+extern const struct mach_header _mh_execute_header;
+#else
+extern const struct mach_header_64 _mh_execute_header;
+#endif
+#endif
+
+const unsigned char *get_blocks_dat_start(int testnet, int stagenet)
+{
+ size_t size;
+ if (testnet)
+ return getsectiondata(&_mh_execute_header, "__DATA", "__testnet_blocks_dat", &size);
+ else if (stagenet)
+ return getsectiondata(&_mh_execute_header, "__DATA", "__stagenet_blocks_dat", &size);
+ else
+ return getsectiondata(&_mh_execute_header, "__DATA", "__blocks_dat", &size);
+}
+
+size_t get_blocks_dat_size(int testnet, int stagenet)
+{
+ size_t size;
+ if (testnet)
+ getsectiondata(&_mh_execute_header, "__DATA", "__testnet_blocks_dat", &size);
+ else if (stagenet)
+ getsectiondata(&_mh_execute_header, "__DATA", "__stagenet_blocks_dat", &size);
+ else
+ getsectiondata(&_mh_execute_header, "__DATA", "__blocks_dat", &size);
+ return size;
+}
+
+#else
+
+#if defined(_WIN32) && !defined(_WIN64)
+#define _binary_blocks_start binary_blocks_dat_start
+#define _binary_blocks_end binary_blocks_dat_end
+#define _binary_testnet_blocks_start binary_testnet_blocks_dat_start
+#define _binary_testnet_blocks_end binary_testnet_blocks_dat_end
+#define _binary_stagenet_blocks_start binary_stagenet_blocks_dat_start
+#define _binary_stagenet_blocks_end binary_stagenet_blocks_dat_end
+#else
+#define _binary_blocks_start _binary_blocks_dat_start
+#define _binary_blocks_end _binary_blocks_dat_end
+#define _binary_testnet_blocks_start _binary_testnet_blocks_dat_start
+#define _binary_testnet_blocks_end _binary_testnet_blocks_dat_end
+#define _binary_stagenet_blocks_start _binary_stagenet_blocks_dat_start
+#define _binary_stagenet_blocks_end _binary_stagenet_blocks_dat_end
+#endif
+
+extern const unsigned char _binary_blocks_start[];
+extern const unsigned char _binary_blocks_end[];
+extern const unsigned char _binary_testnet_blocks_start[];
+extern const unsigned char _binary_testnet_blocks_end[];
+extern const unsigned char _binary_stagenet_blocks_start[];
+extern const unsigned char _binary_stagenet_blocks_end[];
+
+const unsigned char *get_blocks_dat_start(int testnet, int stagenet)
+{
+ if (testnet)
+ return _binary_testnet_blocks_start;
+ else if (stagenet)
+ return _binary_stagenet_blocks_start;
+ else
+ return _binary_blocks_start;
+}
+
+size_t get_blocks_dat_size(int testnet, int stagenet)
+{
+ if (testnet)
+ return (size_t) (_binary_testnet_blocks_end - _binary_testnet_blocks_start);
+ else if (stagenet)
+ return (size_t) (_binary_stagenet_blocks_end - _binary_stagenet_blocks_start);
+ else
+ return (size_t) (_binary_blocks_end - _binary_blocks_start);
+}
+
+#endif
diff --git a/src/blocks/blocks.cpp b/src/blocks/blocks.cpp
deleted file mode 100644
index 0661f8448..000000000
--- a/src/blocks/blocks.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "blocks.h"
-
-#include <unordered_map>
-
-extern const unsigned char checkpoints[];
-extern const size_t checkpoints_len;
-extern const unsigned char stagenet_blocks[];
-extern const size_t stagenet_blocks_len;
-extern const unsigned char testnet_blocks[];
-extern const size_t testnet_blocks_len;
-
-namespace blocks
-{
-
- const std::unordered_map<cryptonote::network_type, const epee::span<const unsigned char>, std::hash<size_t>> CheckpointsByNetwork = {
- {cryptonote::network_type::MAINNET, {checkpoints, checkpoints_len}},
- {cryptonote::network_type::STAGENET, {stagenet_blocks, stagenet_blocks_len}},
- {cryptonote::network_type::TESTNET, {testnet_blocks, testnet_blocks_len}}
- };
-
- const epee::span<const unsigned char> GetCheckpointsData(cryptonote::network_type network)
- {
- const auto it = CheckpointsByNetwork.find(network);
- if (it != CheckpointsByNetwork.end())
- {
- return it->second;
- }
- return nullptr;
- }
-
-}
diff --git a/src/blocks/blocks.dat b/src/blocks/blocks.dat
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/blocks/blocks.dat
diff --git a/src/blocks/blocks.h b/src/blocks/blocks.h
index 14e391319..ec683f47e 100644
--- a/src/blocks/blocks.h
+++ b/src/blocks/blocks.h
@@ -1,12 +1,16 @@
#ifndef SRC_BLOCKS_BLOCKS_H_
#define SRC_BLOCKS_BLOCKS_H_
-#include "cryptonote_config.h"
-#include "span.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
-namespace blocks
-{
- const epee::span<const unsigned char> GetCheckpointsData(cryptonote::network_type network);
+const unsigned char *get_blocks_dat_start(int testnet, int stagenet);
+size_t get_blocks_dat_size(int testnet, int stagenet);
+
+#ifdef __cplusplus
}
+#endif
+
#endif /* SRC_BLOCKS_BLOCKS_H_ */
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
index c62eeb738..a6858ce7c 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
@@ -30,7 +30,6 @@
#pragma once
-#include <stdexcept>
#include <string>
#include <boost/uuid/uuid.hpp>
diff --git a/src/cryptonote_core/CMakeLists.txt b/src/cryptonote_core/CMakeLists.txt
index 231489fdb..72844db66 100644
--- a/src/cryptonote_core/CMakeLists.txt
+++ b/src/cryptonote_core/CMakeLists.txt
@@ -41,6 +41,12 @@ set(cryptonote_core_private_headers
tx_pool.h
cryptonote_tx_utils.h)
+if(PER_BLOCK_CHECKPOINT)
+ set(Blocks "blocks")
+else()
+ set(Blocks "")
+endif()
+
monero_private_headers(cryptonote_core
${cryptonote_core_private_headers})
monero_add_library(cryptonote_core
@@ -63,4 +69,5 @@ target_link_libraries(cryptonote_core
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
PRIVATE
+ ${Blocks}
${EXTRA_LIBRARIES})
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 6c6e024e4..eb869b795 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -53,6 +53,9 @@
#include "ringct/rctSigs.h"
#include "common/perf_timer.h"
#include "common/notify.h"
+#if defined(PER_BLOCK_CHECKPOINT)
+#include "blocks/blocks.h"
+#endif
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "blockchain"
@@ -338,7 +341,7 @@ uint64_t Blockchain::get_current_blockchain_height() const
//------------------------------------------------------------------
//FIXME: possibly move this into the constructor, to avoid accidentally
// dereferencing a null BlockchainDB pointer
-bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline, const cryptonote::test_options *test_options, difficulty_type fixed_difficulty, const GetCheckpointsCallback get_checkpoints/* = nullptr*/)
+bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline, const cryptonote::test_options *test_options, difficulty_type fixed_difficulty)
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_tx_pool);
@@ -436,7 +439,7 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline
#if defined(PER_BLOCK_CHECKPOINT)
if (m_nettype != FAKECHAIN)
- load_compiled_in_block_hashes(get_checkpoints);
+ load_compiled_in_block_hashes();
#endif
MINFO("Blockchain initialized. last block: " << m_db->height() - 1 << ", " << epee::misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block());
@@ -4401,21 +4404,19 @@ void Blockchain::cancel()
#if defined(PER_BLOCK_CHECKPOINT)
static const char expected_block_hashes_hash[] = "954cb2bbfa2fe6f74b2cdd22a1a4c767aea249ad47ad4f7c9445f0f03260f511";
-void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback get_checkpoints)
+void Blockchain::load_compiled_in_block_hashes()
{
- if (get_checkpoints == nullptr || !m_fast_sync)
- {
- return;
- }
- const epee::span<const unsigned char> checkpoints = get_checkpoints(m_nettype);
- if (!checkpoints.empty())
+ const bool testnet = m_nettype == TESTNET;
+ const bool stagenet = m_nettype == STAGENET;
+ if (m_fast_sync && get_blocks_dat_start(testnet, stagenet) != nullptr && get_blocks_dat_size(testnet, stagenet) > 0)
{
- MINFO("Loading precomputed blocks (" << checkpoints.size() << " bytes)");
+ MINFO("Loading precomputed blocks (" << get_blocks_dat_size(testnet, stagenet) << " bytes)");
+
if (m_nettype == MAINNET)
{
// first check hash
crypto::hash hash;
- if (!tools::sha256sum(checkpoints.data(), checkpoints.size(), hash))
+ if (!tools::sha256sum(get_blocks_dat_start(testnet, stagenet), get_blocks_dat_size(testnet, stagenet), hash))
{
MERROR("Failed to hash precomputed blocks data");
return;
@@ -4435,9 +4436,9 @@ void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback get_
}
}
- if (checkpoints.size() > 4)
+ if (get_blocks_dat_size(testnet, stagenet) > 4)
{
- const unsigned char *p = checkpoints.data();
+ const unsigned char *p = get_blocks_dat_start(testnet, stagenet);
const uint32_t nblocks = *p | ((*(p+1))<<8) | ((*(p+2))<<16) | ((*(p+3))<<24);
if (nblocks > (std::numeric_limits<uint32_t>::max() - 4) / sizeof(hash))
{
@@ -4445,7 +4446,7 @@ void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback get_
return;
}
const size_t size_needed = 4 + nblocks * sizeof(crypto::hash);
- if(nblocks > 0 && nblocks > (m_db->height() + HASH_OF_HASHES_STEP - 1) / HASH_OF_HASHES_STEP && checkpoints.size() >= size_needed)
+ if(nblocks > 0 && nblocks > (m_db->height() + HASH_OF_HASHES_STEP - 1) / HASH_OF_HASHES_STEP && get_blocks_dat_size(testnet, stagenet) >= size_needed)
{
p += sizeof(uint32_t);
m_blocks_hash_of_hashes.reserve(nblocks);
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 9b67765b5..ab66fac8b 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -38,11 +38,9 @@
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <atomic>
-#include <functional>
#include <unordered_map>
#include <unordered_set>
-#include "span.h"
#include "syncobj.h"
#include "string_tools.h"
#include "cryptonote_basic/cryptonote_basic.h"
@@ -75,15 +73,6 @@ namespace cryptonote
db_nosync //!< Leave syncing up to the backing db (safest, but slowest because of disk I/O)
};
- /**
- * @brief Callback routine that returns checkpoints data for specific network type
- *
- * @param network network type
- *
- * @return checkpoints data, empty span if there ain't any checkpoints for specific network type
- */
- typedef std::function<const epee::span<const unsigned char>(cryptonote::network_type network)> GetCheckpointsCallback;
-
/************************************************************************/
/* */
/************************************************************************/
@@ -128,11 +117,10 @@ namespace cryptonote
* @param offline true if running offline, else false
* @param test_options test parameters
* @param fixed_difficulty fixed difficulty for testing purposes; 0 means disabled
- * @param get_checkpoints if set, will be called to get checkpoints data
*
* @return true on success, false if any initialization steps fail
*/
- bool init(BlockchainDB* db, const network_type nettype = MAINNET, bool offline = false, const cryptonote::test_options *test_options = NULL, difficulty_type fixed_difficulty = 0, const GetCheckpointsCallback get_checkpoints = nullptr);
+ bool init(BlockchainDB* db, const network_type nettype = MAINNET, bool offline = false, const cryptonote::test_options *test_options = NULL, difficulty_type fixed_difficulty = 0);
/**
* @brief Initialize the Blockchain state
@@ -1381,10 +1369,8 @@ namespace cryptonote
* A (possibly empty) set of block hashes can be compiled into the
* monero daemon binary. This function loads those hashes into
* a useful state.
- *
- * @param get_checkpoints if set, will be called to get checkpoints data
*/
- void load_compiled_in_block_hashes(const GetCheckpointsCallback get_checkpoints);
+ void load_compiled_in_block_hashes();
/**
* @brief expands v2 transaction data from blockchain
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 3882a14ae..69e3c708b 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -389,7 +389,7 @@ namespace cryptonote
return m_blockchain_storage.get_alternative_blocks_count();
}
//-----------------------------------------------------------------------------------------------
- bool core::init(const boost::program_options::variables_map& vm, const char *config_subdir, const cryptonote::test_options *test_options, const GetCheckpointsCallback get_checkpoints/* = nullptr */)
+ bool core::init(const boost::program_options::variables_map& vm, const char *config_subdir, const cryptonote::test_options *test_options)
{
start_time = std::time(nullptr);
@@ -567,7 +567,7 @@ namespace cryptonote
regtest_hard_forks
};
const difficulty_type fixed_difficulty = command_line::get_arg(vm, arg_fixed_difficulty);
- r = m_blockchain_storage.init(db.release(), m_nettype, m_offline, regtest ? &regtest_test_options : test_options, fixed_difficulty, get_checkpoints);
+ r = m_blockchain_storage.init(db.release(), m_nettype, m_offline, regtest ? &regtest_test_options : test_options, fixed_difficulty);
r = m_mempool.init(max_txpool_weight);
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize memory pool");
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index 882568330..58fe5b7b5 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -244,11 +244,10 @@ namespace cryptonote
* @param vm command line parameters
* @param config_subdir subdirectory for config storage
* @param test_options configuration options for testing
- * @param get_checkpoints if set, will be called to get checkpoints data, must return checkpoints data pointer and size or nullptr if there ain't any checkpoints for specific network type
*
* @return false if one of the init steps fails, otherwise true
*/
- bool init(const boost::program_options::variables_map& vm, const char *config_subdir = NULL, const test_options *test_options = NULL, const GetCheckpointsCallback get_checkpoints = nullptr);
+ bool init(const boost::program_options::variables_map& vm, const char *config_subdir = NULL, const test_options *test_options = NULL);
/**
* @copydoc Blockchain::reset_and_set_genesis_block
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
index 117790455..f645836a4 100644
--- a/src/daemon/CMakeLists.txt
+++ b/src/daemon/CMakeLists.txt
@@ -26,6 +26,20 @@
# 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.
+set(blocksdat "")
+if(PER_BLOCK_CHECKPOINT)
+ if(APPLE AND DEPENDS)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} --target=x86_64-apple-darwin11 -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*)
+ elseif(APPLE AND NOT DEPENDS)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*)
+ elseif(LINUX_32)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat)
+ else()
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat)
+ endif()
+ set(blocksdat "blocksdat.o")
+endif()
+
set(daemon_sources
command_parser_executor.cpp
command_server.cpp
@@ -67,7 +81,9 @@ monero_private_headers(daemon
monero_add_executable(daemon
${daemon_sources}
${daemon_headers}
- ${daemon_private_headers})
+ ${daemon_private_headers}
+ ${blocksdat}
+)
target_link_libraries(daemon
PRIVATE
rpc
@@ -90,8 +106,7 @@ target_link_libraries(daemon
${CMAKE_THREAD_LIBS_INIT}
${ZMQ_LIB}
${GNU_READLINE_LIBRARY}
- ${EXTRA_LIBRARIES}
- ${Blocks})
+ ${EXTRA_LIBRARIES})
set_property(TARGET daemon
PROPERTY
OUTPUT_NAME "monerod")
diff --git a/src/daemon/core.h b/src/daemon/core.h
index eda8894a6..475f418d6 100644
--- a/src/daemon/core.h
+++ b/src/daemon/core.h
@@ -28,7 +28,6 @@
#pragma once
-#include "blocks/blocks.h"
#include "cryptonote_core/cryptonote_core.h"
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
#include "misc_log_ex.h"
@@ -86,12 +85,7 @@ public:
//initialize core here
MGINFO("Initializing core...");
std::string config_subdir = get_config_subdir();
-#if defined(PER_BLOCK_CHECKPOINT)
- cryptonote::GetCheckpointsCallback get_checkpoints = blocks::GetCheckpointsData;
-#else
- cryptonote::GetCheckpointsCallback get_checkpoints = nullptr;
-#endif
- if (!m_core.init(m_vm_HACK, config_subdir.empty() ? NULL : config_subdir.c_str(), nullptr, get_checkpoints))
+ if (!m_core.init(m_vm_HACK, config_subdir.empty() ? NULL : config_subdir.c_str()))
{
return false;
}
diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt
index 727134f75..8f446f42a 100644
--- a/src/device/CMakeLists.txt
+++ b/src/device/CMakeLists.txt
@@ -58,6 +58,12 @@ endif()
set(device_private_headers)
+if(PER_BLOCK_CHECKPOINT)
+ set(Blocks "blocks")
+else()
+ set(Blocks "")
+endif()
+
monero_private_headers(device
${device_private_headers})
@@ -73,4 +79,5 @@ target_link_libraries(device
ringct_basic
${OPENSSL_CRYPTO_LIBRARIES}
PRIVATE
+ ${Blocks}
${EXTRA_LIBRARIES})
diff --git a/src/device/device.cpp b/src/device/device.cpp
index 50041baef..d5e3031ff 100644
--- a/src/device/device.cpp
+++ b/src/device/device.cpp
@@ -41,13 +41,26 @@ namespace hw {
/* SETUP */
/* ======================================================================= */
- static std::unique_ptr<device_registry> registry;
+ static device_registry *get_device_registry(bool clear = false){
+ static device_registry *registry = new device_registry();
+ if (clear)
+ {
+ delete registry;
+ registry = NULL;
+ }
+ return registry;
+ }
+
+ static void clear_device_registry(){
+ get_device_registry(true);
+ }
device_registry::device_registry(){
hw::core::register_all(registry);
#ifdef WITH_DEVICE_LEDGER
hw::ledger::register_all(registry);
#endif
+ atexit(clear_device_registry);
}
bool device_registry::register_device(const std::string & device_name, device * hw_device){
@@ -80,18 +93,12 @@ namespace hw {
}
device& get_device(const std::string & device_descriptor) {
- if (!registry){
- registry.reset(new device_registry());
- }
-
+ device_registry *registry = get_device_registry();
return registry->get_device(device_descriptor);
}
bool register_device(const std::string & device_name, device * hw_device){
- if (!registry){
- registry.reset(new device_registry());
- }
-
+ device_registry *registry = get_device_registry();
return registry->register_device(device_name, hw_device);
}
diff --git a/src/device/device_io_hid.hpp b/src/device/device_io_hid.hpp
index 560208c77..6fd15a1d1 100644
--- a/src/device/device_io_hid.hpp
+++ b/src/device/device_io_hid.hpp
@@ -86,13 +86,13 @@ namespace hw {
public:
bool hid_verbose = false;
- const unsigned int OR_SELECT = 1;
- const unsigned int AND_SELECT = 2;
+ static const unsigned int OR_SELECT = 1;
+ static const unsigned int AND_SELECT = 2;
- const unsigned char DEFAULT_CHANNEL = 0x0001;
- const unsigned char DEFAULT_TAG = 0x01;
- const unsigned int DEFAULT_PACKET_SIZE = 64;
- const unsigned int DEFAULT_TIMEOUT = 120000;
+ static const unsigned short DEFAULT_CHANNEL = 0x0001;
+ static const unsigned char DEFAULT_TAG = 0x01;
+ static const unsigned int DEFAULT_PACKET_SIZE = 64;
+ static const unsigned int DEFAULT_TIMEOUT = 120000;
device_io_hid(unsigned short channel, unsigned char tag, unsigned int packet_zize, unsigned int timeout);
device_io_hid();
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
index 456eda739..a17784960 100644
--- a/src/device/device_ledger.cpp
+++ b/src/device/device_ledger.cpp
@@ -48,21 +48,12 @@ namespace hw {
/* ===================================================================== */
/* === Debug ==== */
/* ===================================================================== */
- #ifdef WIN32
- static char *pcsc_stringify_error(LONG rv) {
- static __thread char out[20];
- sprintf_s(out, sizeof(out), "0x%08lX", rv);
-
- return out;
- }
- #endif
void set_apdu_verbose(bool verbose) {
apdu_verbose = verbose;
}
#define TRACKD MTRACE("hw")
- #define ASSERT_RV(rv) CHECK_AND_ASSERT_THROW_MES((rv)==SCARD_S_SUCCESS, "Fail SCard API : (" << (rv) << ") "<< pcsc_stringify_error(rv)<<" Device="<<this->id<<", hCard="<<hCard<<", hContext="<<hContext);
#define ASSERT_SW(sw,ok,msk) CHECK_AND_ASSERT_THROW_MES(((sw)&(mask))==(ok), "Wrong Device Status : SW=" << std::hex << (sw) << " (EXPECT=" << std::hex << (ok) << ", MASK=" << std::hex << (mask) << ")") ;
#define ASSERT_T0(exp) CHECK_AND_ASSERT_THROW_MES(exp, "Protocol assert failure: "#exp ) ;
#define ASSERT_X(exp,msg) CHECK_AND_ASSERT_THROW_MES(exp, msg);
@@ -185,7 +176,7 @@ namespace hw {
#define INS_GET_RESPONSE 0xc0
- device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 10000) {
+ device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 120000) {
this->id = device_id++;
this->reset_buffer();
this->mode = NONE;
diff --git a/utils/build_scripts/android32.Dockerfile b/utils/build_scripts/android32.Dockerfile
index 8647341cb..e49bdc652 100644
--- a/utils/build_scripts/android32.Dockerfile
+++ b/utils/build_scripts/android32.Dockerfile
@@ -139,4 +139,4 @@ RUN cd /src \
CMAKE_LIBRARY_PATH="${PREFIX}/lib" \
ANDROID_STANDALONE_TOOLCHAIN_PATH=${TOOLCHAIN_DIR} \
USE_SINGLE_BUILDDIR=1 \
- PATH=${HOST_PATH} make release-static-android -j${NPROC}
+ PATH=${HOST_PATH} make release-static-android-armv7 -j${NPROC}
diff --git a/utils/build_scripts/android64.Dockerfile b/utils/build_scripts/android64.Dockerfile
new file mode 100644
index 000000000..c4464fa84
--- /dev/null
+++ b/utils/build_scripts/android64.Dockerfile
@@ -0,0 +1,142 @@
+FROM debian:stable
+
+RUN apt-get update && apt-get install -y unzip automake build-essential curl file pkg-config git python libtool
+
+WORKDIR /opt/android
+## INSTALL ANDROID SDK
+ENV ANDROID_SDK_REVISION 4333796
+ENV ANDROID_SDK_HASH 92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9
+RUN curl -s -O https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \
+ && echo "${ANDROID_SDK_HASH} sdk-tools-linux-${ANDROID_SDK_REVISION}.zip" | sha256sum -c \
+ && unzip sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \
+ && rm -f sdk-tools-linux-${ANDROID_SDK_REVISION}.zip
+
+## INSTALL ANDROID NDK
+ENV ANDROID_NDK_REVISION 17b
+ENV ANDROID_NDK_HASH 5dfbbdc2d3ba859fed90d0e978af87c71a91a5be1f6e1c40ba697503d48ccecd
+RUN curl -s -O https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
+ && echo "${ANDROID_NDK_HASH} android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip" | sha256sum -c \
+ && unzip android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
+ && rm -f android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip
+
+ENV WORKDIR /opt/android
+ENV ANDROID_SDK_ROOT ${WORKDIR}/tools
+ENV ANDROID_NDK_ROOT ${WORKDIR}/android-ndk-r${ANDROID_NDK_REVISION}
+ENV PREFIX /opt/android/prefix
+
+ENV TOOLCHAIN_DIR ${WORKDIR}/toolchain-arm
+RUN ${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py \
+ --arch arm64 \
+ --api 21 \
+ --install-dir ${TOOLCHAIN_DIR} \
+ --stl=libc++
+
+#INSTALL cmake
+ENV CMAKE_VERSION 3.12.1
+RUN cd /usr \
+ && curl -s -O https://cmake.org/files/v3.12/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \
+ && tar -xzf /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \
+ && rm -f /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz
+ENV PATH /usr/cmake-${CMAKE_VERSION}-Linux-x86_64/bin:$PATH
+
+## Boost
+ARG BOOST_VERSION=1_68_0
+ARG BOOST_VERSION_DOT=1.68.0
+ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7
+RUN set -ex \
+ && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
+ && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
+ && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
+ && rm -f boost_${BOOST_VERSION}.tar.bz2 \
+ && cd boost_${BOOST_VERSION} \
+ && ./bootstrap.sh --prefix=${PREFIX}
+
+ENV HOST_PATH $PATH
+ENV PATH $TOOLCHAIN_DIR/aarch64-linux-android/bin:$TOOLCHAIN_DIR/bin:$PATH
+
+ARG NPROC=1
+
+# Build iconv for lib boost locale
+ENV ICONV_VERSION 1.15
+ENV ICONV_HASH ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
+RUN curl -s -O http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz \
+ && echo "${ICONV_HASH} libiconv-${ICONV_VERSION}.tar.gz" | sha256sum -c \
+ && tar -xzf libiconv-${ICONV_VERSION}.tar.gz \
+ && rm -f libiconv-${ICONV_VERSION}.tar.gz \
+ && cd libiconv-${ICONV_VERSION} \
+ && CC=aarch64-linux-android-clang CXX=aarch64-linux-android-clang++ ./configure --build=x86_64-linux-gnu --host=arm-eabi --prefix=${PREFIX} --disable-rpath \
+ && make -j${NPROC} && make install
+
+## Build BOOST
+RUN cd boost_${BOOST_VERSION} \
+ && ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale --build-dir=android --stagedir=android toolset=clang threading=multi threadapi=pthread target-os=android -sICONV_PATH=${PREFIX} install -j${NPROC}
+
+#Note : we build openssl because the default lacks DSA1
+
+# download, configure and make Zlib
+ENV ZLIB_VERSION 1.2.11
+ENV ZLIB_HASH c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
+RUN curl -s -O https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz \
+ && echo "${ZLIB_HASH} zlib-${ZLIB_VERSION}.tar.gz" | sha256sum -c \
+ && tar -xzf zlib-${ZLIB_VERSION}.tar.gz \
+ && rm zlib-${ZLIB_VERSION}.tar.gz \
+ && mv zlib-${ZLIB_VERSION} zlib \
+ && cd zlib && CC=clang CXX=clang++ ./configure --static \
+ && make -j${NPROC}
+
+# open ssl
+ARG OPENSSL_VERSION=1.0.2p
+ARG OPENSSL_HASH=50a98e07b1a89eb8f6a99477f262df71c6fa7bef77df4dc83025a2845c827d00
+RUN curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \
+ && echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \
+ && tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \
+ && rm openssl-${OPENSSL_VERSION}.tar.gz \
+ && cd openssl-${OPENSSL_VERSION} \
+ && sed -i -e "s/mandroid/target\ aarch64\-linux\-android/" Configure \
+ && CC=clang CXX=clang++ \
+ ./Configure android \
+ no-asm \
+ no-shared --static \
+ --with-zlib-include=${WORKDIR}/zlib/include --with-zlib-lib=${WORKDIR}/zlib/lib \
+ --prefix=${PREFIX} --openssldir=${PREFIX} \
+ && make -j${NPROC} \
+ && make install
+
+# ZMQ
+ARG ZMQ_VERSION=master
+ARG ZMQ_HASH=501d0815bf2b0abb93be8214fc66519918ef6c40
+RUN git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} \
+ && cd libzmq \
+ && git checkout ${ZMQ_HASH} \
+ && ./autogen.sh \
+ && CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=aarch64-linux-android --enable-static --disable-shared \
+ && make -j${NPROC} \
+ && make install
+
+# zmq.hpp
+ARG CPPZMQ_VERSION=v4.2.3
+ARG CPPZMQ_HASH=6aa3ab686e916cb0e62df7fa7d12e0b13ae9fae6
+RUN git clone https://github.com/zeromq/cppzmq.git -b ${CPPZMQ_VERSION} \
+ && cd cppzmq \
+ && test `git rev-parse HEAD` = ${CPPZMQ_HASH} || exit 1 \
+ && cp *.hpp ${PREFIX}/include
+
+# Sodium
+ARG SODIUM_VERSION=1.0.16
+ARG SODIUM_HASH=675149b9b8b66ff44152553fb3ebf9858128363d
+RUN set -ex \
+ && git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION} \
+ && cd libsodium \
+ && test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 \
+ && ./autogen.sh \
+ && CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=aarch64-linux-android --enable-static --disable-shared \
+ && make -j${NPROC} \
+ && make install
+
+ADD . /src
+RUN cd /src \
+ && CMAKE_INCLUDE_PATH="${PREFIX}/include" \
+ CMAKE_LIBRARY_PATH="${PREFIX}/lib" \
+ ANDROID_STANDALONE_TOOLCHAIN_PATH=${TOOLCHAIN_DIR} \
+ USE_SINGLE_BUILDDIR=1 \
+ PATH=${HOST_PATH} make release-static-android-armv8 -j${NPROC}