1 /* MIT License
2 * Copyright (c) 2025 Matheus C. França
3 * See LICENSE file for details
4 */
5 
6 /// Utilities for comparing LLVM versions between compilers.
7 module builder.llvmversion;
8 
9 version(LDC):
10 
11 import std.process;
12 import std.string;
13 import std.array;
14 import std.algorithm : find;
15 import std.exception : enforce;
16 
17 /// Compares LLVM versions used by ldc2 and zig cc.
18 /// Returns: true if versions match, false otherwise.
19 /// Throws: Exception if command execution fails or versions cannot be parsed.
20 bool hasMatchingLLVMVersions() @safe
21 {
22     auto zigResult = execute(["zig", "cc", "--version"]);
23     enforce(zigResult.status == 0, "Failed to execute zig cc --version: " ~ zigResult.output);
24     auto zigLines = zigResult.output.splitLines;
25     enforce(zigLines.length > 0, "No output from zig cc --version");
26 
27     // Extract zig cc version
28     auto zigFirstLine = zigLines[0].strip;
29     auto zigFields = zigFirstLine.split;
30     enforce(zigFields.length >= 3 && zigFields[0] == "clang" && zigFields[1] == "version",
31         "Unexpected zig cc --version format: " ~ zigFirstLine);
32     string zigVersion = zigFields[2];
33 
34     auto ldcResult = execute(["ldc2", "--version"]);
35     enforce(ldcResult.status == 0, "Failed to execute ldc2 --version: " ~ ldcResult.output);
36     auto ldcLines = ldcResult.output.splitLines;
37     enforce(ldcLines.length > 1, "Insufficient output from ldc2 --version");
38 
39     // Extract ldc2 version
40     auto ldcSecondLine = ldcLines[1].strip;
41     auto ldcFields = ldcSecondLine.split;
42     auto llvmIndex = ldcFields.indexOf("LLVM");
43     enforce(llvmIndex >= 0 && llvmIndex + 1 < ldcFields.length,
44         "Unexpected ldc2 --version format: " ~ ldcSecondLine);
45     string ldcVersion = ldcFields[llvmIndex + 1].strip;
46 
47     // Compare versions
48     return zigVersion == ldcVersion;
49 }
50 
51 private ptrdiff_t indexOf(string[] arr, string value) @trusted @nogc nothrow
52 {
53     foreach (i, v; arr)
54         if (v == value)
55             return i;
56     return -1;
57 }
58 
59 version (unittest)
60 {
61     @("Check LLVM version matching")
62     @safe unittest
63     {
64         bool result = hasMatchingLLVMVersions();
65         assert(!result, "Expected different LLVM versions");
66 
67     }
68 }