From 8465190cb630fcbd789b12e9f4c835cf0b6b9993 Mon Sep 17 00:00:00 2001 From: Barnabas Debreczeni Date: Sat, 30 Jan 2016 17:46:19 +0100 Subject: [PATCH 1/2] Add suport for deterministic armhf builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many people use development boards (Raspberry Pi 2, Banana Pi, Odroid boards, etc) to run full nodes in CLI mode. The only option they had until now is to compile their own from source. Even though many tutorials are available, it is still not trivial for non tech-savvy users. Providing an officially built armhf binary would provide non tech-savvy users an easy ramp-on to Bitcoin Classic. *** GUI has been disabled for this build — according to Qt docs it needs to be compiled on with device-specific headers. Most armhf users use it in CLI mode only anyway. Tested binaries on Raspberry Pi2, Odroid C1 and Odroid XU4. --- .../gitian-descriptors/gitian-linux-armhf.yml | 112 ++++++++++++++++++ doc/gitian-building.md | 6 +- doc/release-process.md | 11 +- 3 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 contrib/gitian-descriptors/gitian-linux-armhf.yml diff --git a/contrib/gitian-descriptors/gitian-linux-armhf.yml b/contrib/gitian-descriptors/gitian-linux-armhf.yml new file mode 100644 index 00000000000..c47b9f5571f --- /dev/null +++ b/contrib/gitian-descriptors/gitian-linux-armhf.yml @@ -0,0 +1,112 @@ +--- +name: "bitcoin-linux-armhf-0.12" +enable_cache: true +suites: +- "trusty" +architectures: +- "amd64" +packages: +- "g++-arm-linux-gnueabihf" +- "git-core" +- "pkg-config" +- "autoconf" +- "libtool" +- "automake" +- "faketime" +- "bsdmainutils" +- "binutils-gold" +- "ca-certificates" +- "python" +reference_datetime: "2016-01-01 00:00:00" +remotes: +- "url": "https://github.com/bitcoinclassic/bitcoinclassic.git" + "dir": "bitcoin" +files: [] +script: | + WRAP_DIR=$HOME/wrapped + HOSTS="arm-linux-gnueabihf" + CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" + FAKETIME_HOST_PROGS="" + FAKETIME_PROGS="date ar ranlib nm strip" + + export QT_RCC_TEST=1 + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + if test -n "$GBUILD_CACHE_ENABLED"; then + export SOURCES_PATH=${GBUILD_COMMON_CACHE} + export BASE_CACHE=${GBUILD_PACKAGE_CACHE} + mkdir -p ${BASE_CACHE} ${SOURCES_PATH} + fi + + # Create global faketime wrappers + for prog in ${FAKETIME_PROGS}; do + echo '#!/bin/bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + + # Create per-host faketime wrappers + for i in $HOSTS; do + for prog in ${FAKETIME_HOST_PROGS}; do + echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + export PATH=${WRAP_DIR}:${PATH} + + cd bitcoin + BASEPREFIX=`pwd`/depends + # Build dependencies for each host + # disable building the GUI as Qt needs to be built for specific devices + for i in $HOSTS; do + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" NO_QT=1 + done + + # Create the release tarball using (arbitrarily) the first host + ./autogen.sh + ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` + make dist + SOURCEDIST=`echo bitcoin-*.tar.gz` + DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` + # Correct tar file order + mkdir -p temp + pushd temp + tar xf ../$SOURCEDIST + find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST + popd + + ORIGPATH="$PATH" + # Extract the release tarball into a dir for each host and build + for i in ${HOSTS}; do + export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + mkdir -p distsrc-${i} + cd distsrc-${i} + INSTALLPATH=`pwd`/installed/${DISTNAME} + mkdir -p ${INSTALLPATH} + tar --strip-components=1 -xf ../$SOURCEDIST + + ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + make ${MAKEOPTS} + make ${MAKEOPTS} -C src check-security + make install-strip + cd installed + find . -name "lib*.la" -delete + find . -name "lib*.a" -delete + rm -rf ${DISTNAME}/lib/pkgconfig + find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + cd ../../ + done + mkdir -p $OUTDIR/src + mv $SOURCEDIST $OUTDIR/src + mv ${OUTDIR}/${DISTNAME}-arm-*.tar.gz ${OUTDIR}/${DISTNAME}-armhf-cli.tar.gz + diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 06e631746e3..bc4f8b82af4 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -311,7 +311,7 @@ Setting up the Gitian image ------------------------- Gitian needs a virtual image of the operating system to build in. -Currently this is Ubuntu Precise x86_64. +Currently this is Ubuntu Trusty x86_64. This image will be copied and used every time that a build is started to make sure that the build is deterministic. Creating the image will take a while, but only has to be done once. @@ -361,7 +361,7 @@ Output from `gbuild` will look something like Resolving deltas: 100% (41590/41590), done. From https://github.com/bitcoin/bitcoin ... (new tags, new branch etc) - --- Building for precise amd64 --- + --- Building for trusty x86_64 --- Stopping target if it is up Making a new image copy stdin: is not a tty @@ -390,6 +390,7 @@ COMMIT=2014_03_windows_unicode_path ./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml ./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml +./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-linux-armhf.yml ``` Building fully offline @@ -456,6 +457,7 @@ in `gitian.sigs` to your signing machine and do ```bash gpg --detach-sign ${VERSION}-linux/${SIGNER}/bitcoin-linux-build.assert + gpg --detach-sign ${VERSION}-linux/${SIGNER}/bitcoin-linux-armhf-build.assert gpg --detach-sign ${VERSION}-win/${SIGNER}/bitcoin-win-build.assert gpg --detach-sign ${VERSION}-osx-unsigned/${SIGNER}/bitcoin-osx-build.assert ``` diff --git a/doc/release-process.md b/doc/release-process.md index e478b22101f..b4d0561b27b 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -91,8 +91,9 @@ The gbuild invocations below DO NOT DO THIS by default. ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml - mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ - + ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux-armhf.yml + ./bin/gsign --signer $SIGNER --release ${VERSION}-linux-armhf --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux-armhf.yml + mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz @@ -106,10 +107,11 @@ The gbuild invocations below DO NOT DO THIS by default. Build output expected: 1. source tarball (bitcoin-${VERSION}.tar.gz) - 2. linux 32-bit and 64-bit dist tarballs (bitcoin-${VERSION}-linux[32|64].tar.gz) + 2. linux 32-bit (i386) and 64-bit (x86_64) dist tarballs (bitcoin-${VERSION}-linux[32|64].tar.gz) + 3. linux 32-bit (armhf) dist tarball (bitcoin-${VERSION}-armhf-cli.tar.gz) 3. windows 32-bit and 64-bit unsigned installers and dist zips (bitcoin-${VERSION}-win[32|64]-setup-unsigned.exe, bitcoin-${VERSION}-win[32|64].zip) 4. OS X unsigned installer and dist tarball (bitcoin-${VERSION}-osx-unsigned.dmg, bitcoin-${VERSION}-osx64.tar.gz) - 5. Gitian signatures (in gitian.sigs/${VERSION}-/(your Gitian key)/ + 5. Gitian signatures (in gitian.sigs/${VERSION}-/(your Gitian key)/ ###Verify other gitian builders signatures to your own. (Optional) @@ -131,6 +133,7 @@ Commit your signature to gitian.sigs: pushd gitian.sigs git add ${VERSION}-linux/${SIGNER} + git add ${VERSION}-linux-armhf/${SIGNER} git add ${VERSION}-win-unsigned/${SIGNER} git add ${VERSION}-osx-unsigned/${SIGNER} git commit -a From 2e568375ea3410a67ed4d7cb18a2cabd4ece0580 Mon Sep 17 00:00:00 2001 From: Barnabas Debreczeni Date: Sat, 5 Mar 2016 15:21:22 +0100 Subject: [PATCH 2/2] Gitian: fix check-symbols for armhf builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amrhf builds leak Boost symbols, so @laanwj’s linker script hack was added back to armhf builds. Also added ld-linux-armhf.so.3 to the list of allowed libraries in symbol-check.py. --- contrib/devtools/symbol-check.py | 1 + .../gitian-descriptors/gitian-linux-armhf.yml | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 4ad5136f79e..7ea6b5c97c3 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -62,6 +62,7 @@ ALLOWED_LIBRARIES = { 'librt.so.1', # real-time (clock) 'ld-linux-x86-64.so.2', # 64-bit dynamic linker 'ld-linux.so.2', # 32-bit dynamic linker +'ld-linux-armhf.so.3', # 32-bit armhf dynamic linker # bitcoin-qt only 'libX11-xcb.so.1', # part of X11 'libX11.so.6', # part of X11 diff --git a/contrib/gitian-descriptors/gitian-linux-armhf.yml b/contrib/gitian-descriptors/gitian-linux-armhf.yml index c47b9f5571f..020e2c2dff6 100644 --- a/contrib/gitian-descriptors/gitian-linux-armhf.yml +++ b/contrib/gitian-descriptors/gitian-linux-armhf.yml @@ -23,9 +23,20 @@ remotes: "dir": "bitcoin" files: [] script: | + # Avoid exporting *any* symbols from the executable + # This avoids conflicts between the libraries statically linked into bitcoin and any + # libraries we may link dynamically (such as Qt and OpenSSL, see issue #4094). + # It also avoids start-up overhead to not export any unnecessary symbols. + # To do this, build a linker script that marks all symbols as local. + LINKER_SCRIPT=$HOME/build/linker_version_script + echo ' + { + local: *; + };' > $LINKER_SCRIPT WRAP_DIR=$HOME/wrapped HOSTS="arm-linux-gnueabihf" - CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" + CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports" + CONFIGLDFLAGS="-static-libstdc++ -Wl,--version-script=$LINKER_SCRIPT" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="date ar ranlib nm strip" @@ -95,9 +106,10 @@ script: | mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST - ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} LDFLAGS="${CONFIGLDFLAGS}" make ${MAKEOPTS} make ${MAKEOPTS} -C src check-security + make ${MAKEOPTS} -C src check-symbols make install-strip cd installed find . -name "lib*.la" -delete