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 for LTO build.
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     }
69 }