From 4894f1abec36d85097f4c8dcb6130ab5a590bb55 Mon Sep 17 00:00:00 2001 From: Chris Kleeschulte Date: Tue, 9 Feb 2016 14:32:51 -0500 Subject: [PATCH 1/3] Enable Cross-Compiling support 1. To use this feature, set CC and CXX env variables to the appropriate cross compiler 2. Example, for cross compiling to ARM, use: CC=arm-linux-gnueabihf-gcc-4.9 CXX=arm-linux-gnueabihf-g++-4.9 npm install 3. You can still compile without setting CC and CXX, you can still just run npm install --- bin/build | 11 +++++++---- bin/get-tarball-name.js | 4 +++- bin/package.js | 2 +- bin/upload.js | 2 +- bin/variables.sh | 41 +++++++++++++++++++++++++++++++++++------ etc/bitcoin.patch | 22 ++++++++-------------- 6 files changed, 55 insertions(+), 27 deletions(-) diff --git a/bin/build b/bin/build index bed89c1d..8c0fbe64 100755 --- a/bin/build +++ b/bin/build @@ -1,9 +1,10 @@ #!/bin/bash root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/.." options=`cat ${root_dir}/bin/config_options.sh` +host=$(${root_dir}/bin/variables.sh host) || exit -1 depends_dir=$($root_dir/bin/variables.sh depends_dir) -host=$(${root_dir}/bin/variables.sh host) btc_dir="${root_dir}/libbitcoind" +sys=$($root_dir/bin/variables.sh sys) patch_sha=$($root_dir/bin/variables.sh patch_sha) config_lib_dir=$($root_dir/bin/variables.sh config_lib_dir) export CPPFLAGS="-I${depends_dir}/${host}/include/boost -I${depends_dir}/${host}/include -L${depends_dir}/${host}/lib" @@ -51,7 +52,7 @@ compare_patch () { cache_files () { cache_file="${root_dir}"/cache/cache.tar pushd "${btc_dir}" || exit -1 - find . -type f \( -name "*.h" -or -name "*.hpp" -or -name \ + find src depends/${host} -type f \( -name "*.h" -or -name "*.hpp" -or -name \ "*.ipp" -or -name "*.a" \) | tar -cf "${cache_file}" -T - if test $? -ne 0; then echo "We were trying to copy over your cached artifacts, but there was an issue." @@ -154,7 +155,8 @@ apply the current patch from "${root_dir}"/etc/bitcoin.patch? (y/N): " echo './autogen.sh' ./autogen.sh || exit -1 - full_options="${options} ${config_lib_dir}" + config_host="--host ${host}" + full_options="${options} ${config_host} ${config_lib_dir}" echo "running the configure script with the following options:\n :::[\"${full_options}\"]:::" ${full_options} @@ -181,4 +183,5 @@ if test x"$1" = x'debug'; then debug=--debug fi -node-gyp ${debug} rebuild +echo "running::: 'node-gyp ${sys} ${debug} rebuild'" +node-gyp ${sys} ${debug} rebuild diff --git a/bin/get-tarball-name.js b/bin/get-tarball-name.js index e931904b..c7ea0ffb 100644 --- a/bin/get-tarball-name.js +++ b/bin/get-tarball-name.js @@ -1,10 +1,12 @@ 'use strict'; +var execSync = require('child_process').execSync; + function getTarballName() { var packageRoot = __dirname + '/..'; var version = require(packageRoot + '/package.json').version; var platform = process.platform; - var arch = process.arch; + var arch = execSync(packageRoot + '/bin/variables.sh arch').toString(); var abi = process.versions.modules; var tarballName = 'libbitcoind-' + version + '-node' + abi + '-' + platform + '-' + arch + '.tgz'; return tarballName; diff --git a/bin/package.js b/bin/package.js index d5b00d07..c03639bd 100644 --- a/bin/package.js +++ b/bin/package.js @@ -2,7 +2,7 @@ var exec = require('child_process').exec; var bindings = require('bindings'); -var index = require('../'); +var index = require('../lib'); var log = index.log; var packageRoot = bindings.getRoot(bindings.getFileName()); diff --git a/bin/upload.js b/bin/upload.js index b1c66bf0..4376bb20 100644 --- a/bin/upload.js +++ b/bin/upload.js @@ -3,7 +3,7 @@ var fs = require('fs'); var AWS = require('aws-sdk'); var bindings = require('bindings'); -var index = require('../'); +var index = require('../lib'); var log = index.log; var config = require(process.env.HOME + '/.bitcore-node-upload.json'); diff --git a/bin/variables.sh b/bin/variables.sh index 8b35e0cf..21b962ed 100755 --- a/bin/variables.sh +++ b/bin/variables.sh @@ -8,18 +8,37 @@ fi bitcoin_dir="${root_dir}"/libbitcoind cache_dir="${root_dir}"/cache -host= -compute_host () { +get_host_and_platform () { platform=`uname -a | awk '{print tolower($1)}'` arch=`uname -m` if [ "${arch:0:3}" == "arm" ]; then - host="arm-linux-gnueabihf" - else - host="${arch}"-"${platform}" + platform="linux-gnueabihf" + arch="arm" + fi + if [ -n "${CXX}" ] && [ -n "${CC}" ]; then + cc_target=$("${CC}" -v 2>&1 | awk '/Target:/ {print $2}') + cxx_target=$("${CXX}" -v 2>&1 | awk '/Target:/ {print $2}') + IFS='-' read -ra SYS <<< "${cc_target}" + if [ "${SYS[0]}" != "${arch}" ]; then + if [ -n "${SYS[1]}" ] && [ -n "${SYS[2]}" ] && hash "${CXX}" && hash "${CC}" && [ -n "${cc_target}" ] && [ -n "${cxx_target}" ]; then + #try and see if we've got a cross compiler, if not then auto detect + arch="${SYS[0]}" + platform="${SYS[1]}"-"${SYS[2]}" + else + error_message="You've specified a cross compiler, but we could not compute the host-platform-triplet for cross compilation. Please set CC and CXX environment variables with host-platform-triplet-*. Example: CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++" + return_error_message + fi + fi fi } -compute_host +return_error_message () { + echo "${error_message}" + exit -1 +} + +get_host_and_platform +host="${arch}"-"${platform}" mac_response= check_mac_build_system () { @@ -115,6 +134,10 @@ if test -z "$1" -o x"$1" = x'host'; then echo -n "${host}" fi +if test -z "$1" -o x"$1" = x'arch'; then + echo -n "${arch}" +fi + if test -z "$1" -o x"$1" = x'bdb'; then if [ "${BITCORENODE_ENV}" == "test" ]; then echo -n "${cache_dir}"/depends/"${host}"/lib/libdb_cxx.a @@ -144,6 +167,12 @@ if test -z "$1" -o x"$1" = x'wallet_enabled'; then fi fi +if test -z "$1" -o x"$1" = x'sys'; then + if [ -n "${SYS}" ]; then + echo -n "--arch=${SYS[0]}" + fi +fi + if test -z "$1" -o x"$1" = x'bitcoind'; then echo -n "${cache_dir}"/src/.libs/libbitcoind.a fi diff --git a/etc/bitcoin.patch b/etc/bitcoin.patch index 3eda2bc7..d03b22d4 100644 --- a/etc/bitcoin.patch +++ b/etc/bitcoin.patch @@ -163,23 +163,21 @@ index e7aa48d..df0f7ae 100644 endef diff --git a/src/Makefile.am b/src/Makefile.am -index 2461f82..7be6d6e 100644 +index 2461f82..e7e9ecf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am -@@ -1,6 +1,12 @@ +@@ -1,6 +1,10 @@ DIST_SUBDIRS = secp256k1 AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) +noinst_LTLIBRARIES = +libbitcoind_la_LIBADD = +libbitcoind_la_LDFLAGS = -no-undefined -+STATIC_BOOST_LIBS = -+STATIC_BDB_LIBS = -+STATIC_EXTRA_LIBS = $(STATIC_BOOST_LIBS) $(LIBLEVELDB) $(LIBMEMENV) ++STATIC_EXTRA_LIBS = $(LIBLEVELDB) $(LIBMEMENV) if EMBEDDED_LEVELDB LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include -@@ -49,16 +55,16 @@ BITCOIN_INCLUDES += $(BDB_CPPFLAGS) +@@ -49,16 +53,16 @@ BITCOIN_INCLUDES += $(BDB_CPPFLAGS) EXTRA_LIBRARIES += libbitcoin_wallet.a endif @@ -203,7 +201,7 @@ index 2461f82..7be6d6e 100644 if BUILD_BITCOIND bin_PROGRAMS += bitcoind endif -@@ -66,6 +72,9 @@ endif +@@ -66,6 +70,9 @@ endif if BUILD_BITCOIN_UTILS bin_PROGRAMS += bitcoin-cli bitcoin-tx endif @@ -213,7 +211,7 @@ index 2461f82..7be6d6e 100644 .PHONY: FORCE # bitcoin core # -@@ -170,8 +179,11 @@ obj/build.h: FORCE +@@ -170,8 +177,11 @@ obj/build.h: FORCE @$(MKDIR_P) $(builddir)/obj @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \ $(abs_top_srcdir) @@ -226,7 +224,7 @@ index 2461f82..7be6d6e 100644 # server: shared between bitcoind and bitcoin-qt libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) libbitcoin_server_a_SOURCES = \ -@@ -310,9 +322,18 @@ nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h +@@ -310,9 +320,18 @@ nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h bitcoind_SOURCES = bitcoind.cpp bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES) bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) @@ -245,17 +243,13 @@ index 2461f82..7be6d6e 100644 endif bitcoind_LDADD = \ -@@ -327,10 +348,21 @@ bitcoind_LDADD = \ +@@ -327,10 +346,17 @@ bitcoind_LDADD = \ if ENABLE_WALLET bitcoind_LDADD += libbitcoin_wallet.a -+STATIC_EXTRA_LIBS += $(STATIC_BDB_LIBS) +libbitcoind_la_SOURCES += $(libbitcoin_wallet_a_SOURCES) endif -+STATIC_BOOST_LIBS += ../depends/$(ARCH_PLATFORM)/lib/libboost_filesystem-mt.a ../depends/$(ARCH_PLATFORM)/lib/libboost_system-mt.a ../depends/$(ARCH_PLATFORM)/lib/libboost_chrono-mt.a ../depends/$(ARCH_PLATFORM)/lib/libboost_thread-mt.a ../depends/$(ARCH_PLATFORM)/lib/libboost_program_options-mt.a -+STATIC_BDB_LIBS += ../depends/$(ARCH_PLATFORM)/lib/libdb_cxx.a -+ bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) -# +libbitcoind_la_LIBADD += $(SSL_LIBS) $(LIBSECP256K1) $(CRYPTO_LIBS) $(STATIC_EXTRA_LIBS) From afce33e5ff7b6779df7bf5ba6646e38b907afa1c Mon Sep 17 00:00:00 2001 From: Chris Kleeschulte Date: Wed, 10 Feb 2016 15:00:04 -0500 Subject: [PATCH 2/3] Fixed test to refer to variables.sh for the architecture. --- test/bin/get-tarball-name.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/bin/get-tarball-name.js b/test/bin/get-tarball-name.js index fa2b0601..6f8bdbde 100644 --- a/test/bin/get-tarball-name.js +++ b/test/bin/get-tarball-name.js @@ -3,13 +3,14 @@ var should = require('chai').should(); var path = require('path'); var getTarballName = require('../../bin/get-tarball-name'); +var execSync = require('child_process').execSync; describe('#getTarballName', function() { it('will return the expected tarball name', function() { var name = getTarballName(); var version = require(path.resolve(__dirname + '../../../package.json')).version; var platform = process.platform; - var arch = process.arch; + var arch = execSync(path.resolve(__dirname) + '/../../bin/variables.sh arch'); var abi = process.versions.modules; var expected = 'libbitcoind-' + version + '-node' + abi + '-' + platform + '-' + arch + '.tgz'; name.should.equal(expected); From 610b9ea269b6875c7ca990a7b69e5e949606ddf7 Mon Sep 17 00:00:00 2001 From: Chris Kleeschulte Date: Wed, 10 Feb 2016 17:18:08 -0500 Subject: [PATCH 3/3] Added a doc fragment in build.md about cross compilation and clarified the error message. --- bin/variables.sh | 2 +- docs/build.md | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/bin/variables.sh b/bin/variables.sh index 21b962ed..0988e0fa 100755 --- a/bin/variables.sh +++ b/bin/variables.sh @@ -25,7 +25,7 @@ get_host_and_platform () { arch="${SYS[0]}" platform="${SYS[1]}"-"${SYS[2]}" else - error_message="You've specified a cross compiler, but we could not compute the host-platform-triplet for cross compilation. Please set CC and CXX environment variables with host-platform-triplet-*. Example: CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++" + error_message="You've specified a cross compiler, but we could not compute the host-platform-triplet for cross compilation. Please set CC and CXX environment variables with host-platform-triplet-*. Also ensure the cross compiler exists on your system and is available on your path. Example: CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++" return_error_message fi fi diff --git a/docs/build.md b/docs/build.md index 1846356f..d22b8411 100644 --- a/docs/build.md +++ b/docs/build.md @@ -80,6 +80,34 @@ And finally run the build which will take several minutes. A script in the "bin" npm install ``` +## Cross Compilation +If you desire to cross compile to ARM or Windows from a system that has cross compilation tools available for use, please use the following directions: + +Using a Debian (Jessie) system as the host system (the system that will be doing the compiling): + +```bash +echo -n "deb http://emdebian.org/tools/debian/ jessie main" | sudo tee -a /etc/apt/sources.list +sudo dpkg --add-architecture armhf #or whatever arch you are interested in compiling for +sudo apt-get update #you will get GPG KEY warnings, you can decide if you would like to trust the key +sudo apt-get install crossbuild-essential-armhf +``` + +Next is to use the cross compilation toolchain instead of the defaults: + +```bash +CXX=arm-linux-gnueabihf-g++ CC=arm-linux-gnueabihf-gcc npm install +``` + +The only thing different is the setting of CC/CXX environment variables. Please make sure those compilers (arm-linux-gnueabihf-gcc) actually exist and are on your path. + +```bash +arm-linux-gnueabihf-g++ -v +arm-linux-gnueabihf-gcc -v +``` + +You should get output with the last line ending with something like this: +gcc version 4.9.2 ( 4.9.2-10) + Once everything is built, you can run bitcore-node via: ```bash