diff --git a/Makefile b/Makefile index bfb2c946..f837982a 100644 --- a/Makefile +++ b/Makefile @@ -8,10 +8,7 @@ all $(MAKECMDGOALS): $(MAKECMDGOALS) git-submodules: - @set -e; if [ ! -f releng/meson/meson.py ]; then \ - git submodule update --init --depth 1 subprojects/frida-core subprojects/frida-gum; \ - git submodule update --init --depth 1 --recursive releng; \ - fi + @[ ! -f releng/meson/meson.py ] && $(PYTHON) tools/ensure-submodules.py -include git-submodules .PHONY: all $(MAKECMDGOALS) diff --git a/configure b/configure index a6ea7618..786eb50c 100755 --- a/configure +++ b/configure @@ -3,14 +3,8 @@ [ -z "$PYTHON" ] && PYTHON=$(which python3 >/dev/null && echo python3 || echo python) cd $(dirname $0) - srcroot=$(pwd) - -if [ ! -f releng/meson/meson.py ]; then - git submodule update --init --depth 1 subprojects/frida-core subprojects/frida-gum - git submodule update --init --depth 1 --recursive releng -fi - +[ ! -f releng/meson/meson.py ] && "$PYTHON" tools/ensure-submodules.py cd - >/dev/null exec "$PYTHON" \ diff --git a/configure.bat b/configure.bat index d830fd5a..417cb0f2 100644 --- a/configure.bat +++ b/configure.bat @@ -12,10 +12,7 @@ goto :eof call :set_real_dp0 if not exist "%dp0%\releng\meson\meson.py" ( - pushd "%dp0%" ^ - & git submodule update --init --depth 1 "%dp0%\subprojects\frida-core" "%dp0%\subprojects\frida-gum" ^ - & git submodule update --init --depth 1 --recursive "%dp0%\releng" ^ - & popd + python "%dp0%\tools\ensure-submodules.py" if %errorlevel% neq 0 exit /b %errorlevel% ) diff --git a/make.bat b/make.bat index bf14db0f..0c160c20 100644 --- a/make.bat +++ b/make.bat @@ -12,10 +12,7 @@ goto :eof call :set_real_dp0 if not exist "%dp0%\releng\meson\meson.py" ( - pushd "%dp0%" ^ - & git submodule update --init --depth 1 "%dp0%\subprojects\frida-core" "%dp0%\subprojects\frida-gum" ^ - & git submodule update --init --depth 1 --recursive "%dp0%\releng" ^ - & popd + python "%dp0%\tools\ensure-submodules.py" if %errorlevel% neq 0 exit /b %errorlevel% ) diff --git a/meson.build b/meson.build index 1d731ee3..e7351d50 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,6 @@ project('frida', 'c', meson_version: '>=1.1.0', ) -fs = import('fs') python = import('python').find_installation() is_cross_build = meson.is_cross_build() @@ -24,19 +23,16 @@ foreach component : ['gadget', 'server', 'inject'] endforeach subproject('frida-core', default_options: core_options) -grab_submodule = ['git', 'submodule', 'update', '--init', '--depth', '1'] +ensure_submodules = [python, files('tools' / 'ensure-submodules.py')] if get_option('frida_clr') \ .disable_auto_if(is_cross_build) \ .disable_auto_if(build_machine.system() != 'windows') \ .disable_auto_if(get_option('b_vscrt').startswith('mt')) \ .allowed() - dir = 'subprojects' / 'frida-clr' - if not fs.exists(dir / 'meson.build') - run_command(grab_submodule, dir, check: true) - endif + run_command(ensure_submodules, 'frida-clr', check: true) if get_option('frida_clr').auto() - detect_result = run_command(python, dir / 'detect-netfx.py', check: false) + detect_result = run_command(python, 'subprojects' / 'frida-clr' / 'detect-netfx.py', check: false) build_clr_bindings = detect_result.returncode() == 0 else build_clr_bindings = true @@ -49,20 +45,14 @@ endif if get_option('frida_node') \ .disable_auto_if(is_cross_build) \ .allowed() - dir = 'subprojects' / 'frida-node' - if not fs.exists(dir / 'meson.build') - run_command(grab_submodule, dir, check: true) - endif + run_command(ensure_submodules, 'frida-node', check: true) subproject('frida-node') endif if get_option('frida_python') \ .disable_auto_if(is_cross_build) \ .allowed() - dir = 'subprojects' / 'frida-python' - if not fs.exists(dir / 'meson.build') - run_command(grab_submodule, dir, check: true) - endif + run_command(ensure_submodules, 'frida-python', check: true) subproject('frida-python') endif @@ -70,10 +60,7 @@ if get_option('frida_swift') \ .disable_auto_if(is_cross_build) \ .disable_auto_if(build_machine.system() != 'macos') \ .allowed() - dir = 'subprojects' / 'frida-swift' - if not fs.exists(dir / 'meson.build') - run_command(grab_submodule, dir, check: true) - endif + run_command(ensure_submodules, 'frida-swift', check: true) subproject('frida-swift') endif @@ -82,19 +69,13 @@ if get_option('frida_qml') \ .disable_auto_if(is_cross_build) \ .disable_auto_if(not qt6_dep.found()) \ .allowed() - dir = 'subprojects' / 'frida-qml' - if not fs.exists(dir / 'meson.build') - run_command(grab_submodule, dir, check: true) - endif + run_command(ensure_submodules, 'frida-qml', check: true) subproject('frida-qml') endif if get_option('frida_tools') \ .disable_auto_if(is_cross_build) \ .allowed() - dir = 'subprojects' / 'frida-tools' - if not fs.exists(dir / 'meson.build') - run_command(grab_submodule, dir, check: true) - endif + run_command(ensure_submodules, 'frida-tools', check: true) subproject('frida-tools') endif diff --git a/tools/ensure-submodules.py b/tools/ensure-submodules.py new file mode 100755 index 00000000..9246ece6 --- /dev/null +++ b/tools/ensure-submodules.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +import subprocess +import sys +from pathlib import Path + +SOURCE_ROOT = Path(__file__).resolve().parent.parent +UPDATE_FLAGS = ["--init", "--depth", "1"] + + +def main(argv: list[str]): + names = argv[1:] + if not names: + names = ["frida-gum", "frida-core"] + paths_to_check = [Path("subprojects") / name for name in names] + + try: + releng = SOURCE_ROOT / "releng" + if not (releng / "meson" / "meson.py").exists(): + print(f"Fetching releng...", flush=True) + run(["git", "submodule", "update", *UPDATE_FLAGS], cwd=releng) + + for relpath in paths_to_check: + if not (SOURCE_ROOT / relpath / "meson.build").exists(): + print(f"Fetching {relpath.name}...", flush=True) + run(["git", "submodule", "update", *UPDATE_FLAGS, relpath], cwd=SOURCE_ROOT) + except Exception as e: + print(e, file=sys.stderr) + if isinstance(e, subprocess.CalledProcessError): + for label, data in [("Output", e.output), ("Stderr", e.stderr)]: + if data: + print(f"{label}:\n\t| " + "\n\t| ".join(data.strip().split("\n")), file=sys.stderr) + sys.exit(1) + + +def run(argv: list[str], **kwargs) -> subprocess.CompletedProcess: + return subprocess.run(argv, capture_output=True, encoding="utf-8", check=True, **kwargs) + + +if __name__ == "__main__": + main(sys.argv)