Merge pull request #11421 from mon/ti-armclang

Basic support for TI Arm Clang toolchain
diff --git a/docs/markdown/snippets/ti_armclang.md b/docs/markdown/snippets/ti_armclang.md
new file mode 100644
index 0000000..7f0f912
--- /dev/null
+++ b/docs/markdown/snippets/ti_armclang.md
@@ -0,0 +1,3 @@
+## Basic support for TI Arm Clang (tiarmclang)
+
+Support for TI's newer [Clang-based ARM toolchain](https://www.ti.com/tool/ARM-CGT).
diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py
index 6e35e7d..90a3ac5 100644
--- a/mesonbuild/compilers/detect.py
+++ b/mesonbuild/compilers/detect.py
@@ -224,14 +224,13 @@
             return linkers.CcrxLinker(linker)
         if out.startswith('GNU ar') and 'xc16-ar' in linker_name:
             return linkers.Xc16Linker(linker)
-        if "-->  error: bad option 'e'" in err: # TI
+        if 'Texas Instruments Incorporated' in out:
             if 'ar2000' in linker_name:
                 return linkers.C2000Linker(linker)
+            elif 'ar6000' in linker_name:
+                return linkers.C6000Linker(linker)
             else:
                 return linkers.TILinker(linker)
-        if 'Texas Instruments Incorporated' in out:
-            if 'ar6000' in linker_name:
-                return linkers.C6000Linker(linker)
         if out.startswith('The CompCert'):
             return linkers.CompCertLinker(linker)
         if out.strip().startswith('Metrowerks') or out.strip().startswith('Freescale'):
@@ -437,8 +436,8 @@
            'TI ARM C/C++ Compiler': (c.TICCompiler, cpp.TICPPCompiler, linkers.TIDynamicLinker),
            'MSP430 C/C++': (c.TICCompiler, cpp.TICPPCompiler, linkers.TIDynamicLinker)
         }
-        for indentifier, compiler_classes in ti_compilers.items():
-            if indentifier in out:
+        for identifier, compiler_classes in ti_compilers.items():
+            if identifier in out:
                 cls = compiler_classes[0] if lang == 'c' else compiler_classes[1]
                 lnk = compiler_classes[2]
                 env.coredata.add_lang_args(cls.language, cls, for_machine, env)
diff --git a/mesonbuild/linkers/detect.py b/mesonbuild/linkers/detect.py
index bb391d1..65d77f6 100644
--- a/mesonbuild/linkers/detect.py
+++ b/mesonbuild/linkers/detect.py
@@ -141,7 +141,7 @@
 
     v = search_version(o + e)
     linker: DynamicLinker
-    if 'LLD' in o.split('\n', maxsplit=1)[0]:
+    if 'LLD' in o.split('\n', maxsplit=1)[0] or 'tiarmlnk' in e:
         if isinstance(comp_class.LINKER_PREFIX, str):
             cmd = compiler + override + [comp_class.LINKER_PREFIX + '-v'] + extra_args
         else:
diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py
index ca3c854..de08e0f 100644
--- a/mesonbuild/linkers/linkers.py
+++ b/mesonbuild/linkers/linkers.py
@@ -885,15 +885,36 @@
         super().__init__(exelist, for_machine, prefix_arg, always_args, version=version)
 
         # Some targets don't seem to support this argument (windows, wasm, ...)
-        _, _, e = mesonlib.Popen_safe(self.exelist + always_args + self._apply_prefix('--allow-shlib-undefined'))
-        # Versions < 9 do not have a quoted argument
-        self.has_allow_shlib_undefined = ('unknown argument: --allow-shlib-undefined' not in e) and ("unknown argument: '--allow-shlib-undefined'" not in e)
+        self.has_allow_shlib_undefined = self._supports_flag('--allow-shlib-undefined', always_args)
+        # These aren't supported by TI Arm Clang
+        self.has_as_needed = self._supports_flag('--as-needed', always_args)
+        self.has_no_undefined = self._supports_flag('--no-undefined', always_args)
+
+    def _supports_flag(self, flag: str, always_args: T.List[str]) -> bool:
+        _, _, e = mesonlib.Popen_safe(self.exelist + always_args + self._apply_prefix(flag))
+        return (
+            # Versions < 9 do not have a quoted argument
+            (f'unknown argument: {flag}' not in e) and
+            (f"unknown argument: '{flag}'" not in e) and
+            # TI Arm Clang uses a different message
+            (f'invalid option:  {flag}' not in e)
+        )
 
     def get_allow_undefined_args(self) -> T.List[str]:
         if self.has_allow_shlib_undefined:
             return self._apply_prefix('--allow-shlib-undefined')
         return []
 
+    def get_asneeded_args(self) -> T.List[str]:
+        if self.has_as_needed:
+            return self._apply_prefix('--as-needed')
+        return []
+
+    def no_undefined_args(self) -> T.List[str]:
+        if self.has_no_undefined:
+            return self._apply_prefix('--no-undefined')
+        return []
+
     def get_thinlto_cache_args(self, path: str) -> T.List[str]:
         return ['-Wl,--thinlto-cache-dir=' + path]