First version that only builds obfs4proxy for Android and Linux

parents
/.idea
/__pycache__
/toolchain
/jni
/android-ndk
/android-ndk.zip
/obfs4proxy_*.zip
/obfs4
\ No newline at end of file
#!/usr/bin/env python3
from glob import glob
import os
from shutil import move, rmtree
from subprocess import check_call
from utils import get_build_versions, ex, get_sha256, fail, zip_file
NDK_DIR = 'android-ndk'
REPO_DIR = 'obfs4'
SOURCE = 'obfs4/obfs4proxy/*'
def main():
# Get the latest versions for building
versions = get_build_versions(None)
# Setup Android NDK
setup_android_ndk(versions)
# Clone or reset the git repository
prepare_repo(versions)
# Install dependencies (of git HEAD)
ex(['go', 'get', '-d', versions['obfs4']['got-get']])
# Build for various Android versions
build_android()
# Build for 64-bit Linux
build_linux()
def setup_android_ndk(versions):
if os.path.isdir(NDK_DIR):
# check that we are using the correct NDK
from configparser import ConfigParser
config = ConfigParser()
with open(os.path.join(NDK_DIR, 'source.properties'), 'rt') as f:
config.read_string('[default]\n' + str(f.read()))
revision = config.get('default', 'Pkg.Revision')
if revision != versions['ndk']['revision']:
print("Existing Android NDK has unexpected revision (%s). Deleting..." % revision)
rmtree(NDK_DIR)
if not os.path.isdir(NDK_DIR):
# download Android NDK
print("Downloading Android NDK...")
check_call(['wget', '-c', '--no-verbose', versions['ndk']['url'], '-O', 'android-ndk.zip'])
# check sha256 hash on downloaded file
is_hash = get_sha256('android-ndk.zip')
if is_hash != versions['ndk']['sha256']:
fail("Android NDK checksum does not match, should be %s" % is_hash)
# install the NDK
print("Unpacking Android NDK...")
ndk_dir_tmp = NDK_DIR + '-tmp'
check_call(['unzip', '-q', 'android-ndk.zip', '-d', ndk_dir_tmp])
content = os.listdir(ndk_dir_tmp)
if len(content) == 1 and content[0].startswith('android-ndk-r'):
move(os.path.join(ndk_dir_tmp, content[0]), NDK_DIR)
os.rmdir(ndk_dir_tmp)
else:
fail("Could not extract NDK: %s" % str(content))
os.putenv('ANDROID_NDK_HOME', os.path.abspath(NDK_DIR))
def prepare_repo(versions):
if os.path.isdir(REPO_DIR):
# get latest commits and tags from remote
check_call(['git', 'fetch', 'origin'], cwd=REPO_DIR)
else:
# clone repo
url = versions['obfs4']['url']
check_call(['git', 'clone', url, REPO_DIR])
# checkout tag
check_call(['git', 'checkout', '-f', versions['obfs4']['tag']], cwd=REPO_DIR)
# undo all changes
check_call(['git', 'reset', '--hard'], cwd=REPO_DIR)
# clean all untracked files and directories (-d) from repo
check_call(['git', 'clean', '-dffx'], cwd=REPO_DIR)
def build_android():
env = os.environ.copy()
env['GOARCH'] = "arm"
env['GOARM'] = "7"
build_android_arch(env, "arm-linux-androideabi", ndk_arch="arm", pie=False)
env = os.environ.copy()
env['GOARCH'] = "arm"
env['GOARM'] = "7"
build_android_arch(env, "arm-linux-androideabi", ndk_arch="arm", pie=True)
env = os.environ.copy()
env['GOARCH'] = "386"
build_android_arch(env, "i686-linux-android", ndk_arch="x86", pie=False)
env = os.environ.copy()
env['GOARCH'] = "386"
build_android_arch(env, "i686-linux-android", ndk_arch="x86", pie=True)
def build_android_arch(env, tool, ndk_arch, pie):
toolchain = os.path.join("toolchain", ndk_arch)
if not os.path.isdir(toolchain):
toolchain_maker = os.path.join(NDK_DIR, "build", "tools", "make-standalone-toolchain.sh")
ex([toolchain_maker, "--arch=%s" % ndk_arch, "--install-dir=%s" % toolchain])
env['CC'] = "%s/bin/%s-clang" % (os.path.abspath(toolchain), tool)
env['CGO_ENABLED'] = "1"
env['GOOS'] = "android"
build_mode = "pie" if pie else "exe"
ex(['go', 'build', '-buildmode=%s' % build_mode, '-o', 'obfs4proxy'] + glob(SOURCE), env=env)
ex(['%s/bin/%s-strip' % (toolchain, tool), '-D', 'obfs4proxy'])
pie_suffix = '_pie' if pie else ''
zip_file('obfs4proxy', 'obfs4proxy_%s%s.zip' % (ndk_arch, pie_suffix))
os.remove('obfs4proxy')
def build_linux():
ex(['go', 'build', '-o', 'obfs4proxy'] + glob(SOURCE))
ex(['strip', '-D', 'obfs4proxy'])
zip_file('obfs4proxy', 'obfs4proxy_linux-x86_64.zip')
os.remove('obfs4proxy')
def get_source_files():
files = []
for file_name in glob(SOURCE):
print(file_name)
return files
if __name__ == "__main__":
main()
import hashlib
import json
import sys
from collections import OrderedDict
from subprocess import check_call
REPO_DIR = 'tor-android'
def get_version():
if len(sys.argv) > 2:
fail("Usage: %s [version tag]" % sys.argv[0])
return sys.argv[1] if len(sys.argv) > 1 else None
def get_build_versions(tag):
# load versions and their dependencies
with open('versions.json', 'r') as f:
versions = json.load(f, object_pairs_hook=OrderedDict)
if tag is None:
# take top-most version
tag = next(iter(versions))
return versions[tag]
def ex(args, env=None):
print("+ %s" % " ".join(args))
check_call(args, env=env)
def fail(msg=""):
sys.stderr.write("Error: %s\n" % msg)
sys.exit(1)
def get_sha256(filename, block_size=65536):
sha256 = hashlib.sha256()
with open(filename, 'rb') as f:
for block in iter(lambda: f.read(block_size), b''):
sha256.update(block)
return sha256.hexdigest()
def zip_file(file_name, zip_name):
ex(['touch', '--no-dereference', '-t', '197001010000.00', file_name])
ex(['zip', '-X', zip_name, file_name])
{
"0.0.7": {
"obfs4": {
"url": "https://git.torproject.org/pluggable-transports/obfs4.git",
"got-get": "git.torproject.org/pluggable-transports/obfs4.git/obfs4proxy",
"tag": "obfs4proxy-0.0.7"
},
"ndk": {
"url": "https://dl.google.com/android/repository/android-ndk-r18-linux-x86_64.zip",
"revision": "18.0.5002713",
"sha256": "c413dd014edc37f822d0dc88fabc05b64232d07d5c6e9345224e47073fdf140b"
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment