Skip to content

reproducible build process #141

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 9, 2014
4 changes: 2 additions & 2 deletions .classpath
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="lib" path="libs/commons-codec.jar"/>
<classpathentry kind="lib" path="libs/guava-r09.jar"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
41 changes: 30 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,31 @@ SQLCIPHER_DIR := ${EXTERNAL_DIR}/sqlcipher
LICENSE := SQLCIPHER_LICENSE
ASSETS_DIR := assets
OPENSSL_DIR := ${EXTERNAL_DIR}/openssl
GIT_DESCRIBE := $(shell git describe)
LATEST_TAG := $(shell git tag | sort -r | head -1)
SECOND_LATEST_TAG := $(shell git tag | sort -r | head -2 | tail -1)
RELEASE_DIR := sqlipher-for-android-${LATEST_TAG}
CHANGE_LOG_HEADER := "Changes included in the ${LATEST_TAG} release of SQLCipher for Android:"
RELEASE_DIR := sqlcipher-for-android-${GIT_DESCRIBE}
CHANGE_LOG_HEADER := "Changes included in the ${GIT_DESCRIBE} release of SQLCipher for Android:"
README := ${RELEASE_DIR}/README

# Use faketime to freeze time to make for reproducible builds.
# faketime needs to have a very specific timestamp format in order to freeze
# time. The time needs to be frozen so that the timestamps don't depend on
# the speed of the machine that the build process is running on. See `man
# faketime` for more info on the "advanced timestamp format". Also, force
# time to UTC so its always the same on all machines.
ifeq ($(shell if which faketime > /dev/null; then echo faketime; fi),faketime)
export TZ=UTC
TIMESTAMP := $(shell faketime -f "`git log -n1 --format=format:%ai`" \
date -u '+%Y-%m-%d %H:%M:%S')
TOUCH := touch -t $(shell faketime -f "`git log -n1 --format=format:%ai`" \
date -u '+%Y%m%d%H%M.%S')
# frozen time
FAKETIME := faketime -f "$(TIMESTAMP)"
# time moving at 5% of normal speed
FAKETIME_5 := faketime -f "@$(TIMESTAMP) x0.05"
endif

init:
git submodule update --init
android update project -p .
Expand All @@ -23,18 +42,16 @@ all: build-external build-jni build-java copy-libs

build-external:
cd ${EXTERNAL_DIR} && \
make -f Android.mk build-local-hack && \
ndk-build NDK_LIBS_OUT=$(EXTERNAL_DIR)/libs && \
make -f Android.mk copy-libs-hack
$(FAKETIME) make -f Android.mk build-local-hack && \
$(FAKETIME) ndk-build NDK_LIBS_OUT=$(EXTERNAL_DIR)/libs && \
$(FAKETIME) make -f Android.mk copy-libs-hack

build-jni:
cd ${JNI_DIR} && \
ndk-build NDK_LIBS_OUT=$(JNI_DIR)/libs
$(FAKETIME) ndk-build NDK_LIBS_OUT=$(JNI_DIR)/libs

build-java:
ant release && \
cd ${CURDIR}/bin/classes && \
jar -cvf sqlcipher.jar .
$(FAKETIME_5) ant release

release:
-rm -rf ${RELEASE_DIR}
Expand All @@ -45,7 +62,10 @@ release:
cp ${LICENSE} ${RELEASE_DIR}
printf "%s\n\n" ${CHANGE_LOG_HEADER} > ${README}
git log --pretty=format:' * %s' ${SECOND_LATEST_TAG}..${LATEST_TAG} >> ${README}
zip -r ${RELEASE_DIR}.zip ${RELEASE_DIR}
# fix the timestamp on the files to include in the zipball
find ${RELEASE_DIR} | xargs $(TOUCH)
ls -lR ${RELEASE_DIR}
find ${RELEASE_DIR} | sort -u | $(FAKETIME) zip -@9 ${RELEASE_DIR}.zip
rm -rf ${RELEASE_DIR}

clean:
Expand All @@ -71,7 +91,6 @@ copy-libs:
${LIBRARY_ROOT}/armeabi && \
cp ${JNI_DIR}/libs/armeabi/libdatabase_sqlcipher.so \
${LIBRARY_ROOT}/armeabi && \
cp ${CURDIR}/bin/classes/sqlcipher.jar ${LIBRARY_ROOT} && \
cp ${EXTERNAL_DIR}/libs/armeabi/libstlport_shared.so \
${LIBRARY_ROOT}/armeabi
mkdir -p ${LIBRARY_ROOT}/x86
Expand Down
66 changes: 66 additions & 0 deletions compare-to-official-release
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/sh

if [ $# -ne 2 ]; then
echo "Usage: $0 /path/to/sqlcipher-for-android.zip /another/sqlcipher-for-android.zip"
exit 1
fi

set -e
set -x

test -e "$1"
test -e "$2"

tmpdir=`mktemp -d /tmp/.compare-zips.XXXXXXXXXX`
zip1=$(basename $1)
zip2=$(basename $2)
sourcedir1=$(cd `dirname $1` && pwd)
sourcedir2=$(cd `dirname $2` && pwd)
zipname1=`echo $zip1 | sed 's,\.zip$,,'`
zipname2=`echo $zip2 | sed 's,\.zip$,,'`
dir1=$tmpdir/`echo $(dirname $1) | sed 's,[/ ],_,g'`-$zipname1
dir2=$tmpdir/`echo $(dirname $2) | sed 's,[/ ],_,g'`-$zipname2

mkdir -p $dir1
cd $dir1
unzip "$sourcedir1/$zip1"
# strip the full path to the zip for the comparison
unzip -l "$sourcedir1/$zip1" | sed 's,^\(Archive:\s\s*\)/.*/,\1,' > $dir1/unzip-l.txt
unzip -lv "$sourcedir1/$zip1" | sed 's,^\(Archive:\s\s*\)/.*/,\1,' > $dir1/unzip-lv.txt
mkdir -p $dir1/$zipname1/libs/sqlcipher
cd $dir1/$zipname1/libs/sqlcipher
unzip ../sqlcipher.jar
unzip -l ../sqlcipher.jar > unzip-l.txt
unzip -lv ../sqlcipher.jar > unzip-lv.txt
mkdir -p $dir1/$zipname1/libs/sqlcipher-javadoc
cd $dir1/$zipname1/libs/sqlcipher-javadoc
unzip ../sqlcipher-javadoc.jar
unzip -l ../sqlcipher-javadoc.jar > unzip-l.txt
unzip -lv ../sqlcipher-javadoc.jar > unzip-lv.txt

mkdir -p $dir2
cd $dir2
unzip "$sourcedir2/$zip2"
# strip the full path to the zip for the comparison
unzip -l "$sourcedir2/$zip2" | sed 's,^\(Archive:\s\s*\)/.*/,\1,' > $dir2/unzip-l.txt
unzip -lv "$sourcedir2/$zip2" | sed 's,^\(Archive:\s\s*\)/.*/,\1,' > $dir2/unzip-lv.txt
mkdir -p $dir2/$zipname2/libs/sqlcipher
cd $dir2/$zipname2/libs/sqlcipher
unzip ../sqlcipher.jar
unzip -l ../sqlcipher.jar > unzip-l.txt
unzip -lv ../sqlcipher.jar > unzip-lv.txt
mkdir -p $dir2/$zipname2/libs/sqlcipher-javadoc
cd $dir2/$zipname2/libs/sqlcipher-javadoc
unzip ../sqlcipher-javadoc.jar
unzip -l ../sqlcipher-javadoc.jar > unzip-l.txt
unzip -lv ../sqlcipher-javadoc.jar > unzip-lv.txt

if which meld > /dev/null; then
meld $dir1 $dir2
elif which opendiff > /dev/null; then
opendiff $dir1 $dir2
else
echo "ERROR: meld or opendiff required for the comparison!"
fi

rm -rf $tmpdir/
65 changes: 65 additions & 0 deletions custom_rules.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules">

<condition property="ndk.dir" value="${env.ANDROID_NDK}">
<isset property="env.ANDROID_NDK" />
</condition>

<target name="-getgitdetails" >
<exec executable="git" outputproperty="git.describe">
<arg value="describe"/>
</exec>
<exec executable="git" outputproperty="git.revision">
<arg value="rev-parse"/>
<arg value="HEAD"/>
</exec>
</target>

<target name="-javadoc" description="Generate Javadocs">
<property name="javadoc.jar.name" value="${out.dir}/sqlcipher-javadoc.jar" />
<javadoc sourcepath="${source.dir}"
destdir="${out.dir}/javadoc"
packagenames="net.sqlcipher.*"
windowtitle="SQLCipher for Android"
doctitle="SQLCipher for Android" />
<delete file="${javadoc.jar.name}"/>
<jar destfile="${javadoc.jar.name}"
includes="net/sqlcipher/**"
basedir="${out.dir}/javadoc">
<manifest>
<attribute name="Implementation-Vendor" value="Zetetic"/>
<attribute name="Implementation-Title" value="SQLCipher for Android"/>
<attribute name="Implementation-URL" value="https://www.zetetic.net/sqlcipher/open-source"/>
<attribute name="Implementation-Version" value="${git.describe}"/>
<attribute name="Git-Revision" value="${git.revision}"/>
</manifest>
</jar>
</target>

<target name="-post-build" depends="-getgitdetails,-javadoc">
<property name="jar.dir" value="libs" />
<property name="jar.name" value="${jar.dir}/sqlcipher.jar" />
<property file="${sdk.dir}/tools/source.properties" />
<exec executable="cat" outputproperty="ndk.release">
<arg value="${ndk.dir}/RELEASE.TXT"/>
</exec>
<delete file="${jar.name}"/>
<mkdir dir="${jar.dir}" />
<jar destfile="${jar.name}"
includes="net/sqlcipher/**"
basedir="${out.classes.absolute.dir}">
<manifest>
<attribute name="Implementation-Vendor" value="Zetetic"/>
<attribute name="Implementation-Title" value="SQLCipher for Android"/>
<attribute name="Implementation-URL" value="https://www.zetetic.net/sqlcipher/open-source"/>
<attribute name="Implementation-Version" value="${git.describe}"/>
<attribute name="Git-Revision" value="${git.revision}"/>
<attribute name="Android-SDK-Release" value="${Pkg.Revision}"/>
<attribute name="Android-SDK-Host-OS" value="${Archive.HostOs}"/>
<attribute name="Android-NDK-Release" value="${ndk.release}"/>
</manifest>
</jar>
<copy file="${out.dir}/sqlcipher-javadoc.jar" todir="${jar.dir}" preservelastmodified="true" overwrite="true"/>
</target>

</project>