cja 0.2.2__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cja-0.2.2 → cja-0.2.3}/PKG-INFO +1 -1
- {cja-0.2.2 → cja-0.2.3}/pyproject.toml +1 -1
- {cja-0.2.2 → cja-0.2.3}/src/cja/build_context.py +24 -2
- {cja-0.2.2 → cja-0.2.3}/src/cja/find_package.py +100 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/generator.py +161 -15
- {cja-0.2.2 → cja-0.2.3}/README.md +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/__init__.py +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/__main__.py +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/cli.py +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/cmake/Modules/FindGTest.cmake +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/commands.py +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/ninja_syntax.py +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/parser.py +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/py.typed +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/syntax.py +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/targets.py +0 -0
- {cja-0.2.2 → cja-0.2.3}/src/cja/utils.py +0 -0
{cja-0.2.2 → cja-0.2.3}/PKG-INFO
RENAMED
|
@@ -47,6 +47,21 @@ class CustomCommand:
|
|
|
47
47
|
defined_line: int = 0
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
@dataclass
|
|
51
|
+
class CustomTarget:
|
|
52
|
+
"""A custom target (phony build target)."""
|
|
53
|
+
|
|
54
|
+
name: str
|
|
55
|
+
commands: list[list[str]]
|
|
56
|
+
depends: list[str]
|
|
57
|
+
all: bool = False
|
|
58
|
+
working_directory: str | None = None
|
|
59
|
+
verbatim: bool = False
|
|
60
|
+
comment: str = ""
|
|
61
|
+
defined_file: Path | None = None
|
|
62
|
+
defined_line: int = 0
|
|
63
|
+
|
|
64
|
+
|
|
50
65
|
@dataclass
|
|
51
66
|
class BuildContext:
|
|
52
67
|
"""Context for processing CMake commands."""
|
|
@@ -58,7 +73,9 @@ class BuildContext:
|
|
|
58
73
|
project_name: str = ""
|
|
59
74
|
variables: dict[str, str] = field(default_factory=dict)
|
|
60
75
|
cache_variables: set[str] = field(default_factory=set) # Variables from -D flags
|
|
61
|
-
cli_variables: dict[str, str] = field(
|
|
76
|
+
cli_variables: dict[str, str] = field(
|
|
77
|
+
default_factory=dict
|
|
78
|
+
) # Original -D flag values
|
|
62
79
|
libraries: list[Library] = field(default_factory=list)
|
|
63
80
|
executables: list[Executable] = field(default_factory=list)
|
|
64
81
|
imported_targets: dict[str, ImportedTarget] = field(default_factory=dict)
|
|
@@ -69,6 +86,9 @@ class BuildContext:
|
|
|
69
86
|
custom_commands: list[CustomCommand] = field(
|
|
70
87
|
default_factory=list
|
|
71
88
|
) # Custom build commands
|
|
89
|
+
custom_targets: list[CustomTarget] = field(
|
|
90
|
+
default_factory=list
|
|
91
|
+
) # Custom targets (phony)
|
|
72
92
|
functions: dict[str, FunctionDef] = field(
|
|
73
93
|
default_factory=dict
|
|
74
94
|
) # User-defined functions
|
|
@@ -179,7 +199,9 @@ class BuildContext:
|
|
|
179
199
|
if allow_undefined_empty:
|
|
180
200
|
return ""
|
|
181
201
|
if allow_undefined_warning:
|
|
182
|
-
self.print_warning(
|
|
202
|
+
self.print_warning(
|
|
203
|
+
f"undefined variable referenced: {var_name}", line
|
|
204
|
+
)
|
|
183
205
|
return ""
|
|
184
206
|
level = self.print_error if strict else self.print_warning
|
|
185
207
|
level(f"undefined variable referenced: {var_name}", line)
|
|
@@ -519,4 +519,104 @@ def handle_builtin_find_package(
|
|
|
519
519
|
print(f"{colored('✗', 'red')} {package_name}")
|
|
520
520
|
return True
|
|
521
521
|
|
|
522
|
+
if package_name == "Qt5":
|
|
523
|
+
keywords = {
|
|
524
|
+
"REQUIRED",
|
|
525
|
+
"QUIET",
|
|
526
|
+
"COMPONENTS",
|
|
527
|
+
"OPTIONAL_COMPONENTS",
|
|
528
|
+
"EXACT",
|
|
529
|
+
"MODULE",
|
|
530
|
+
"CONFIG",
|
|
531
|
+
"NO_MODULE",
|
|
532
|
+
}
|
|
533
|
+
required_components: list[str] = []
|
|
534
|
+
optional_components: list[str] = []
|
|
535
|
+
i = 1
|
|
536
|
+
while i < len(args):
|
|
537
|
+
token = args[i]
|
|
538
|
+
if token == "COMPONENTS":
|
|
539
|
+
i += 1
|
|
540
|
+
while i < len(args) and args[i] not in keywords:
|
|
541
|
+
required_components.append(args[i])
|
|
542
|
+
i += 1
|
|
543
|
+
continue
|
|
544
|
+
if token == "OPTIONAL_COMPONENTS":
|
|
545
|
+
i += 1
|
|
546
|
+
while i < len(args) and args[i] not in keywords:
|
|
547
|
+
optional_components.append(args[i])
|
|
548
|
+
i += 1
|
|
549
|
+
continue
|
|
550
|
+
i += 1
|
|
551
|
+
|
|
552
|
+
all_components = required_components + optional_components
|
|
553
|
+
if not all_components:
|
|
554
|
+
all_components = ["Core"]
|
|
555
|
+
|
|
556
|
+
found = False
|
|
557
|
+
missing_required: list[str] = []
|
|
558
|
+
|
|
559
|
+
for component in all_components:
|
|
560
|
+
pkg_name = f"Qt5{component}"
|
|
561
|
+
component_found = False
|
|
562
|
+
try:
|
|
563
|
+
result = subprocess.run(
|
|
564
|
+
["pkg-config", "--exists", pkg_name],
|
|
565
|
+
capture_output=True,
|
|
566
|
+
)
|
|
567
|
+
component_found = result.returncode == 0
|
|
568
|
+
except FileNotFoundError:
|
|
569
|
+
component_found = False
|
|
570
|
+
|
|
571
|
+
if component_found:
|
|
572
|
+
found = True
|
|
573
|
+
cflags_result = subprocess.run(
|
|
574
|
+
["pkg-config", "--cflags", pkg_name],
|
|
575
|
+
capture_output=True,
|
|
576
|
+
text=True,
|
|
577
|
+
)
|
|
578
|
+
libs_result = subprocess.run(
|
|
579
|
+
["pkg-config", "--libs", pkg_name],
|
|
580
|
+
capture_output=True,
|
|
581
|
+
text=True,
|
|
582
|
+
)
|
|
583
|
+
version_result = subprocess.run(
|
|
584
|
+
["pkg-config", "--modversion", pkg_name],
|
|
585
|
+
capture_output=True,
|
|
586
|
+
text=True,
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
comp_cflags = cflags_result.stdout.strip()
|
|
590
|
+
comp_libs = libs_result.stdout.strip()
|
|
591
|
+
comp_version = version_result.stdout.strip()
|
|
592
|
+
|
|
593
|
+
ctx.variables[f"Qt5{component}_FOUND"] = "TRUE"
|
|
594
|
+
if comp_version:
|
|
595
|
+
ctx.variables[f"Qt5{component}_VERSION"] = comp_version
|
|
596
|
+
ctx.variables["Qt5_VERSION"] = comp_version
|
|
597
|
+
|
|
598
|
+
ctx.imported_targets[f"Qt5::{component}"] = ImportedTarget(
|
|
599
|
+
cflags=comp_cflags,
|
|
600
|
+
libs=comp_libs,
|
|
601
|
+
)
|
|
602
|
+
else:
|
|
603
|
+
ctx.variables[f"Qt5{component}_FOUND"] = "FALSE"
|
|
604
|
+
if component in required_components:
|
|
605
|
+
missing_required.append(component)
|
|
606
|
+
|
|
607
|
+
found = found and not missing_required
|
|
608
|
+
ctx.variables["Qt5_FOUND"] = "TRUE" if found else "FALSE"
|
|
609
|
+
|
|
610
|
+
if found:
|
|
611
|
+
if not quiet:
|
|
612
|
+
print(f"{colored('✓', 'green')} {package_name}")
|
|
613
|
+
else:
|
|
614
|
+
ctx.variables["Qt5_FOUND"] = "FALSE"
|
|
615
|
+
if required:
|
|
616
|
+
ctx.print_error("could not find package: Qt5", cmd.line)
|
|
617
|
+
raise SystemExit(1)
|
|
618
|
+
if not quiet:
|
|
619
|
+
print(f"{colored('✗', 'red')} {package_name}")
|
|
620
|
+
return True
|
|
621
|
+
|
|
522
622
|
return False
|
|
@@ -27,6 +27,7 @@ from .syntax import (
|
|
|
27
27
|
from .build_context import (
|
|
28
28
|
BuildContext,
|
|
29
29
|
CustomCommand,
|
|
30
|
+
CustomTarget,
|
|
30
31
|
find_matching_endforeach,
|
|
31
32
|
find_matching_endif,
|
|
32
33
|
)
|
|
@@ -808,6 +809,8 @@ def process_commands(
|
|
|
808
809
|
add_dir(root)
|
|
809
810
|
else:
|
|
810
811
|
unix_defaults = ["/usr/local", "/usr"]
|
|
812
|
+
if platform.system() == "Darwin" and Path("/opt/homebrew").is_dir():
|
|
813
|
+
unix_defaults.insert(0, "/opt/homebrew")
|
|
811
814
|
for root in unix_defaults:
|
|
812
815
|
if kind == "path":
|
|
813
816
|
add_dir(str(Path(root) / "include"))
|
|
@@ -996,7 +999,6 @@ def process_commands(
|
|
|
996
999
|
if sub_cmakelists.exists():
|
|
997
1000
|
from .parser import parse_file
|
|
998
1001
|
|
|
999
|
-
ctx.record_cmake_file(sub_cmakelists)
|
|
1000
1002
|
ctx.record_cmake_file(sub_cmakelists)
|
|
1001
1003
|
sub_commands = parse_file(sub_cmakelists)
|
|
1002
1004
|
|
|
@@ -1327,6 +1329,7 @@ def process_commands(
|
|
|
1327
1329
|
if sub_cmakelists.exists():
|
|
1328
1330
|
from .parser import parse_file
|
|
1329
1331
|
|
|
1332
|
+
ctx.record_cmake_file(sub_cmakelists)
|
|
1330
1333
|
sub_commands = parse_file(sub_cmakelists)
|
|
1331
1334
|
|
|
1332
1335
|
saved_current_source_dir = ctx.current_source_dir
|
|
@@ -2235,6 +2238,64 @@ int main() {{
|
|
|
2235
2238
|
)
|
|
2236
2239
|
)
|
|
2237
2240
|
|
|
2241
|
+
case "add_custom_target":
|
|
2242
|
+
# Support: add_custom_target(<name> [ALL] [COMMAND cmd ...] [DEPENDS ...] [WORKING_DIRECTORY ...] [VERBATIM] [COMMENT ...])
|
|
2243
|
+
if not args:
|
|
2244
|
+
break
|
|
2245
|
+
target_name = ctx.expand_variables(args[0], strict, cmd.line)
|
|
2246
|
+
ct_commands: list[list[str]] = []
|
|
2247
|
+
ct_depends: list[str] = []
|
|
2248
|
+
ct_all = False
|
|
2249
|
+
ct_working_directory: str | None = None
|
|
2250
|
+
ct_verbatim = False
|
|
2251
|
+
ct_comment = ""
|
|
2252
|
+
ct_section: str | None = None
|
|
2253
|
+
ct_idx = 1
|
|
2254
|
+
while ct_idx < len(args):
|
|
2255
|
+
arg = args[ct_idx]
|
|
2256
|
+
if arg == "ALL":
|
|
2257
|
+
ct_all = True
|
|
2258
|
+
elif arg in ("COMMAND", "DEPENDS", "WORKING_DIRECTORY", "COMMENT"):
|
|
2259
|
+
ct_section = arg
|
|
2260
|
+
if arg == "COMMAND":
|
|
2261
|
+
ct_commands.append([])
|
|
2262
|
+
elif arg in ("VERBATIM", "USES_TERMINAL", "COMMAND_EXPAND_LISTS"):
|
|
2263
|
+
if arg == "VERBATIM":
|
|
2264
|
+
ct_verbatim = True
|
|
2265
|
+
ct_section = None
|
|
2266
|
+
elif arg == "SOURCES":
|
|
2267
|
+
ct_section = "SOURCES"
|
|
2268
|
+
else:
|
|
2269
|
+
arg = ctx.expand_variables(arg, strict, cmd.line)
|
|
2270
|
+
if ct_section == "COMMAND":
|
|
2271
|
+
ct_commands[-1].append(arg)
|
|
2272
|
+
elif ct_section == "DEPENDS":
|
|
2273
|
+
rel = make_relative(arg, ctx.build_dir)
|
|
2274
|
+
if rel == arg:
|
|
2275
|
+
rel = ctx.resolve_path(arg)
|
|
2276
|
+
ct_depends.append(rel)
|
|
2277
|
+
elif ct_section == "WORKING_DIRECTORY":
|
|
2278
|
+
ct_working_directory = arg
|
|
2279
|
+
elif ct_section == "COMMENT":
|
|
2280
|
+
ct_comment = arg
|
|
2281
|
+
elif ct_section == "SOURCES":
|
|
2282
|
+
pass # Ignored, only for IDE integration
|
|
2283
|
+
ct_idx += 1
|
|
2284
|
+
|
|
2285
|
+
ctx.custom_targets.append(
|
|
2286
|
+
CustomTarget(
|
|
2287
|
+
name=target_name,
|
|
2288
|
+
commands=ct_commands,
|
|
2289
|
+
depends=ct_depends,
|
|
2290
|
+
all=ct_all,
|
|
2291
|
+
working_directory=ct_working_directory,
|
|
2292
|
+
verbatim=ct_verbatim,
|
|
2293
|
+
comment=ct_comment,
|
|
2294
|
+
defined_file=ctx.current_list_file,
|
|
2295
|
+
defined_line=cmd.line,
|
|
2296
|
+
)
|
|
2297
|
+
)
|
|
2298
|
+
|
|
2238
2299
|
case "add_test":
|
|
2239
2300
|
# Support: add_test(NAME <name> COMMAND <command> ...)
|
|
2240
2301
|
# Or: add_test(<name> <command> ...)
|
|
@@ -2370,6 +2431,12 @@ int main() {{
|
|
|
2370
2431
|
case "find_path":
|
|
2371
2432
|
if len(args) >= 2:
|
|
2372
2433
|
var_name = args[0]
|
|
2434
|
+
existing = ctx.variables.get(var_name, "")
|
|
2435
|
+
if var_name in ctx.cache_variables or (
|
|
2436
|
+
existing and not existing.endswith("-NOTFOUND")
|
|
2437
|
+
):
|
|
2438
|
+
frame.pc += 1
|
|
2439
|
+
continue
|
|
2373
2440
|
ctx.cache_variables.add(var_name)
|
|
2374
2441
|
names: list[str] = []
|
|
2375
2442
|
paths: list[str] = []
|
|
@@ -2478,6 +2545,12 @@ int main() {{
|
|
|
2478
2545
|
case "find_library":
|
|
2479
2546
|
if len(args) >= 2:
|
|
2480
2547
|
var_name = args[0]
|
|
2548
|
+
existing = ctx.variables.get(var_name, "")
|
|
2549
|
+
if var_name in ctx.cache_variables or (
|
|
2550
|
+
existing and not existing.endswith("-NOTFOUND")
|
|
2551
|
+
):
|
|
2552
|
+
frame.pc += 1
|
|
2553
|
+
continue
|
|
2481
2554
|
ctx.cache_variables.add(var_name)
|
|
2482
2555
|
names: list[str] = []
|
|
2483
2556
|
paths: list[str] = []
|
|
@@ -3519,7 +3592,17 @@ def generate_ninja(
|
|
|
3519
3592
|
return f"-D{name}="
|
|
3520
3593
|
return f"-D{name}={value}"
|
|
3521
3594
|
|
|
3522
|
-
|
|
3595
|
+
cja_cmd = ["cja"]
|
|
3596
|
+
absolute_cja_cmd = shutil.which(cja_cmd[0])
|
|
3597
|
+
if absolute_cja_cmd is None:
|
|
3598
|
+
# If cja is not in PATH, use the current Python executable to run it as a module
|
|
3599
|
+
cja_cmd = [sys.executable, "-m", "cja"]
|
|
3600
|
+
elif os.getenv("VIRTUAL_ENV") is not None:
|
|
3601
|
+
# The venv might not be active when the user runs ninja (e.g. the IDE runs it)
|
|
3602
|
+
cja_cmd = [absolute_cja_cmd]
|
|
3603
|
+
if platform.system() == "Windows":
|
|
3604
|
+
cja_cmd[0] = to_posix_path(cja_cmd[0])
|
|
3605
|
+
reconfigure_cmd_parts = cja_cmd + ["--regenerate-during-build"]
|
|
3523
3606
|
if builddir != "build":
|
|
3524
3607
|
reconfigure_cmd_parts += ["-B", "$builddir"]
|
|
3525
3608
|
for var_name in sorted(ctx.cli_variables):
|
|
@@ -3583,9 +3666,24 @@ def generate_ninja(
|
|
|
3583
3666
|
n.newline()
|
|
3584
3667
|
|
|
3585
3668
|
# Archive rule for static libraries
|
|
3669
|
+
# We must delete the old archive before creating a new one because
|
|
3670
|
+
# ar rcs only adds/replaces members but never removes them.
|
|
3671
|
+
if platform.system() == "Windows":
|
|
3672
|
+
# On Windows, shell metacharacters (&, |, <, >, ^) cause ninja to
|
|
3673
|
+
# wrap the command with cmd.exe, which corrupts pipe handles
|
|
3674
|
+
# ("ReadFile: The handle is invalid"). Use a Python one-liner to
|
|
3675
|
+
# avoid all shell metacharacters so ninja uses CreateProcess directly.
|
|
3676
|
+
ar_command = (
|
|
3677
|
+
'python -c "import os,subprocess,sys;'
|
|
3678
|
+
"o=sys.argv[1];os.path.exists(o) and os.remove(o);"
|
|
3679
|
+
'sys.exit(subprocess.call(sys.argv[2:]))"'
|
|
3680
|
+
" $out $ar rcs $out $in"
|
|
3681
|
+
)
|
|
3682
|
+
else:
|
|
3683
|
+
ar_command = "rm -f $out && $ar rcs $out $in"
|
|
3586
3684
|
n.rule(
|
|
3587
3685
|
"ar",
|
|
3588
|
-
command=
|
|
3686
|
+
command=ar_command,
|
|
3589
3687
|
description="\x1b[32;1mArchiving $out\x1b[0m",
|
|
3590
3688
|
# TODO: CMake shows "Linking C static library" or "Linking C++ static library" instead.
|
|
3591
3689
|
# "static" is redundant info here, but we should also distinguish C vs C++.
|
|
@@ -3660,6 +3758,19 @@ def generate_ninja(
|
|
|
3660
3758
|
)
|
|
3661
3759
|
n.newline()
|
|
3662
3760
|
|
|
3761
|
+
shell_operators = (
|
|
3762
|
+
">",
|
|
3763
|
+
">>",
|
|
3764
|
+
"2>",
|
|
3765
|
+
"2>&1",
|
|
3766
|
+
"<",
|
|
3767
|
+
"|",
|
|
3768
|
+
"&",
|
|
3769
|
+
"&&",
|
|
3770
|
+
"||",
|
|
3771
|
+
";",
|
|
3772
|
+
)
|
|
3773
|
+
|
|
3663
3774
|
# Generate custom commands
|
|
3664
3775
|
for custom_cmd in ctx.custom_commands:
|
|
3665
3776
|
outputs = []
|
|
@@ -3673,18 +3784,6 @@ def generate_ninja(
|
|
|
3673
3784
|
|
|
3674
3785
|
# Process multiple commands
|
|
3675
3786
|
cmd_parts: list[str] = []
|
|
3676
|
-
shell_operators = (
|
|
3677
|
-
">",
|
|
3678
|
-
">>",
|
|
3679
|
-
"2>",
|
|
3680
|
-
"2>&1",
|
|
3681
|
-
"<",
|
|
3682
|
-
"|",
|
|
3683
|
-
"&",
|
|
3684
|
-
"&&",
|
|
3685
|
-
"||",
|
|
3686
|
-
";",
|
|
3687
|
-
)
|
|
3688
3787
|
for command in custom_cmd.commands:
|
|
3689
3788
|
if custom_cmd.verbatim:
|
|
3690
3789
|
parts = []
|
|
@@ -3728,6 +3827,52 @@ def generate_ninja(
|
|
|
3728
3827
|
register_output(out, custom_cmd.defined_file, custom_cmd.defined_line)
|
|
3729
3828
|
n.newline()
|
|
3730
3829
|
|
|
3830
|
+
# Generate custom targets (phony targets)
|
|
3831
|
+
custom_target_all: list[str] = []
|
|
3832
|
+
for ct in ctx.custom_targets:
|
|
3833
|
+
ct_depends = [
|
|
3834
|
+
f"$builddir/{d}"
|
|
3835
|
+
if d in custom_command_outputs and not Path(d).is_absolute()
|
|
3836
|
+
else d
|
|
3837
|
+
for d in ct.depends
|
|
3838
|
+
]
|
|
3839
|
+
|
|
3840
|
+
if ct.commands:
|
|
3841
|
+
# Custom target with commands: use custom_command rule
|
|
3842
|
+
ct_cmd_parts: list[str] = []
|
|
3843
|
+
for command in ct.commands:
|
|
3844
|
+
if ct.verbatim:
|
|
3845
|
+
parts = []
|
|
3846
|
+
for arg in command:
|
|
3847
|
+
if arg in shell_operators:
|
|
3848
|
+
parts.append(str(arg))
|
|
3849
|
+
else:
|
|
3850
|
+
parts.append(shlex.quote(str(arg)))
|
|
3851
|
+
ct_cmd_parts.append(" ".join(parts))
|
|
3852
|
+
else:
|
|
3853
|
+
ct_cmd_parts.append(" ".join(str(c) for c in command))
|
|
3854
|
+
|
|
3855
|
+
ct_cmd_str = " && ".join(ct_cmd_parts)
|
|
3856
|
+
if ct.working_directory:
|
|
3857
|
+
ct_cmd_str = f"cd {ct.working_directory} && {ct_cmd_str}"
|
|
3858
|
+
|
|
3859
|
+
# Use a stamp file so ninja can track when the target last ran
|
|
3860
|
+
stamp = f"$builddir/{ct.name}.stamp"
|
|
3861
|
+
n.build(
|
|
3862
|
+
[stamp],
|
|
3863
|
+
"custom_command",
|
|
3864
|
+
ct_depends,
|
|
3865
|
+
variables={"cmd": f"{ct_cmd_str} && touch {stamp}"},
|
|
3866
|
+
)
|
|
3867
|
+
n.build([ct.name], "phony", [stamp])
|
|
3868
|
+
else:
|
|
3869
|
+
# No commands: purely a phony dependency aggregator
|
|
3870
|
+
n.build([ct.name], "phony", ct_depends)
|
|
3871
|
+
|
|
3872
|
+
if ct.all:
|
|
3873
|
+
custom_target_all.append(ct.name)
|
|
3874
|
+
n.newline()
|
|
3875
|
+
|
|
3731
3876
|
# Helper to expand link libraries recursively
|
|
3732
3877
|
def expand_link_libraries(
|
|
3733
3878
|
initial: list[str], follow_private_of_static: bool
|
|
@@ -4008,6 +4153,7 @@ def generate_ninja(
|
|
|
4008
4153
|
|
|
4009
4154
|
# Collect default targets (libraries that produce real output files)
|
|
4010
4155
|
default_targets: list[str] = list(lib_outputs.values())
|
|
4156
|
+
default_targets.extend(custom_target_all)
|
|
4011
4157
|
|
|
4012
4158
|
# Generate build statements for executables
|
|
4013
4159
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|