[llvm] cmake: Derive CMake system name from a triple via new mechanism (PR #208773)

Alexis Engelke via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 30 06:30:31 PDT 2026


================
@@ -0,0 +1,155 @@
+#!/usr/bin/env python3
+"""Derive a CMake system name from a target triple.
+
+The recognized OS and environment names are defined in
+llvm/include/llvm/TargetParser/TripleName.def. This script parses that
+file so the CMake runtimes build can map a (possibly unnormalized)
+triple to a CMake system name without running a compiled tool. CMake
+invokes it once per target with --triple and reads the printed name.
+
+Modes:
+  --triple TRIPLE   Print the CMake system name for TRIPLE (empty if unknown or
+                    the triple has too few components; the caller then falls back
+                    to the host system name).
+
+Options:
+  --def-file PATH   Path to TripleName.def to parse instead of the copy located
+                    relative to this script (in llvm/include/llvm/TargetParser).
+
+"""
+
+import argparse
+import os
+import re
+import sys
+
+_OS_RE = re.compile(r'^\s*TRIPLE_OS\(\s*(\w+)\s*,\s*"([^"]*)"\s*,\s*"([^"]*)"\s*\)')
+_OS_ALIAS_RE = re.compile(r'^\s*TRIPLE_OS_ALIAS\(\s*(\w+)\s*,\s*"([^"]*)"\s*\)')
+_ENV_RE = re.compile(r'^\s*TRIPLE_ENV\(\s*(\w+)\s*,\s*"([^"]*)"\s*,\s*"([^"]*)"\s*\)')
+
+
+class TripleNames:
+    def __init__(self):
+        # Ordered lists of (prefix, value) preserving .def order, which matters
+        # for prefix matching (longer prefixes precede shorter ones).
+        self.os = []  # (name, cmake_name)
+        self.env = []  # (name, cmake_override)
+
+
+def find_def_file():
+    # This script lives in llvm/utils/, the .def in llvm/include/...
+    llvm_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+    return os.path.join(llvm_dir, "include", "llvm", "TargetParser", "TripleName.def")
+
+
+def parse(def_path):
+    names = TripleNames()
+    with open(def_path) as f:
+        lines = f.readlines()
+
+    # First pass: map each OS enum to its CMake name so aliases can reuse it.
+    os_cmake = {}
+    for line in lines:
+        m = _OS_RE.match(line)
+        if m:
+            enum, _name, cmake_name = m.groups()
+            os_cmake[enum] = cmake_name
+
+    # Second pass: build the ordered lists (order matters for prefix matching).
+    for line in lines:
+        m = _OS_RE.match(line)
+        if m:
+            _enum, name, cmake_name = m.groups()
+            names.os.append((name, cmake_name))
+            continue
+        m = _OS_ALIAS_RE.match(line)
+        if m:
+            enum, alias = m.groups()
+            names.os.append((alias, os_cmake.get(enum, "Generic")))
+            continue
+        m = _ENV_RE.match(line)
+        if m:
+            _enum, name, override = m.groups()
+            names.env.append((name, override))
+    return names
+
+
+def system_name(names, triple):
+    # Mirror the component classification of Triple::normalize: do not
+    # trust fixed positions. A triple may omit the vendor
+    # (aarch64-linux-android), put the os in the vendor slot
+    # (wasm32-wasi, i686-linux), or even be a bare os with no arch at
+    # all (clang accepts --target=darwin as unknown-unknown-darwin),
+    # so scan every component and use the first that classifies. No
+    # arch name is a prefix of any os/env name, so scanning the first
+    # component too cannot misclassify a real arch. This makes the
+    # result match what normalize would produce even for unnormalized
+    # inputs.
+    parts = triple.split("-")
+    rest = parts
----------------
aengelke wrote:

why two variables?

https://github.com/llvm/llvm-project/pull/208773


More information about the llvm-commits mailing list