Support compiling against lower SDK

Reduce even more size for static binaries
This commit is contained in:
topjohnwu 2018-07-13 05:41:29 +08:00
parent 7779c3e372
commit 1affb91f17
8 changed files with 99 additions and 59 deletions

View File

@ -114,7 +114,7 @@ def build_binary(args):
if 'magisk' in targets: if 'magisk' in targets:
# Magisk is special case as it is a dependency of magiskinit # Magisk is special case as it is a dependency of magiskinit
proc = subprocess.run('{} -C native {} B_MAGISK=1 -j{}'.format(ndk_build, base_flags, cpu_count), shell=True) proc = subprocess.run('{} -C native {} B_MAGISK=1 -j{}'.format(ndk_build, base_flags, cpu_count), shell=True, stdout=STDOUT)
if proc.returncode != 0: if proc.returncode != 0:
error('Build Magisk binary failed!') error('Build Magisk binary failed!')
collect_binary() collect_binary()
@ -126,15 +126,6 @@ def build_binary(args):
flags += ' B_BXZ=1' flags += ' B_BXZ=1'
old_platform = True old_platform = True
if old_platform:
proc = subprocess.run('{} -C native OLD_PLAT=1 {} -j{}'.format(ndk_build, flags, cpu_count), shell=True)
if proc.returncode != 0:
error('Build binaries failed!')
collect_binary()
other = False
flags = base_flags
if 'magiskinit' in targets: if 'magiskinit' in targets:
for arch in archs: for arch in archs:
bin_file = os.path.join('native', 'out', arch, 'magisk') bin_file = os.path.join('native', 'out', arch, 'magisk')
@ -153,18 +144,27 @@ def build_binary(args):
xz_dump(src, out, 'manager_xz') xz_dump(src, out, 'manager_xz')
flags += ' B_INIT=1' flags += ' B_INIT=1'
other = True old_platform = True
if 'magiskboot' in targets: if 'magiskboot' in targets:
flags += ' B_BOOT=1' flags += ' B_BOOT=1'
other = True old_platform = True
if old_platform:
proc = subprocess.run('{} -C native OLD_PLAT=1 {} -j{}'.format(ndk_build, flags, cpu_count), shell=True, stdout=STDOUT)
if proc.returncode != 0:
error('Build binaries failed!')
collect_binary()
other = False
flags = base_flags
if 'busybox' in targets: if 'busybox' in targets:
flags += ' B_BB=1' flags += ' B_BB=1'
other = True other = True
if other: if other:
proc = subprocess.run('{} -C native {} -j{}'.format(ndk_build, flags, cpu_count), shell=True) proc = subprocess.run('{} -C native {} -j{}'.format(ndk_build, flags, cpu_count), shell=True, stdout=STDOUT)
if proc.returncode != 0: if proc.returncode != 0:
error('Build binaries failed!') error('Build binaries failed!')
collect_binary() collect_binary()
@ -203,7 +203,7 @@ def build_apk(args):
if not os.path.exists('release-key.jks'): if not os.path.exists('release-key.jks'):
error('Please generate a java keystore and place it in \'release-key.jks\'') error('Please generate a java keystore and place it in \'release-key.jks\'')
proc = subprocess.run('{} app:assembleRelease'.format(os.path.join('.', 'gradlew.bat' if os.name == 'nt' else 'gradlew')), shell=True) proc = subprocess.run('{} app:assembleRelease'.format(os.path.join('.', 'gradlew.bat' if os.name == 'nt' else 'gradlew')), shell=True, stdout=STDOUT)
if proc.returncode != 0: if proc.returncode != 0:
error('Build Magisk Manager failed!') error('Build Magisk Manager failed!')
@ -219,7 +219,7 @@ def build_apk(args):
header('Output: ' + release) header('Output: ' + release)
rm(unsigned) rm(unsigned)
else: else:
proc = subprocess.run('{} app:assembleDebug'.format(os.path.join('.', 'gradlew.bat' if os.name == 'nt' else 'gradlew')), shell=True) proc = subprocess.run('{} app:assembleDebug'.format(os.path.join('.', 'gradlew.bat' if os.name == 'nt' else 'gradlew')), shell=True, stdout=STDOUT)
if proc.returncode != 0: if proc.returncode != 0:
error('Build Magisk Manager failed!') error('Build Magisk Manager failed!')
@ -234,7 +234,7 @@ def build_apk(args):
header('Output: ' + target) header('Output: ' + target)
def build_snet(args): def build_snet(args):
proc = subprocess.run('{} snet:assembleRelease'.format(os.path.join('.', 'gradlew.bat' if os.name == 'nt' else 'gradlew')), shell=True) proc = subprocess.run('{} snet:assembleRelease'.format(os.path.join('.', 'gradlew.bat' if os.name == 'nt' else 'gradlew')), shell=True, stdout=STDOUT)
if proc.returncode != 0: if proc.returncode != 0:
error('Build snet extention failed!') error('Build snet extention failed!')
source = os.path.join('snet', 'build', 'outputs', 'apk', 'release', 'snet-release-unsigned.apk') source = os.path.join('snet', 'build', 'outputs', 'apk', 'release', 'snet-release-unsigned.apk')
@ -390,7 +390,7 @@ def sign_adjust_zip(unsigned, output):
if not os.path.exists(jarsigner): if not os.path.exists(jarsigner):
header('* Building ' + signer_name) header('* Building ' + signer_name)
proc = subprocess.run('{} utils:shadowJar'.format(os.path.join('.', 'gradlew.bat' if os.name == 'nt' else 'gradlew')), shell=True) proc = subprocess.run('{} utils:shadowJar'.format(os.path.join('.', 'gradlew.bat' if os.name == 'nt' else 'gradlew')), shell=True, stdout=STDOUT)
if proc.returncode != 0: if proc.returncode != 0:
error('Build {} failed!'.format(signer_name)) error('Build {} failed!'.format(signer_name))
@ -408,12 +408,12 @@ def cleanup(args):
if 'native' in args.target: if 'native' in args.target:
header('* Cleaning native') header('* Cleaning native')
subprocess.run(ndk_build + ' -C native B_MAGISK=1 B_INIT=1 B_BOOT=1 B_BXZ=1 B_BB=1 clean', shell=True) subprocess.run(ndk_build + ' -C native B_MAGISK=1 B_INIT=1 B_BOOT=1 B_BXZ=1 B_BB=1 clean', shell=True, stdout=STDOUT)
shutil.rmtree(os.path.join('native', 'out'), ignore_errors=True) shutil.rmtree(os.path.join('native', 'out'), ignore_errors=True)
if 'java' in args.target: if 'java' in args.target:
header('* Cleaning java') header('* Cleaning java')
subprocess.run('{} app:clean snet:clean utils:clean'.format(os.path.join('.', 'gradlew')), shell=True) subprocess.run('{} app:clean snet:clean utils:clean'.format(os.path.join('.', 'gradlew')), shell=True, stdout=STDOUT)
def parse_config(): def parse_config():
c = {} c = {}
@ -446,13 +446,14 @@ def parse_config():
config = parse_config() config = parse_config()
parser = argparse.ArgumentParser(description='Magisk build script') parser = argparse.ArgumentParser(description='Magisk build script')
parser.add_argument('--release', action='store_true', help='compile Magisk for release') parser.add_argument('-r', '--release', action='store_true', help='compile Magisk for release')
parser.add_argument('-v', '--verbose', action='store_true', help='verbose output')
subparsers = parser.add_subparsers(title='actions') subparsers = parser.add_subparsers(title='actions')
all_parser = subparsers.add_parser('all', help='build everything (binaries/apks/zips)') all_parser = subparsers.add_parser('all', help='build everything (binaries/apks/zips)')
all_parser.set_defaults(func=build_all) all_parser.set_defaults(func=build_all)
binary_parser = subparsers.add_parser('binary', help='build binaries. target: magisk magiskinit magiskboot busybox b64xz') binary_parser = subparsers.add_parser('binary', help='build binaries. Target: magisk magiskinit magiskboot busybox b64xz')
binary_parser.add_argument('target', nargs='*') binary_parser.add_argument('target', nargs='*')
binary_parser.set_defaults(func=build_binary) binary_parser.set_defaults(func=build_binary)
@ -468,7 +469,7 @@ zip_parser.set_defaults(func=zip_main)
uninstaller_parser = subparsers.add_parser('uninstaller', help='create flashable uninstaller') uninstaller_parser = subparsers.add_parser('uninstaller', help='create flashable uninstaller')
uninstaller_parser.set_defaults(func=zip_uninstaller) uninstaller_parser.set_defaults(func=zip_uninstaller)
clean_parser = subparsers.add_parser('clean', help='cleanup. target: binary java zip') clean_parser = subparsers.add_parser('clean', help='cleanup. Target: native java')
clean_parser.add_argument('target', nargs='*') clean_parser.add_argument('target', nargs='*')
clean_parser.set_defaults(func=cleanup) clean_parser.set_defaults(func=cleanup)
@ -477,5 +478,5 @@ if len(sys.argv) == 1:
sys.exit(1) sys.exit(1)
args = parser.parse_args() args = parser.parse_args()
STDOUT = None if args.verbose else subprocess.DEVNULL
args.func(args) args.func(args)

View File

@ -4,7 +4,8 @@ APP_CFLAGS := -std=gnu99 ${MAGISK_DEBUG} \
APP_CPPFLAGS := -std=c++11 APP_CPPFLAGS := -std=c++11
APP_SHORT_COMMANDS := true APP_SHORT_COMMANDS := true
ifdef OLD_PLAT ifdef OLD_PLAT
APP_PLATFORM := android-9 APP_PLATFORM := android-16
APP_CFLAGS += -Wno-implicit-function-declaration
else else
APP_PLATFORM := android-21 APP_PLATFORM := android-21
endif endif

View File

@ -579,7 +579,7 @@ void startup() {
while((entry = xreaddir(dir))) { while((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
snprintf(buf, PATH_MAX, "/root/%s", entry->d_name); snprintf(buf, PATH_MAX, "/root/%s", entry->d_name);
symlinkat(buf, sbin, entry->d_name); xsymlinkat(buf, sbin, entry->d_name);
} }
close(sbin); close(sbin);

View File

@ -382,9 +382,9 @@ int main(int argc, char *argv[]) {
mknod("/null", S_IFCHR | 0666, makedev(1, 3)); mknod("/null", S_IFCHR | 0666, makedev(1, 3));
int null = open("/null", O_RDWR | O_CLOEXEC); int null = open("/null", O_RDWR | O_CLOEXEC);
unlink("/null"); unlink("/null");
dup3(null, STDIN_FILENO, O_CLOEXEC); xdup3(null, STDIN_FILENO, O_CLOEXEC);
dup3(null, STDOUT_FILENO, O_CLOEXEC); xdup3(null, STDOUT_FILENO, O_CLOEXEC);
dup3(null, STDERR_FILENO, O_CLOEXEC); xdup3(null, STDERR_FILENO, O_CLOEXEC);
if (null > STDERR_FILENO) if (null > STDERR_FILENO)
close(null); close(null);

View File

@ -19,6 +19,13 @@
// xwrap.c // xwrap.c
#ifndef SOCK_CLOEXEC
#define SOCK_CLOEXEC O_CLOEXEC
#endif
#ifndef SOCK_NONBLOCK
#define SOCK_NONBLOCK O_NONBLOCK
#endif
FILE *xfopen(const char *pathname, const char *mode); FILE *xfopen(const char *pathname, const char *mode);
FILE *xfdopen(int fd, const char *mode); FILE *xfdopen(int fd, const char *mode);
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME #define GET_MACRO(_1, _2, _3, NAME, ...) NAME
@ -51,9 +58,12 @@ int xsocketpair(int domain, int type, int protocol, int sv[2]);
int xstat(const char *pathname, struct stat *buf); int xstat(const char *pathname, struct stat *buf);
int xlstat(const char *pathname, struct stat *buf); int xlstat(const char *pathname, struct stat *buf);
int xdup2(int oldfd, int newfd); int xdup2(int oldfd, int newfd);
int xdup3(int oldfd, int newfd, int flags);
ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz); ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz);
ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz); ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz);
int xsymlink(const char *target, const char *linkpath); int xsymlink(const char *target, const char *linkpath);
int xsymlinkat(const char *target, int newdirfd, const char *linkpath);
int xlinkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags);
int xmount(const char *source, const char *target, int xmount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags, const char *filesystemtype, unsigned long mountflags,
const void *data); const void *data);
@ -105,7 +115,6 @@ struct file_attr {
char con[128]; char con[128];
}; };
int fd_getpath(int fd, char *path, size_t size);
int mkdirs(const char *pathname, mode_t mode); int mkdirs(const char *pathname, mode_t mode);
void in_order_walk(int dirfd, void (*callback)(int, struct dirent*)); void in_order_walk(int dirfd, void (*callback)(int, struct dirent*));
void rm_rf(const char *path); void rm_rf(const char *path);

View File

@ -28,11 +28,16 @@ static int is_excl(const char *name) {
return 0; return 0;
} }
int fd_getpath(int fd, char *path, size_t size) { static int fd_getpath(int fd, char *path, size_t size) {
snprintf(path, size, "/proc/self/fd/%d", fd); snprintf(path, size, "/proc/self/fd/%d", fd);
if (xreadlink(path, path, size) == -1) return xreadlink(path, path, size) == -1;
return -1; }
return 0;
static int fd_getpathat(int dirfd, const char *name, char *path, size_t size) {
if (fd_getpath(dirfd, path, size))
return 1;
snprintf(path, size, "%s/%s", path, name);
return 0;
} }
int mkdirs(const char *pathname, mode_t mode) { int mkdirs(const char *pathname, mode_t mode) {
@ -220,7 +225,7 @@ void clone_dir(int src, int dest) {
break; break;
case DT_LNK: case DT_LNK:
xreadlinkat(src, entry->d_name, buf, sizeof(buf)); xreadlinkat(src, entry->d_name, buf, sizeof(buf));
symlinkat(buf, dest, entry->d_name); xsymlinkat(buf, dest, entry->d_name);
setattrat(dest, entry->d_name, &a); setattrat(dest, entry->d_name, &a);
break; break;
} }
@ -249,7 +254,7 @@ void link_dir(int src, int dest) {
close(newsrc); close(newsrc);
close(newdest); close(newdest);
} else { } else {
linkat(src, entry->d_name, dest, entry->d_name, 0); xlinkat(src, entry->d_name, dest, entry->d_name, 0);
} }
} }
} }
@ -270,12 +275,9 @@ int getattr(const char *path, struct file_attr *a) {
} }
int getattrat(int dirfd, const char *pathname, struct file_attr *a) { int getattrat(int dirfd, const char *pathname, struct file_attr *a) {
int fd = xopenat(dirfd, pathname, O_PATH | O_NOFOLLOW | O_CLOEXEC); char path[PATH_MAX];
if (fd < 0) fd_getpathat(dirfd, pathname, path, sizeof(path));
return -1; return getattr(path, a);
int ret = fgetattr(fd, a);
close(fd);
return ret;
} }
int fgetattr(int fd, struct file_attr *a) { int fgetattr(int fd, struct file_attr *a) {
@ -304,12 +306,9 @@ int setattr(const char *path, struct file_attr *a) {
} }
int setattrat(int dirfd, const char *pathname, struct file_attr *a) { int setattrat(int dirfd, const char *pathname, struct file_attr *a) {
int fd = xopenat(dirfd, pathname, O_PATH | O_NOFOLLOW | O_CLOEXEC); char path[PATH_MAX];
if (fd < 0) fd_getpathat(dirfd, pathname, path, sizeof(path));
return -1; return setattr(path, a);
int ret = fsetattr(fd, a);
close(fd);
return ret;
} }
int fsetattr(int fd, struct file_attr *a) { int fsetattr(int fd, struct file_attr *a) {

View File

@ -8,7 +8,7 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/sendfile.h> #include <sys/sendfile.h>
#include <sys/statvfs.h> #include <sys/statfs.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <linux/loop.h> #include <linux/loop.h>
@ -70,12 +70,12 @@ static char *loopsetup(const char *img) {
static void check_filesystem(struct fs_info *info, const char *img, const char *mount) { static void check_filesystem(struct fs_info *info, const char *img, const char *mount) {
struct stat st; struct stat st;
struct statvfs vfs; struct statfs fs;
stat(img, &st); stat(img, &st);
statvfs(mount, &vfs); statfs(mount, &fs);
info->size = st.st_size / 1048576; info->size = st.st_size / 1048576;
info->free = vfs.f_bfree * vfs.f_frsize / 1048576; info->free = fs.f_bfree * (uint64_t)fs.f_frsize / 1048576;
info->used = (vfs.f_blocks - vfs.f_bfree) * vfs.f_frsize / 1048576; info->used = (fs.f_blocks - fs.f_bfree) * (uint64_t)fs.f_frsize / 1048576;
} }
static void usage() { static void usage() {

View File

@ -21,6 +21,7 @@
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/sendfile.h> #include <sys/sendfile.h>
#include <sys/syscall.h>
#include "logging.h" #include "logging.h"
#include "utils.h" #include "utils.h"
@ -100,7 +101,7 @@ int xpipe2(int pipefd[2], int flags) {
} }
int xsetns(int fd, int nstype) { int xsetns(int fd, int nstype) {
int ret = setns(fd, nstype); int ret = (int) syscall(__NR_setns, fd, nstype);
if (ret == -1) { if (ret == -1) {
PLOGE("setns"); PLOGE("setns");
} }
@ -165,9 +166,14 @@ int xlisten(int sockfd, int backlog) {
} }
int xaccept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) { int xaccept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
int fd = accept4(sockfd, addr, addrlen, flags); #ifndef __NR_accept4
#ifdef __i386__
#define __NR_accept4 364
#endif
#endif
int fd = (int) syscall(__NR_accept4, sockfd, addr, addrlen, flags);
if (fd == -1) { if (fd == -1) {
PLOGE("accept"); PLOGE("accept4");
} }
return fd; return fd;
} }
@ -213,7 +219,7 @@ ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags) {
} }
int xpthread_create(pthread_t *thread, const pthread_attr_t *attr, int xpthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg) { void *(*start_routine) (void *), void *arg) {
errno = pthread_create(thread, attr, start_routine, arg); errno = pthread_create(thread, attr, start_routine, arg);
if (errno) { if (errno) {
PLOGE("pthread_create"); PLOGE("pthread_create");
@ -245,6 +251,14 @@ int xdup2(int oldfd, int newfd) {
return ret; return ret;
} }
int xdup3(int oldfd, int newfd, int flags) {
int ret = (int) syscall(__NR_dup3, oldfd, newfd, flags);
if (ret == -1) {
PLOGE("dup3");
}
return ret;
}
ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz) { ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz) {
ssize_t ret = readlink(pathname, buf, bufsiz); ssize_t ret = readlink(pathname, buf, bufsiz);
if (ret == -1) { if (ret == -1) {
@ -256,7 +270,7 @@ ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz) {
} }
ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) { ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) {
ssize_t ret = readlinkat(dirfd, pathname, buf, bufsiz); ssize_t ret = syscall(__NR_readlinkat, dirfd, pathname, buf, bufsiz);
if (ret == -1) { if (ret == -1) {
PLOGE("readlinkat %s", pathname); PLOGE("readlinkat %s", pathname);
} else { } else {
@ -273,10 +287,26 @@ int xsymlink(const char *target, const char *linkpath) {
return ret; return ret;
} }
int xsymlinkat(const char *target, int newdirfd, const char *linkpath) {
int ret = (int) syscall(__NR_symlinkat, target, newdirfd, linkpath);
if (ret == -1) {
PLOGE("symlinkat %s->%s", target, linkpath);
}
return ret;
}
int xlinkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags) {
int ret = (int) syscall(__NR_linkat, olddirfd, oldpath, newdirfd, newpath, flags);
if (ret == -1) {
PLOGE("linkat %s->%s", oldpath, newpath);
}
return ret;
}
int xmount(const char *source, const char *target, int xmount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags, const char *filesystemtype, unsigned long mountflags,
const void *data) { const void *data) {
int ret = mount(source, target, filesystemtype, MS_SILENT | mountflags, data); int ret = mount(source, target, filesystemtype, mountflags, data);
if (ret == -1) { if (ret == -1) {
PLOGE("mount %s->%s", source, target); PLOGE("mount %s->%s", source, target);
} }