-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathmeson_make.py
131 lines (102 loc) · 3.66 KB
/
meson_make.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import argparse
import os
from pathlib import Path
import pickle
import shlex
import shutil
import sys
from typing import Callable
from . import env
from .meson_configure import configure
STANDARD_TARGET_NAMES = ["all", "clean", "distclean", "install", "test"]
def main():
default_sourcedir = Path(sys.argv.pop(1)).resolve()
sourcedir = Path(os.environ.get("MESON_SOURCE_ROOT", default_sourcedir)).resolve()
default_builddir = Path(sys.argv.pop(1)).resolve()
builddir = Path(os.environ.get("MESON_BUILD_ROOT", default_builddir)).resolve()
parser = argparse.ArgumentParser(prog="make")
parser.add_argument("targets",
help="Targets to build, e.g.: " + ", ".join(STANDARD_TARGET_NAMES),
nargs="*",
default="all")
options = parser.parse_args()
targets = options.targets
if isinstance(targets, str):
targets = [targets]
try:
make(sourcedir, builddir, targets)
except Exception as e:
print(e, file=sys.stderr)
sys.exit(1)
def make(sourcedir: Path,
builddir: Path,
targets: list[str],
environ: dict[str, str] = os.environ,
call_meson: Callable = env.call_meson):
if not (builddir / "build.ninja").exists():
configure(sourcedir, builddir, environ=environ)
compile_options = []
if environ.get("V") == "1":
compile_options += ["-v"]
test_options = shlex.split(environ.get("FRIDA_TEST_OPTIONS", "-v"))
standard_targets = {
"all": ["compile"] + compile_options,
"clean": ["compile", "--clean"] + compile_options,
"distclean": lambda: distclean(sourcedir, builddir),
"install": ["install"],
"test": ["test"] + test_options,
}
env_state = pickle.loads((builddir / "frida-env.dat").read_bytes())
machine_config = env_state["host"]
if machine_config is None:
machine_config = env_state["build"]
meson_env = machine_config.make_merged_environment(environ)
meson_env["FRIDA_ALLOWED_PREBUILDS"] = ",".join(env_state["allowed_prebuilds"])
meson_env["FRIDA_DEPS"] = str(env_state["deps"])
def do_meson_command(args):
call_meson(args,
use_submodule=env_state["meson"] == "internal",
cwd=builddir,
env=meson_env,
check=True)
pending_targets = targets.copy()
pending_compile = None
while pending_targets:
target = pending_targets.pop(0)
action = standard_targets.get(target, None)
if action is None:
meson_command = "compile"
elif not callable(action):
meson_command = action[0]
else:
meson_command = None
if meson_command == "compile":
if pending_compile is None:
pending_compile = ["compile"]
if action is not None:
pending_compile += action[1:]
else:
pending_compile += [target]
continue
if pending_compile is not None:
do_meson_command(pending_compile)
pending_compile = None
if meson_command is not None:
do_meson_command(action)
else:
action()
if pending_compile is not None:
do_meson_command(pending_compile)
def distclean(sourcedir: Path, builddir: Path):
items_to_delete = []
if not builddir.is_relative_to(sourcedir):
items_to_delete += list(builddir.iterdir())
items_to_delete += [
sourcedir / "build",
sourcedir / "deps",
]
for item in items_to_delete:
try:
shutil.rmtree(item)
except:
pass