1
0
mirror of https://github.com/0O0o0oOoO00/Alas.git synced 2026-05-14 10:59:24 +08:00
Files
Alas/blcrack/cracker/Dobby/scripts/platform_builder.py

243 lines
8.0 KiB
Python
Raw Normal View History

2025-11-01 00:23:46 +08:00
import os
import pipes
import re
import shutil
import subprocess
import sys
import logging
import argparse
platforms = {
"macos": ["x86_64", "arm64", "arm64e"],
"iphoneos": ["arm64", "arm64e"],
"linux": ["x86", "x86_64", "arm", "arm64"],
"android": ["x86", "x86_64", "armeabi-v7a", "arm64-v8a"]
}
class PlatformBuilder(object):
cmake_args = list()
cmake_build_type = "Release"
cmake_build_verbose = False
cmake_build_dir = ""
library_build_type = "static"
project_dir = ""
output_dir = ""
shared_output_name = ""
static_output_name = ""
platform = ""
arch = ""
def __init__(self, project_dir, library_build_type, platform, arch):
self.project_dir = project_dir
self.library_build_type = library_build_type
self.platform = platform
self.arch = arch
self.cmake_build_dir = f"{self.project_dir}/build/cmake-build-{platform}-{arch}"
self.output_dir = f"{self.project_dir}/build/{platform}/{arch}"
self.cmake = "cmake" if PlatformBuilder.cmake_dir is None else f"{PlatformBuilder.cmake_dir}/bin/cmake"
self.clang = "clang" if PlatformBuilder.llvm_dir is None else f"{PlatformBuilder.llvm_dir}/bin/clang"
self.clangxx = "clang++" if PlatformBuilder.llvm_dir is None else f"{PlatformBuilder.llvm_dir}/bin/clang++"
self.setup_common_args()
def cmake_generate_build_system(self):
cmake_cmd_options = ["-S {}".format(self.project_dir), "-B {}".format(self.cmake_build_dir)]
cmd = [f"{self.cmake}"] + cmake_cmd_options + self.cmake_args
# subprocess.run(cmd, check=True)
cmd_line = " ".join(cmd)
print(cmd_line)
os.system(cmd_line)
def setup_common_args(self):
self.cmake_args += [f"-DCMAKE_C_COMPILER={self.clang}", f"-DCMAKE_CXX_COMPILER={self.clangxx}"]
self.cmake_args += ["-DCMAKE_BUILD_TYPE={}".format(self.cmake_build_type)]
if self.library_build_type == "shared":
pass
# self.cmake_args += ["-DDOBBY_GENERATE_SHARED=ON"]
elif self.library_build_type == "static":
pass
# self.cmake_args += ["-DDOBBY_GENERATE_SHARED=OFF"]
def build(self):
subprocess.run(["mkdir", "-p", "{}".format(self.output_dir)], check=True)
self.cmake_generate_build_system()
subprocess.run("cmake --build . --clean-first --target dobby --target dobby_static -- -j8", cwd=self.cmake_build_dir, shell=True, check=True)
os.system(f"mkdir -p {self.output_dir}")
os.system(f"cp {self.cmake_build_dir}/{self.shared_output_name} {self.output_dir}")
os.system(f"cp {self.cmake_build_dir}/{self.static_output_name} {self.output_dir}")
class WindowsPlatformBuilder(PlatformBuilder):
def __init__(self, project_dir, library_build_type, platform, arch):
super().__init__(project_dir, library_build_type, platform, arch)
if self.library_build_type == "shared":
self.output_name = "libdobby.dll"
else:
self.output_name = "libdobby.lib"
triples = {
"x86": "i686-pc-windows-msvc",
"x64": "x86_64-pc-windows-msvc",
# "arm": "arm-pc-windows-msvc",
"arm64": "arm64-pc-windows-msvc",
}
# self.cmake_args += ["--target {}".format(triples[arch])]
self.cmake_args += [
"-DCMAKE_SYSTEM_PROCESSOR={}".format(arch),
]
class LinuxPlatformBuilder(PlatformBuilder):
def __init__(self, project_dir, library_build_type, arch):
super().__init__(project_dir, library_build_type, "linux", arch)
self.shared_output_name = "libdobby.so"
self.static_output_name = "libdobby.a"
targets = {
"x86": "i686-linux-gnu",
"x86_64": "x86_64-linux-gnu",
"arm": "arm-linux-gnueabi",
"aarch64": "aarch64-linux-gnu",
}
# self.cmake_args += ["--target={}".format(targets[arch])]
self.cmake_args += [
"-DCMAKE_SYSTEM_NAME=Linux",
"-DCMAKE_SYSTEM_PROCESSOR={}".format(arch),
]
class AndroidPlatformBuilder(PlatformBuilder):
def __init__(self, android_nkd_dir, project_dir, library_build_type, arch):
super().__init__(project_dir, library_build_type, "android", arch)
self.shared_output_name = "libdobby.so"
self.static_output_name = "libdobby.a"
android_api_level = 21
if arch == "armeabi-v7a" or arch == "x86":
android_api_level = 19
self.cmake_args += [
"-DCMAKE_SYSTEM_NAME=Android", f"-DCMAKE_ANDROID_NDK={android_nkd_dir}", f"-DCMAKE_ANDROID_ARCH_ABI={arch}",
f"-DCMAKE_SYSTEM_VERSION={android_api_level}"
]
class DarwinPlatformBuilder(PlatformBuilder):
def __init__(self, project_dir, library_build_type, platform, arch):
super().__init__(project_dir, library_build_type, platform, arch)
self.cmake_args += [
"-DCMAKE_OSX_ARCHITECTURES={}".format(arch),
"-DCMAKE_SYSTEM_PROCESSOR={}".format(arch),
]
if platform == "macos":
self.cmake_args += ["-DCMAKE_SYSTEM_NAME=Darwin"]
elif platform == "iphoneos":
self.cmake_args += ["-DCMAKE_SYSTEM_NAME=iOS", "-DCMAKE_OSX_DEPLOYMENT_TARGET=9.3"]
self.shared_output_name = "libdobby.dylib"
self.static_output_name = "libdobby.a"
@classmethod
def lipo_create_fat(cls, project_dir, platform, output_name):
files = list()
archs = platforms[platform]
for arch in archs:
file = f"{project_dir}/build/{platform}/{arch}/{output_name}"
files.append(file)
fat_output_dir = f"{project_dir}/build/{platform}/universal"
subprocess.run(["mkdir", "-p", "{}".format(fat_output_dir)], check=True)
cmd = ["lipo", "-create"] + files + ["-output", f"{fat_output_dir}/{output_name}"]
subprocess.run(cmd, check=True)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--platform", type=str, required=True)
parser.add_argument("--arch", type=str, required=True)
parser.add_argument("--library_build_type", type=str, default="static")
parser.add_argument("--android_ndk_dir", type=str)
parser.add_argument("--cmake_dir", type=str)
parser.add_argument("--llvm_dir", type=str)
args = parser.parse_args()
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
platform = args.platform
arch = args.arch
library_build_type = args.library_build_type
PlatformBuilder.cmake_dir = args.cmake_dir
PlatformBuilder.llvm_dir = args.llvm_dir
project_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
logging.info("project dir: {}".format(project_dir))
if not os.path.exists(f"{project_dir}/CMakeLists.txt"):
logging.error("Please run this script in Dobby project root directory")
sys.exit(1)
if platform not in platforms:
logging.error("invalid platform {}".format(platform))
sys.exit(-1)
if arch != "all" and arch not in platforms[platform]:
logging.error("invalid arch {} for platform {}".format(arch, platform))
sys.exit(-1)
if platform == "android":
if args.android_ndk_dir is None:
logging.error("ndk dir is required for android platform")
sys.exit(-1)
archs = list()
if arch == "all":
archs = platforms[platform]
else:
archs.append(arch)
logging.info("build platform: {}, archs: {}".format(platform, archs))
builder: PlatformBuilder = None
for arch_ in archs:
if platform == "macos":
builder = DarwinPlatformBuilder(project_dir, library_build_type, platform, arch_)
elif platform == "iphoneos":
builder = DarwinPlatformBuilder(project_dir, library_build_type, platform, arch_)
elif platform == "android":
builder = AndroidPlatformBuilder(args.android_ndk_dir, project_dir, library_build_type, arch_)
elif platform == "linux":
builder = LinuxPlatformBuilder(project_dir, library_build_type, arch_)
else:
logging.error("invalid platform {}".format(platform))
sys.exit(-1)
logging.info(
f"build platform: {platform}, arch: {arch_}, cmake_build_dir: {builder.cmake_build_dir}, output_dir: {builder.output_dir}"
)
builder.build()
if platform in ["iphoneos", "macos"] and arch == "all":
DarwinPlatformBuilder.lipo_create_fat(project_dir, platform, builder.shared_output_name)
DarwinPlatformBuilder.lipo_create_fat(project_dir, platform, builder.static_output_name)