clang-tool-chain 1.0.3__py3-none-any.whl
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.
- clang_tool_chain/__init__.py +0 -0
- clang_tool_chain/__version__.py +3 -0
- clang_tool_chain/checksums.py +270 -0
- clang_tool_chain/cli.py +572 -0
- clang_tool_chain/downloader.py +1325 -0
- clang_tool_chain/fetch.py +158 -0
- clang_tool_chain/paths.py +93 -0
- clang_tool_chain/sccache_runner.py +160 -0
- clang_tool_chain/wrapper.py +1589 -0
- clang_tool_chain-1.0.3.dist-info/METADATA +1815 -0
- clang_tool_chain-1.0.3.dist-info/RECORD +14 -0
- clang_tool_chain-1.0.3.dist-info/WHEEL +4 -0
- clang_tool_chain-1.0.3.dist-info/entry_points.txt +31 -0
- clang_tool_chain-1.0.3.dist-info/licenses/LICENSE +204 -0
clang_tool_chain/cli.py
ADDED
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Main entry point for clang-tool-chain CLI.
|
|
3
|
+
|
|
4
|
+
Provides commands for managing and using the LLVM toolchain.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import argparse
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
from typing import NoReturn
|
|
11
|
+
|
|
12
|
+
from . import sccache_runner, wrapper
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
from .__version__ import __version__
|
|
16
|
+
except ImportError:
|
|
17
|
+
__version__ = "unknown"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def cmd_info(args: argparse.Namespace) -> int:
|
|
21
|
+
"""Display information about the toolchain installation."""
|
|
22
|
+
print("Clang Tool Chain - LLVM/Clang Distribution")
|
|
23
|
+
print("=" * 60)
|
|
24
|
+
print()
|
|
25
|
+
|
|
26
|
+
# Platform information
|
|
27
|
+
try:
|
|
28
|
+
platform_name, arch = wrapper.get_platform_info()
|
|
29
|
+
print(f"Platform: {platform_name}")
|
|
30
|
+
print(f"Architecture: {arch}")
|
|
31
|
+
print()
|
|
32
|
+
except RuntimeError as e:
|
|
33
|
+
print(f"Error detecting platform: {e}")
|
|
34
|
+
return 1
|
|
35
|
+
|
|
36
|
+
# Windows GNU ABI information
|
|
37
|
+
if platform_name == "win":
|
|
38
|
+
print("Windows Target Configuration:")
|
|
39
|
+
print(" Default ABI: GNU (x86_64-w64-mingw32)")
|
|
40
|
+
print(" MSVC ABI: Available via clang-tool-chain-c-msvc")
|
|
41
|
+
print(" and clang-tool-chain-cpp-msvc")
|
|
42
|
+
print()
|
|
43
|
+
print("Why GNU ABI is default:")
|
|
44
|
+
print(" - Cross-platform consistency (same ABI on Linux/macOS/Windows)")
|
|
45
|
+
print(" - C++11 strict mode support (MSVC headers require C++14+)")
|
|
46
|
+
print(" - Arduino/embedded compatibility (matches GCC toolchain)")
|
|
47
|
+
print()
|
|
48
|
+
|
|
49
|
+
# Assets directory
|
|
50
|
+
assets_dir = wrapper.get_assets_dir()
|
|
51
|
+
print(f"Assets directory: {assets_dir}")
|
|
52
|
+
print(f"Assets exist: {assets_dir.exists()}")
|
|
53
|
+
print()
|
|
54
|
+
|
|
55
|
+
# Binary directory
|
|
56
|
+
try:
|
|
57
|
+
bin_dir = wrapper.get_platform_binary_dir()
|
|
58
|
+
print(f"Binary directory: {bin_dir}")
|
|
59
|
+
print("Binaries installed: Yes")
|
|
60
|
+
print()
|
|
61
|
+
|
|
62
|
+
# List available tools
|
|
63
|
+
if bin_dir.exists():
|
|
64
|
+
binaries = sorted(
|
|
65
|
+
[f.stem for f in bin_dir.iterdir() if f.is_file()],
|
|
66
|
+
key=str.lower,
|
|
67
|
+
)
|
|
68
|
+
print(f"Available tools ({len(binaries)}):")
|
|
69
|
+
for binary in binaries:
|
|
70
|
+
print(f" - {binary}")
|
|
71
|
+
except RuntimeError:
|
|
72
|
+
print("Binaries installed: No")
|
|
73
|
+
print()
|
|
74
|
+
print("To install binaries, run:")
|
|
75
|
+
print(" python scripts/download_binaries.py --current-only")
|
|
76
|
+
print(" python scripts/strip_binaries.py <extracted_dir> <output_dir> --platform <platform>")
|
|
77
|
+
|
|
78
|
+
return 0
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def cmd_version(args: argparse.Namespace) -> int:
|
|
82
|
+
"""Display version of a specific tool."""
|
|
83
|
+
tool_name: str = args.tool
|
|
84
|
+
|
|
85
|
+
# Map common names to actual tool names
|
|
86
|
+
tool_map = {
|
|
87
|
+
"c": "clang",
|
|
88
|
+
"cpp": "clang++",
|
|
89
|
+
"c++": "clang++",
|
|
90
|
+
"ld": "lld",
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
actual_tool: str = tool_map.get(tool_name, tool_name)
|
|
94
|
+
|
|
95
|
+
try:
|
|
96
|
+
wrapper.find_tool_binary(actual_tool)
|
|
97
|
+
result = wrapper.run_tool(actual_tool, ["--version"])
|
|
98
|
+
return result
|
|
99
|
+
except RuntimeError as e:
|
|
100
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
101
|
+
return 1
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def cmd_list_tools(args: argparse.Namespace) -> int:
|
|
105
|
+
"""List all available wrapper tools."""
|
|
106
|
+
print("Available clang-tool-chain commands:")
|
|
107
|
+
print("=" * 60)
|
|
108
|
+
print()
|
|
109
|
+
|
|
110
|
+
tools = [
|
|
111
|
+
("clang-tool-chain-c", "C compiler (clang) - GNU ABI on Windows"),
|
|
112
|
+
("clang-tool-chain-cpp", "C++ compiler (clang++) - GNU ABI on Windows"),
|
|
113
|
+
("clang-tool-chain-c-msvc", "C compiler (clang) - MSVC ABI (Windows only)"),
|
|
114
|
+
("clang-tool-chain-cpp-msvc", "C++ compiler (clang++) - MSVC ABI (Windows only)"),
|
|
115
|
+
("clang-tool-chain-ld", "LLVM linker (lld/lld-link)"),
|
|
116
|
+
("clang-tool-chain-ar", "Archive tool (llvm-ar)"),
|
|
117
|
+
("clang-tool-chain-nm", "Symbol table viewer (llvm-nm)"),
|
|
118
|
+
("clang-tool-chain-objdump", "Object file dumper (llvm-objdump)"),
|
|
119
|
+
("clang-tool-chain-objcopy", "Object copying tool (llvm-objcopy)"),
|
|
120
|
+
("clang-tool-chain-ranlib", "Archive index generator (llvm-ranlib)"),
|
|
121
|
+
("clang-tool-chain-strip", "Symbol stripper (llvm-strip)"),
|
|
122
|
+
("clang-tool-chain-readelf", "ELF file reader (llvm-readelf)"),
|
|
123
|
+
("clang-tool-chain-as", "LLVM assembler (llvm-as)"),
|
|
124
|
+
("clang-tool-chain-dis", "LLVM disassembler (llvm-dis)"),
|
|
125
|
+
("clang-tool-chain-format", "Code formatter (clang-format)"),
|
|
126
|
+
("clang-tool-chain-tidy", "Static analyzer (clang-tidy)"),
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
for cmd, desc in tools:
|
|
130
|
+
print(f" {cmd:30s} - {desc}")
|
|
131
|
+
|
|
132
|
+
print()
|
|
133
|
+
print("sccache integration (requires sccache in PATH):")
|
|
134
|
+
print("=" * 60)
|
|
135
|
+
print()
|
|
136
|
+
|
|
137
|
+
sccache_tools = [
|
|
138
|
+
("clang-tool-chain-sccache", "Direct sccache access (stats, management)"),
|
|
139
|
+
("clang-tool-chain-sccache-c", "sccache + C compiler (clang)"),
|
|
140
|
+
("clang-tool-chain-sccache-cpp", "sccache + C++ compiler (clang++)"),
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
for cmd, desc in sccache_tools:
|
|
144
|
+
print(f" {cmd:30s} - {desc}")
|
|
145
|
+
|
|
146
|
+
print()
|
|
147
|
+
print("For more information, run:")
|
|
148
|
+
print(" clang-tool-chain info")
|
|
149
|
+
|
|
150
|
+
return 0
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def cmd_path(args: argparse.Namespace) -> int:
|
|
154
|
+
"""Display the path to the binary directory or a specific tool."""
|
|
155
|
+
try:
|
|
156
|
+
if args.tool:
|
|
157
|
+
tool_name: str = args.tool
|
|
158
|
+
# Map common names to actual tool names
|
|
159
|
+
tool_map = {
|
|
160
|
+
"c": "clang",
|
|
161
|
+
"cpp": "clang++",
|
|
162
|
+
"c++": "clang++",
|
|
163
|
+
"ld": "lld",
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
actual_tool: str = tool_map.get(tool_name, tool_name)
|
|
167
|
+
tool_path = wrapper.find_tool_binary(actual_tool)
|
|
168
|
+
print(tool_path)
|
|
169
|
+
else:
|
|
170
|
+
bin_dir = wrapper.get_platform_binary_dir()
|
|
171
|
+
print(bin_dir)
|
|
172
|
+
return 0
|
|
173
|
+
except RuntimeError as e:
|
|
174
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
175
|
+
return 1
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def cmd_package_version(args: argparse.Namespace) -> int:
|
|
179
|
+
"""Display the package version."""
|
|
180
|
+
print(f"clang-tool-chain version: {__version__}")
|
|
181
|
+
print()
|
|
182
|
+
|
|
183
|
+
if args.verbose:
|
|
184
|
+
# Show more detailed version information
|
|
185
|
+
print("Package Information:")
|
|
186
|
+
print("=" * 60)
|
|
187
|
+
print(" Package: clang-tool-chain")
|
|
188
|
+
print(f" Version: {__version__}")
|
|
189
|
+
print()
|
|
190
|
+
|
|
191
|
+
# Try to get actual clang version from installed binaries
|
|
192
|
+
try:
|
|
193
|
+
platform_name, arch = wrapper.get_platform_info()
|
|
194
|
+
print("Platform Information:")
|
|
195
|
+
print(f" Platform: {platform_name}")
|
|
196
|
+
print(f" Architecture: {arch}")
|
|
197
|
+
print()
|
|
198
|
+
|
|
199
|
+
# Try to get installed clang version
|
|
200
|
+
try:
|
|
201
|
+
wrapper.find_tool_binary("clang")
|
|
202
|
+
print("Installed LLVM/Clang:")
|
|
203
|
+
result = wrapper.run_tool("clang", ["--version"])
|
|
204
|
+
if result != 0:
|
|
205
|
+
print(" (Unable to determine version)")
|
|
206
|
+
except RuntimeError:
|
|
207
|
+
print("Installed LLVM/Clang:")
|
|
208
|
+
print(" Not installed yet")
|
|
209
|
+
print()
|
|
210
|
+
print("To install binaries, run:")
|
|
211
|
+
print(" python scripts/download_binaries.py --current-only")
|
|
212
|
+
print(" python scripts/strip_binaries.py <extracted_dir> <output_dir> --platform <platform>")
|
|
213
|
+
except RuntimeError as e:
|
|
214
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
215
|
+
|
|
216
|
+
return 0
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def cmd_test(args: argparse.Namespace) -> int:
|
|
220
|
+
"""Run diagnostic tests to verify the toolchain installation."""
|
|
221
|
+
import tempfile
|
|
222
|
+
from pathlib import Path
|
|
223
|
+
|
|
224
|
+
print("Clang Tool Chain - Diagnostic Tests")
|
|
225
|
+
print("=" * 70)
|
|
226
|
+
print()
|
|
227
|
+
|
|
228
|
+
# Test 1: Platform Detection
|
|
229
|
+
print("[1/7] Testing platform detection...")
|
|
230
|
+
try:
|
|
231
|
+
platform_name, arch = wrapper.get_platform_info()
|
|
232
|
+
print(f" Platform: {platform_name}/{arch}")
|
|
233
|
+
print(" ✓ PASSED")
|
|
234
|
+
except Exception as e:
|
|
235
|
+
print(f" ✗ FAILED: {e}")
|
|
236
|
+
return 1
|
|
237
|
+
print()
|
|
238
|
+
|
|
239
|
+
# Test 2: Toolchain Download/Installation
|
|
240
|
+
print("[2/7] Testing toolchain installation...")
|
|
241
|
+
try:
|
|
242
|
+
bin_dir = wrapper.get_platform_binary_dir()
|
|
243
|
+
if bin_dir.exists():
|
|
244
|
+
print(f" Binary directory: {bin_dir}")
|
|
245
|
+
print(" ✓ PASSED")
|
|
246
|
+
else:
|
|
247
|
+
print(f" ✗ FAILED: Binary directory does not exist: {bin_dir}")
|
|
248
|
+
return 1
|
|
249
|
+
except Exception as e:
|
|
250
|
+
print(f" ✗ FAILED: {e}")
|
|
251
|
+
return 1
|
|
252
|
+
print()
|
|
253
|
+
|
|
254
|
+
# Test 3: Finding clang binary
|
|
255
|
+
print("[3/7] Testing binary resolution (clang)...")
|
|
256
|
+
try:
|
|
257
|
+
clang_path = wrapper.find_tool_binary("clang")
|
|
258
|
+
print(f" Found: {clang_path}")
|
|
259
|
+
if not clang_path.exists():
|
|
260
|
+
print(f" ✗ FAILED: Binary does not exist: {clang_path}")
|
|
261
|
+
return 1
|
|
262
|
+
print(" ✓ PASSED")
|
|
263
|
+
except Exception as e:
|
|
264
|
+
print(f" ✗ FAILED: {e}")
|
|
265
|
+
return 1
|
|
266
|
+
print()
|
|
267
|
+
|
|
268
|
+
# Test 4: Finding clang++ binary
|
|
269
|
+
print("[4/7] Testing binary resolution (clang++)...")
|
|
270
|
+
try:
|
|
271
|
+
clang_cpp_path = wrapper.find_tool_binary("clang++")
|
|
272
|
+
print(f" Found: {clang_cpp_path}")
|
|
273
|
+
if not clang_cpp_path.exists():
|
|
274
|
+
print(f" ✗ FAILED: Binary does not exist: {clang_cpp_path}")
|
|
275
|
+
return 1
|
|
276
|
+
print(" ✓ PASSED")
|
|
277
|
+
except Exception as e:
|
|
278
|
+
print(f" ✗ FAILED: {e}")
|
|
279
|
+
return 1
|
|
280
|
+
print()
|
|
281
|
+
|
|
282
|
+
# Test 5: Version check for clang
|
|
283
|
+
print("[5/7] Testing clang version...")
|
|
284
|
+
try:
|
|
285
|
+
result = subprocess.run([str(clang_path), "--version"], capture_output=True, text=True, timeout=10)
|
|
286
|
+
if result.returncode == 0:
|
|
287
|
+
version_line = result.stdout.split("\n")[0]
|
|
288
|
+
print(f" {version_line}")
|
|
289
|
+
print(" ✓ PASSED")
|
|
290
|
+
else:
|
|
291
|
+
print(f" ✗ FAILED: clang --version returned {result.returncode}")
|
|
292
|
+
print(f" stderr: {result.stderr}")
|
|
293
|
+
return 1
|
|
294
|
+
except Exception as e:
|
|
295
|
+
print(f" ✗ FAILED: {e}")
|
|
296
|
+
return 1
|
|
297
|
+
print()
|
|
298
|
+
|
|
299
|
+
# Test 6: Simple compilation test
|
|
300
|
+
print("[6/7] Testing C compilation...")
|
|
301
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
302
|
+
tmpdir_path = Path(tmpdir)
|
|
303
|
+
test_c = tmpdir_path / "test.c"
|
|
304
|
+
test_out = tmpdir_path / "test"
|
|
305
|
+
if platform_name == "win":
|
|
306
|
+
test_out = test_out.with_suffix(".exe")
|
|
307
|
+
|
|
308
|
+
# Write simple C program
|
|
309
|
+
test_c.write_text(
|
|
310
|
+
"""
|
|
311
|
+
#include <stdio.h>
|
|
312
|
+
int main() {
|
|
313
|
+
printf("Hello from clang-tool-chain!\\n");
|
|
314
|
+
return 0;
|
|
315
|
+
}
|
|
316
|
+
"""
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
try:
|
|
320
|
+
# Compile
|
|
321
|
+
result = subprocess.run(
|
|
322
|
+
[str(clang_path), str(test_c), "-o", str(test_out)], capture_output=True, text=True, timeout=30
|
|
323
|
+
)
|
|
324
|
+
if result.returncode != 0:
|
|
325
|
+
print(" ✗ FAILED: Compilation failed")
|
|
326
|
+
print(f" stdout: {result.stdout}")
|
|
327
|
+
print(f" stderr: {result.stderr}")
|
|
328
|
+
return 1
|
|
329
|
+
|
|
330
|
+
# Verify output file was created
|
|
331
|
+
if not test_out.exists():
|
|
332
|
+
print(f" ✗ FAILED: Output binary not created: {test_out}")
|
|
333
|
+
return 1
|
|
334
|
+
|
|
335
|
+
print(f" Compiled: {test_out}")
|
|
336
|
+
print(" ✓ PASSED")
|
|
337
|
+
except Exception as e:
|
|
338
|
+
print(f" ✗ FAILED: {e}")
|
|
339
|
+
return 1
|
|
340
|
+
print()
|
|
341
|
+
|
|
342
|
+
# Test 7: Simple C++ compilation test
|
|
343
|
+
print("[7/7] Testing C++ compilation...")
|
|
344
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
345
|
+
tmpdir_path = Path(tmpdir)
|
|
346
|
+
test_cpp = tmpdir_path / "test.cpp"
|
|
347
|
+
test_out = tmpdir_path / "test"
|
|
348
|
+
if platform_name == "win":
|
|
349
|
+
test_out = test_out.with_suffix(".exe")
|
|
350
|
+
|
|
351
|
+
# Write simple C++ program
|
|
352
|
+
test_cpp.write_text(
|
|
353
|
+
"""
|
|
354
|
+
#include <iostream>
|
|
355
|
+
int main() {
|
|
356
|
+
std::cout << "Hello from clang-tool-chain C++!" << std::endl;
|
|
357
|
+
return 0;
|
|
358
|
+
}
|
|
359
|
+
"""
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
try:
|
|
363
|
+
# Compile
|
|
364
|
+
result = subprocess.run(
|
|
365
|
+
[str(clang_cpp_path), str(test_cpp), "-o", str(test_out)], capture_output=True, text=True, timeout=30
|
|
366
|
+
)
|
|
367
|
+
if result.returncode != 0:
|
|
368
|
+
print(" ✗ FAILED: Compilation failed")
|
|
369
|
+
print(f" stdout: {result.stdout}")
|
|
370
|
+
print(f" stderr: {result.stderr}")
|
|
371
|
+
return 1
|
|
372
|
+
|
|
373
|
+
# Verify output file was created
|
|
374
|
+
if not test_out.exists():
|
|
375
|
+
print(f" ✗ FAILED: Output binary not created: {test_out}")
|
|
376
|
+
return 1
|
|
377
|
+
|
|
378
|
+
print(f" Compiled: {test_out}")
|
|
379
|
+
print(" ✓ PASSED")
|
|
380
|
+
except Exception as e:
|
|
381
|
+
print(f" ✗ FAILED: {e}")
|
|
382
|
+
return 1
|
|
383
|
+
print()
|
|
384
|
+
|
|
385
|
+
print("=" * 70)
|
|
386
|
+
print("All tests passed! ✓")
|
|
387
|
+
print()
|
|
388
|
+
return 0
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def main() -> int:
|
|
392
|
+
"""Main entry point for the clang-tool-chain CLI."""
|
|
393
|
+
parser = argparse.ArgumentParser(
|
|
394
|
+
prog="clang-tool-chain",
|
|
395
|
+
description="LLVM/Clang toolchain management and wrapper utilities",
|
|
396
|
+
epilog="For more information, visit: https://github.com/your-repo/clang-tool-chain",
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
subparsers = parser.add_subparsers(
|
|
400
|
+
dest="command",
|
|
401
|
+
help="Available commands",
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
# info command
|
|
405
|
+
parser_info = subparsers.add_parser(
|
|
406
|
+
"info",
|
|
407
|
+
help="Display information about the toolchain installation",
|
|
408
|
+
)
|
|
409
|
+
parser_info.set_defaults(func=cmd_info)
|
|
410
|
+
|
|
411
|
+
# version command
|
|
412
|
+
parser_version = subparsers.add_parser(
|
|
413
|
+
"version",
|
|
414
|
+
help="Display version of a specific tool",
|
|
415
|
+
)
|
|
416
|
+
parser_version.add_argument(
|
|
417
|
+
"tool",
|
|
418
|
+
help="Tool name (e.g., clang, clang++, lld)",
|
|
419
|
+
)
|
|
420
|
+
parser_version.set_defaults(func=cmd_version)
|
|
421
|
+
|
|
422
|
+
# list-tools command
|
|
423
|
+
parser_list = subparsers.add_parser(
|
|
424
|
+
"list-tools",
|
|
425
|
+
help="List all available wrapper tools",
|
|
426
|
+
)
|
|
427
|
+
parser_list.set_defaults(func=cmd_list_tools)
|
|
428
|
+
|
|
429
|
+
# path command
|
|
430
|
+
parser_path = subparsers.add_parser(
|
|
431
|
+
"path",
|
|
432
|
+
help="Display the path to the binary directory or a specific tool",
|
|
433
|
+
)
|
|
434
|
+
parser_path.add_argument(
|
|
435
|
+
"tool",
|
|
436
|
+
nargs="?",
|
|
437
|
+
help="Tool name (optional, prints binary directory if not specified)",
|
|
438
|
+
)
|
|
439
|
+
parser_path.set_defaults(func=cmd_path)
|
|
440
|
+
|
|
441
|
+
# package-version command
|
|
442
|
+
parser_pkg_version = subparsers.add_parser(
|
|
443
|
+
"package-version",
|
|
444
|
+
help="Display the package version and target LLVM version",
|
|
445
|
+
)
|
|
446
|
+
parser_pkg_version.add_argument(
|
|
447
|
+
"-v",
|
|
448
|
+
"--verbose",
|
|
449
|
+
action="store_true",
|
|
450
|
+
help="Show detailed version information including installed LLVM version",
|
|
451
|
+
)
|
|
452
|
+
parser_pkg_version.set_defaults(func=cmd_package_version)
|
|
453
|
+
|
|
454
|
+
# test command
|
|
455
|
+
parser_test = subparsers.add_parser(
|
|
456
|
+
"test",
|
|
457
|
+
help="Run diagnostic tests to verify the toolchain installation",
|
|
458
|
+
)
|
|
459
|
+
parser_test.set_defaults(func=cmd_test)
|
|
460
|
+
|
|
461
|
+
# Parse arguments
|
|
462
|
+
args = parser.parse_args()
|
|
463
|
+
|
|
464
|
+
# If no command specified, show help
|
|
465
|
+
if not args.command:
|
|
466
|
+
parser.print_help()
|
|
467
|
+
return 0
|
|
468
|
+
|
|
469
|
+
# Execute command
|
|
470
|
+
return args.func(args)
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def test_main() -> int:
|
|
474
|
+
"""
|
|
475
|
+
Standalone entry point for the test command.
|
|
476
|
+
|
|
477
|
+
This allows running: clang-tool-chain-test
|
|
478
|
+
"""
|
|
479
|
+
import argparse
|
|
480
|
+
|
|
481
|
+
args = argparse.Namespace() # Empty namespace
|
|
482
|
+
return cmd_test(args)
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
def sccache_main() -> int:
|
|
486
|
+
"""
|
|
487
|
+
Entry point for direct sccache passthrough command.
|
|
488
|
+
|
|
489
|
+
This command allows users to run sccache directly for commands like:
|
|
490
|
+
- clang-tool-chain-sccache --show-stats
|
|
491
|
+
- clang-tool-chain-sccache --zero-stats
|
|
492
|
+
- clang-tool-chain-sccache --start-server
|
|
493
|
+
- clang-tool-chain-sccache --stop-server
|
|
494
|
+
|
|
495
|
+
If sccache is not found in PATH, automatically uses iso-env to run it in an isolated environment.
|
|
496
|
+
"""
|
|
497
|
+
args = sys.argv[1:]
|
|
498
|
+
return sccache_runner.run_sccache(args)
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
def sccache_c_main() -> int:
|
|
502
|
+
"""
|
|
503
|
+
Entry point for sccache + clang C compiler wrapper.
|
|
504
|
+
|
|
505
|
+
This command wraps the clang C compiler with sccache for compilation caching.
|
|
506
|
+
If sccache is not found in PATH, automatically uses iso-env to run it in an isolated environment.
|
|
507
|
+
"""
|
|
508
|
+
args = sys.argv[1:]
|
|
509
|
+
|
|
510
|
+
# Find the clang binary from clang-tool-chain
|
|
511
|
+
try:
|
|
512
|
+
clang_path = wrapper.find_tool_binary("clang")
|
|
513
|
+
except RuntimeError as e:
|
|
514
|
+
print("=" * 70, file=sys.stderr)
|
|
515
|
+
print("ERROR: Failed to locate clang binary", file=sys.stderr)
|
|
516
|
+
print("=" * 70, file=sys.stderr)
|
|
517
|
+
print(file=sys.stderr)
|
|
518
|
+
print(str(e), file=sys.stderr)
|
|
519
|
+
print(file=sys.stderr)
|
|
520
|
+
print("=" * 70, file=sys.stderr)
|
|
521
|
+
return 1
|
|
522
|
+
|
|
523
|
+
return sccache_runner.run_sccache_with_compiler(str(clang_path), args)
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
def sccache_cpp_main() -> int:
|
|
527
|
+
"""
|
|
528
|
+
Entry point for sccache + clang++ C++ compiler wrapper.
|
|
529
|
+
|
|
530
|
+
This command wraps the clang++ C++ compiler with sccache for compilation caching.
|
|
531
|
+
If sccache is not found in PATH, automatically uses iso-env to run it in an isolated environment.
|
|
532
|
+
"""
|
|
533
|
+
args = sys.argv[1:]
|
|
534
|
+
|
|
535
|
+
# Find the clang++ binary from clang-tool-chain
|
|
536
|
+
try:
|
|
537
|
+
clang_cpp_path = wrapper.find_tool_binary("clang++")
|
|
538
|
+
except RuntimeError as e:
|
|
539
|
+
print("=" * 70, file=sys.stderr)
|
|
540
|
+
print("ERROR: Failed to locate clang++ binary", file=sys.stderr)
|
|
541
|
+
print("=" * 70, file=sys.stderr)
|
|
542
|
+
print(file=sys.stderr)
|
|
543
|
+
print(str(e), file=sys.stderr)
|
|
544
|
+
print(file=sys.stderr)
|
|
545
|
+
print("=" * 70, file=sys.stderr)
|
|
546
|
+
return 1
|
|
547
|
+
|
|
548
|
+
return sccache_runner.run_sccache_with_compiler(str(clang_cpp_path), args)
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
def sccache_c_msvc_main() -> NoReturn:
|
|
552
|
+
"""
|
|
553
|
+
Entry point for sccache + clang C compiler wrapper with MSVC ABI.
|
|
554
|
+
|
|
555
|
+
This command wraps the clang C compiler with sccache for compilation caching,
|
|
556
|
+
using MSVC ABI target on Windows.
|
|
557
|
+
"""
|
|
558
|
+
wrapper.sccache_clang_main(use_msvc=True)
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
def sccache_cpp_msvc_main() -> NoReturn:
|
|
562
|
+
"""
|
|
563
|
+
Entry point for sccache + clang++ C++ compiler wrapper with MSVC ABI.
|
|
564
|
+
|
|
565
|
+
This command wraps the clang++ C++ compiler with sccache for compilation caching,
|
|
566
|
+
using MSVC ABI target on Windows.
|
|
567
|
+
"""
|
|
568
|
+
wrapper.sccache_clang_cpp_main(use_msvc=True)
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
if __name__ == "__main__":
|
|
572
|
+
sys.exit(main())
|