Skip to content

Commit

Permalink
Unify Magisk configuration
Browse files Browse the repository at this point in the history
Introduce monogisk tool
  • Loading branch information
topjohnwu committed Nov 5, 2017
1 parent 8d6f3c2 commit e710848
Show file tree
Hide file tree
Showing 23 changed files with 829 additions and 667 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
out/
obj/
libs/
*.zip
Expand Down
213 changes: 130 additions & 83 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,36 @@ def header(str):
import lzma
import base64

def silentremove(file):
def mv(source, target):
print('mv: {} -> {}'.format(source, target))
shutil.move(source, target)

def cp(source, target):
print('cp: {} -> {}'.format(source, target))
shutil.copyfile(source, target)

def rm(file):
try:
os.remove(file)
except OSError as e:
if e.errno != errno.ENOENT:
raise

def mkdir(path, mode=0o777):
try:
os.mkdir(path, mode)
except:
pass

def mkdir_p(path, mode=0o777):
os.makedirs(path, mode, exist_ok=True)

def zip_with_msg(zipfile, source, target):
if not os.path.exists(source):
error('{} does not exist! Try build \'binary\' and \'apk\' before zipping!'.format(source))
print('zip: {} -> {}'.format(source, target))
zipfile.write(source, target)

def cp(source, target):
print('cp: {} -> {}'.format(source, target))
shutil.copyfile(source, target)

def build_all(args):
build_binary(args)
build_apk(args)
Expand All @@ -67,13 +80,40 @@ def build_binary(args):
# Force update Android.mk timestamp to trigger recompilation
os.utime(os.path.join('jni', 'Android.mk'))

ndk_build = os.path.join(os.environ['ANDROID_HOME'], 'ndk-bundle', 'ndk-build')
debug_flag = '' if args.release else '-DMAGISK_DEBUG'
proc = subprocess.run('{} APP_CFLAGS=\"-DMAGISK_VERSION=\\\"{}\\\" -DMAGISK_VER_CODE={} {}\" -j{}'.format(
ndk_build, args.versionString, args.versionCode, debug_flag, multiprocessing.cpu_count()), shell=True)
cflag = 'APP_CFLAGS=\"-DMAGISK_VERSION=\\\"{}\\\" -DMAGISK_VER_CODE={} {}\"'.format(args.versionString, args.versionCode, debug_flag)

ndk_build = os.path.join(os.environ['ANDROID_HOME'], 'ndk-bundle', 'ndk-build')
# Prebuild
proc = subprocess.run('PRECOMPILE=true {} {} -j{}'.format(ndk_build, cflag, multiprocessing.cpu_count()), shell=True)
if proc.returncode != 0:
error('Build Magisk binary failed!')

print('')
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']:
mkdir_p(os.path.join('out', arch))
with open(os.path.join('out', arch, 'dump.h'), 'w') as dump:
dump.write('#include "stdlib.h"\n')
for binary in ['magisk', 'magiskinit']:
mv(os.path.join('libs', arch, binary), os.path.join('out', arch, binary))
with open(os.path.join('out', arch, binary), 'rb') as bin:
dump.write('const uint8_t {}_dump[] = "'.format(binary))
dump.write(''.join("\\x{:02X}".format(c) for c in lzma.compress(bin.read(), preset=9)))
dump.write('";\n')
print('')

proc = subprocess.run('{} {} -j{}'.format(ndk_build, cflag, multiprocessing.cpu_count()), shell=True)
if proc.returncode != 0:
error('Build Magisk binary failed!')

print('')
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']:
for binary in ['monogisk', 'magiskboot', 'b64xz', 'busybox']:
try:
mv(os.path.join('libs', arch, binary), os.path.join('out', arch, binary))
except:
pass

def build_apk(args):
header('* Building Magisk Manager')

Expand Down Expand Up @@ -104,8 +144,8 @@ def build_apk(args):
# Find the latest build tools
build_tool = sorted(os.listdir(os.path.join(os.environ['ANDROID_HOME'], 'build-tools')))[-1]

silentremove(aligned)
silentremove(release)
rm(aligned)
rm(release)

proc = subprocess.run([
os.path.join(os.environ['ANDROID_HOME'], 'build-tools', build_tool, 'zipalign'),
Expand All @@ -129,13 +169,24 @@ def build_apk(args):
if proc.returncode != 0:
error('Release sign Magisk Manager failed!')

silentremove(unsigned)
silentremove(aligned)
rm(unsigned)
rm(aligned)

mkdir(os.path.join('..', 'out'))
target = os.path.join('..', 'out', 'app-release.apk')
print('')
mv(release, target)
else:
proc = subprocess.run('{} app:assembleDebug'.format(os.path.join('.', 'gradlew')), shell=True)
if proc.returncode != 0:
error('Build Magisk Manager failed!')

source = os.path.join('app', 'build', 'outputs', 'apk', 'debug', 'app-debug.apk')
mkdir(os.path.join('..', 'out'))
target = os.path.join('..', 'out', 'app-debug.apk')
print('')
mv(source, target)

# Return to upper directory
os.chdir('..')

Expand All @@ -145,76 +196,32 @@ def build_snet(args):
if proc.returncode != 0:
error('Build snet extention failed!')
source = os.path.join('snet', 'build', 'outputs', 'apk', 'release', 'snet-release-unsigned.apk')
target = os.path.join('..', 'snet.apk')
mkdir(os.path.join('..', 'out'))
target = os.path.join('..', 'out', 'snet.apk')
print('')
cp(source, target)
mv(source, target)
os.chdir('..')

def sign_adjust_zip(unsigned, output):
signer_name = 'zipsigner-1.0.jar'
jarsigner = os.path.join('java', 'crypto', 'build', 'libs', signer_name)

if os.name != 'nt' and not os.path.exists(os.path.join('ziptools', 'zipadjust')):
header('* Building zipadjust')
# Compile zipadjust
proc = subprocess.run('gcc -o ziptools/zipadjust ziptools/zipadjust_src/*.c -lz', shell=True)
if proc.returncode != 0:
error('Build zipadjust failed!')
if not os.path.exists(jarsigner):
header('* Building ' + signer_name)
os.chdir('java')
proc = subprocess.run('{} crypto:shadowJar'.format(os.path.join('.', 'gradlew')), shell=True)
if proc.returncode != 0:
error('Build {} failed!'.format(signer_name))
os.chdir('..')

header('* Signing / Adjusting Zip')

publicKey = os.path.join('ziptools', 'public.certificate.x509.pem')
privateKey = os.path.join('ziptools', 'private.key.pk8')

# Unsigned->signed
proc = subprocess.run(['java', '-jar', jarsigner,
publicKey, privateKey, unsigned, 'tmp_signed.zip'])
if proc.returncode != 0:
error('First sign flashable zip failed!')

# Adjust zip
proc = subprocess.run([os.path.join('ziptools', 'zipadjust'), 'tmp_signed.zip', 'tmp_adjusted.zip'])
if proc.returncode != 0:
error('Adjust flashable zip failed!')

# Adjusted -> output
proc = subprocess.run(['java', '-jar', jarsigner,
"-m", publicKey, privateKey, 'tmp_adjusted.zip', output])
if proc.returncode != 0:
error('Second sign flashable zip failed!')

# Cleanup
silentremove(unsigned)
silentremove('tmp_signed.zip')
silentremove('tmp_adjusted.zip')

def gen_update_binary():
update_bin = []
binary = os.path.join('libs', 'armeabi-v7a', 'b64xz')
binary = os.path.join('out', 'armeabi-v7a', 'b64xz')
if not os.path.exists(binary):
error('Please build \'binary\' before zipping!')
with open(binary, 'rb') as b64xz:
update_bin.append('#! /sbin/sh\nEX_ARM=\'')
update_bin.append(''.join("\\x{:02X}".format(c) for c in b64xz.read()))
binary = os.path.join('libs', 'x86', 'b64xz')
binary = os.path.join('out', 'x86', 'b64xz')
with open(binary, 'rb') as b64xz:
update_bin.append('\'\nEX_X86=\'')
update_bin.append(''.join("\\x{:02X}".format(c) for c in b64xz.read()))
binary = os.path.join('libs', 'armeabi-v7a', 'busybox')
binary = os.path.join('out', 'armeabi-v7a', 'busybox')
with open(binary, 'rb') as busybox:
update_bin.append('\'\nBB_ARM=')
update_bin.append(base64.b64encode(lzma.compress(busybox.read())).decode('ascii'))
binary = os.path.join('libs', 'x86', 'busybox')
update_bin.append(base64.b64encode(lzma.compress(busybox.read(), preset=9)).decode('ascii'))
binary = os.path.join('out', 'x86', 'busybox')
with open(binary, 'rb') as busybox:
update_bin.append('\nBB_X86=')
update_bin.append(base64.b64encode(lzma.compress(busybox.read())).decode('ascii'))
update_bin.append(base64.b64encode(lzma.compress(busybox.read(), preset=9)).decode('ascii'))
update_bin.append('\n')
with open(os.path.join('scripts', 'update_binary.sh'), 'r') as script:
update_bin.append(script.read())
Expand All @@ -236,17 +243,13 @@ def zip_main(args):

# Binaries
for lib_dir, zip_dir in [('arm64-v8a', 'arm64'), ('armeabi-v7a', 'arm'), ('x86', 'x86'), ('x86_64', 'x64')]:
for binary in ['magisk', 'magiskboot']:
source = os.path.join('libs', lib_dir, binary)
for binary in ['monogisk', 'magiskboot']:
source = os.path.join('out', lib_dir, binary)
target = os.path.join(zip_dir, binary)
zip_with_msg(zipf, source, target)
source = os.path.join('libs', 'arm64-v8a', 'magiskinit')
target = os.path.join('arm64', 'magiskinit')
zip_with_msg(zipf, source, target)

# APK
source = os.path.join('java', 'app', 'build', 'outputs', 'apk',
'release' if args.release else 'debug', 'app-release.apk' if args.release else 'app-debug.apk')
source = os.path.join('out', 'app-release.apk' if args.release else 'app-debug.apk')
target = os.path.join('common', 'magisk.apk')
zip_with_msg(zipf, source, target)

Expand All @@ -268,10 +271,6 @@ def zip_main(args):
source = os.path.join('scripts', 'addon.d.sh')
target = os.path.join('addon.d', '99-magisk.sh')
zip_with_msg(zipf, source, target)
# init.magisk.rc
source = os.path.join('scripts', 'init.magisk.rc')
target = os.path.join('common', 'init.magisk.rc')
zip_with_msg(zipf, source, target)

# Prebuilts
for chromeos in ['futility', 'kernel_data_key.vbprivk', 'kernel.keyblock']:
Expand All @@ -280,7 +279,7 @@ def zip_main(args):

# End of zipping

output = 'Magisk-v{}.zip'.format(args.versionString)
output = os.path.join('out', 'Magisk-v{}.zip'.format(args.versionString))
sign_adjust_zip('tmp_unsigned.zip', output)

def zip_uninstaller(args):
Expand All @@ -299,7 +298,7 @@ def zip_uninstaller(args):

# Binaries
for lib_dir, zip_dir in [('arm64-v8a', 'arm64'), ('armeabi-v7a', 'arm'), ('x86', 'x86'), ('x86_64', 'x64')]:
source = os.path.join('libs', lib_dir, 'magiskboot')
source = os.path.join('out', lib_dir, 'magiskboot')
target = os.path.join(zip_dir, 'magiskboot')
zip_with_msg(zipf, source, target)

Expand All @@ -325,30 +324,78 @@ def zip_uninstaller(args):

# End of zipping

output = 'Magisk-uninstaller-{}.zip'.format(datetime.datetime.now().strftime('%Y%m%d'))
output = os.path.join('out', 'Magisk-uninstaller-{}.zip'.format(datetime.datetime.now().strftime('%Y%m%d')))
sign_adjust_zip('tmp_unsigned.zip', output)

def sign_adjust_zip(unsigned, output):
signer_name = 'zipsigner-1.0.jar'
jarsigner = os.path.join('java', 'crypto', 'build', 'libs', signer_name)

if os.name != 'nt' and not os.path.exists(os.path.join('ziptools', 'zipadjust')):
header('* Building zipadjust')
# Compile zipadjust
proc = subprocess.run('gcc -o ziptools/zipadjust ziptools/zipadjust_src/*.c -lz', shell=True)
if proc.returncode != 0:
error('Build zipadjust failed!')
if not os.path.exists(jarsigner):
header('* Building ' + signer_name)
os.chdir('java')
proc = subprocess.run('{} crypto:shadowJar'.format(os.path.join('.', 'gradlew')), shell=True)
if proc.returncode != 0:
error('Build {} failed!'.format(signer_name))
os.chdir('..')

header('* Signing / Adjusting Zip')

publicKey = os.path.join('ziptools', 'public.certificate.x509.pem')
privateKey = os.path.join('ziptools', 'private.key.pk8')

# Unsigned->signed
proc = subprocess.run(['java', '-jar', jarsigner,
publicKey, privateKey, unsigned, 'tmp_signed.zip'])
if proc.returncode != 0:
error('First sign flashable zip failed!')

# Adjust zip
proc = subprocess.run([os.path.join('ziptools', 'zipadjust'), 'tmp_signed.zip', 'tmp_adjusted.zip'])
if proc.returncode != 0:
error('Adjust flashable zip failed!')

# Adjusted -> output
proc = subprocess.run(['java', '-jar', jarsigner,
"-m", publicKey, privateKey, 'tmp_adjusted.zip', output])
if proc.returncode != 0:
error('Second sign flashable zip failed!')

# Cleanup
rm(unsigned)
rm('tmp_signed.zip')
rm('tmp_adjusted.zip')

def cleanup(args):
if len(args.target) == 0:
args.target = ['binary', 'java', 'zip']

if 'binary' in args.target:
header('* Cleaning binaries')
subprocess.run(os.path.join(os.environ['ANDROID_HOME'], 'ndk-bundle', 'ndk-build') + ' clean', shell=True)
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']:
shutil.rmtree(os.path.join('out', arch), ignore_errors=True)

if 'java' in args.target:
header('* Cleaning java')
os.chdir('java')
subprocess.run('{} clean'.format(os.path.join('.', 'gradlew')), shell=True)
os.chdir('..')
silentremove('snet.apk')
for f in os.listdir('out'):
if '.apk' in f:
rm(os.path.join('out', f))

if 'zip' in args.target:
header('* Cleaning zip files')
for f in os.listdir('.'):
for f in os.listdir('out'):
if '.zip' in f:
print('rm {}'.format(f))
silentremove(f)
rm(os.path.join('out', f))

parser = argparse.ArgumentParser(description='Magisk build script')
parser.add_argument('--release', action='store_true', help='compile Magisk for release')
Expand Down
2 changes: 1 addition & 1 deletion java
Submodule java updated 36 files
+4 −7 app/src/main/java/com/topjohnwu/magisk/AboutActivity.java
+9 −17 app/src/main/java/com/topjohnwu/magisk/FlashActivity.java
+7 −7 app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java
+9 −11 app/src/main/java/com/topjohnwu/magisk/MagiskLogFragment.java
+28 −176 app/src/main/java/com/topjohnwu/magisk/MagiskManager.java
+25 −8 app/src/main/java/com/topjohnwu/magisk/MainActivity.java
+4 −5 app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java
+43 −44 app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java
+131 −5 app/src/main/java/com/topjohnwu/magisk/SplashActivity.java
+3 −14 app/src/main/java/com/topjohnwu/magisk/adapters/ApplicationAdapter.java
+7 −11 app/src/main/java/com/topjohnwu/magisk/asyncs/CheckSafetyNet.java
+5 −10 app/src/main/java/com/topjohnwu/magisk/asyncs/CheckUpdates.java
+0 −54 app/src/main/java/com/topjohnwu/magisk/asyncs/DownloadBusybox.java
+2 −1 app/src/main/java/com/topjohnwu/magisk/asyncs/FlashZip.java
+33 −13 app/src/main/java/com/topjohnwu/magisk/asyncs/HideManager.java
+29 −26 app/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java
+2 −1 app/src/main/java/com/topjohnwu/magisk/asyncs/LoadModules.java
+3 −2 app/src/main/java/com/topjohnwu/magisk/asyncs/ProcessRepoZip.java
+12 −4 app/src/main/java/com/topjohnwu/magisk/asyncs/RestoreStockBoot.java
+8 −13 app/src/main/java/com/topjohnwu/magisk/asyncs/UpdateRepos.java
+4 −8 app/src/main/java/com/topjohnwu/magisk/components/Activity.java
+5 −9 app/src/main/java/com/topjohnwu/magisk/container/Repo.java
+2 −1 app/src/main/java/com/topjohnwu/magisk/database/RepoDatabaseHelper.java
+1 −18 app/src/main/java/com/topjohnwu/magisk/database/SuDatabaseHelper.java
+3 −3 app/src/main/java/com/topjohnwu/magisk/receivers/ManagerUpdate.java
+3 −5 app/src/main/java/com/topjohnwu/magisk/services/OnBootIntentService.java
+1 −1 app/src/main/java/com/topjohnwu/magisk/services/UpdateCheckService.java
+9 −14 app/src/main/java/com/topjohnwu/magisk/superuser/SuReceiver.java
+5 −10 app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java
+2 −2 app/src/main/java/com/topjohnwu/magisk/utils/BootSigner.java
+136 −0 app/src/main/java/com/topjohnwu/magisk/utils/Const.java
+3 −4 app/src/main/java/com/topjohnwu/magisk/utils/Logger.java
+36 −37 app/src/main/java/com/topjohnwu/magisk/utils/ShowUI.java
+13 −6 app/src/main/java/com/topjohnwu/magisk/utils/Utils.java
+1 −4 app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java
+1 −1 app/src/main/res/xml/app_settings.xml
Loading

0 comments on commit e710848

Please sign in to comment.