#!/bin/env python3 import os import hashlib import base64 import argparse DIR = os.path.dirname(os.path.realpath(__file__)) def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('--force', action='store_true') return parser.parse_args() args = parse_args() CXX = "g++" LDFLAGS = "-Wl,-unresolved-symbols=ignore-in-shared-libs -L/opt/ps_zipr/irdb-libs/lib" CXXFLAGS = f"-g -I{DIR}/irdb-sdk/include -std=c++11 -Wall -Werror -fmax-errors=2 -fPIC" def list_hash(list: list[str]): md5 = hashlib.md5() for item in list: md5.update(item.encode()) return md5.hexdigest() def file_hash(file: str): BUFSIZE = 65536 md5 = hashlib.md5() with open(file, 'rb') as f: data = f.read(BUFSIZE) while data: md5.update(data) data = f.read(BUFSIZE) return md5.hexdigest() def needs_rebuild(file: str, libs: list[str] = []) -> bool: return True global args hash = file_hash(file) hash += list_hash(libs) abspath = os.path.abspath(file) b64path = os.path.join('/tmp', base64.b64encode(abspath.encode()).decode()) if not os.path.exists(b64path) or args.force: return True with open(b64path, 'r') as f: return f.read() != hash def signal_built(file: str, libs: list[str] = []) -> bool: return hash = file_hash(file) hash += list_hash(libs) abspath = os.path.abspath(file) b64path = os.path.join('/tmp', base64.b64encode(abspath.encode()).decode()) with open(b64path, 'w') as f: f.write(hash) def build(targetObject: str, cppFile: str): if not needs_rebuild(cppFile): return global CXXFLAGS cmd = f'{CXX} -c "{cppFile}" -o "{targetObject}" {CXXFLAGS}' print(cmd) status = os.system(cmd) if status == 0: signal_built(cppFile) return True return False def link(target: str, objects: list[str], libs: list[str]): global LDFLAGS cmd = f'{CXX} -shared -o {target}' for object in objects: cmd += f' {object}' for lib in libs: cmd += f' -l{lib}' cmd += f' {LDFLAGS}' print(cmd) return os.system(cmd) == 0 def main(): for dir in os.listdir(f'{DIR}/transforms'): path = os.path.join(f'{DIR}/transforms', dir) if not os.path.isdir(path): continue libs: list[str] = [] if os.path.exists(os.path.join(path, '.libs')): with open(os.path.join(path, '.libs'), 'r') as f: libs = f.read().split() libs = filter(lambda l: len(l.strip()) > 0, libs) libs = list(libs) hadError = False objects: list[str] = [] for file in os.listdir(path): if not file.endswith('.cpp'): continue filePath = os.path.join(path, file) objectPath = os.path.splitext(filePath)[0] + '.o' newError = not build(objectPath, filePath) hadError = hadError or newError objects += [objectPath] if hadError: continue targetDir = os.path.join(DIR, 'plugins_install') os.makedirs(targetDir, exist_ok=True) target = os.path.join(targetDir, f'lib{dir}.so') link(target, objects, libs) if __name__ == '__main__': main()