Browse Source

LinkerId: Try multiple flags to detect linker id and version

In general there is no one flag on any platform that can identify every
linker.
Brad King 2 years ago
parent
commit
c1e48a19a5
1 changed files with 51 additions and 42 deletions
  1. 51 42
      Modules/Internal/CMakeDetermineLinkerId.cmake

+ 51 - 42
Modules/Internal/CMakeDetermineLinkerId.cmake

@@ -19,53 +19,62 @@ function(cmake_determine_linker_id lang linker)
     return()
   endif()
 
-  if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR linker MATCHES "lld$")
-    set(flags "--version")
-  else()
-    set(flags "-v")
-  endif()
-  execute_process(COMMAND "${linker}" ${flags}
-                  OUTPUT_VARIABLE linker_desc
-                  ERROR_VARIABLE linker_desc
-                  OUTPUT_STRIP_TRAILING_WHITESPACE
-                  ERROR_STRIP_TRAILING_WHITESPACE)
-
+  set(linker_id)
   set(linker_frontend)
   set(linker_version)
 
   # Compute the linker ID and version.
-  if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND linker_desc MATCHES "@\\(#\\)PROGRAM:ld.+PROJECT:[a-z0-9]+-([0-9.]+).+")
-    set(linker_id "AppleClang")
-    set(linker_frontend "GNU")
-    set(linker_version "${CMAKE_MATCH_1}")
-  elseif (linker_desc MATCHES "mold \\(sold\\) ([0-9.]+)")
-    set(linker_id "MOLD")
-    set(linker_frontend "GNU")
-    set(linker_version "${CMAKE_MATCH_1}")
-  elseif (linker_desc MATCHES "mold ([0-9.]+)")
-    set(linker_id "MOLD")
-    set(linker_frontend "GNU")
-    set(linker_version "${CMAKE_MATCH_1}")
-  elseif (linker_desc MATCHES "LLD ([0-9.]+)")
-    set(linker_id "LLD")
-    set(linker_frontend "GNU")
-    set(linker_version "${CMAKE_MATCH_1}")
-    if (WIN32 AND NOT linker_desc MATCHES "compatible with GNU")
-      set (linker_frontend "MSVC")
+  foreach(flags IN ITEMS
+      "-v"        # AppleClang, GNU, GNUgold, MOLD
+      "--version" # LLD
+      )
+    execute_process(COMMAND "${linker}" ${flags}
+                    OUTPUT_VARIABLE linker_desc
+                    ERROR_VARIABLE linker_desc
+                    OUTPUT_STRIP_TRAILING_WHITESPACE
+                    ERROR_STRIP_TRAILING_WHITESPACE)
+
+    if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND linker_desc MATCHES "@\\(#\\)PROGRAM:ld.+PROJECT:[a-z0-9]+-([0-9.]+).+")
+      set(linker_id "AppleClang")
+      set(linker_frontend "GNU")
+      set(linker_version "${CMAKE_MATCH_1}")
+      break()
+    elseif(linker_desc MATCHES "mold \\(sold\\) ([0-9.]+)")
+      set(linker_id "MOLD")
+      set(linker_frontend "GNU")
+      set(linker_version "${CMAKE_MATCH_1}")
+      break()
+    elseif(linker_desc MATCHES "mold ([0-9.]+)")
+      set(linker_id "MOLD")
+      set(linker_frontend "GNU")
+      set(linker_version "${CMAKE_MATCH_1}")
+      break()
+    elseif(linker_desc MATCHES "LLD ([0-9.]+)")
+      set(linker_id "LLD")
+      set(linker_frontend "GNU")
+      set(linker_version "${CMAKE_MATCH_1}")
+      if(WIN32 AND NOT linker_desc MATCHES "compatible with GNU")
+        set(linker_frontend "MSVC")
+      endif()
+      break()
+    elseif(linker_desc MATCHES "GNU ld \\([^)]+\\) ([0-9.]+)")
+      set(linker_id "GNU")
+      set(linker_frontend "GNU")
+      set(linker_version "${CMAKE_MATCH_1}")
+      break()
+    elseif(linker_desc MATCHES "GNU gold \\([^)]+\\) ([0-9.]+)")
+      set(linker_id "GNUgold")
+      set(linker_frontend "GNU")
+      set(linker_version "${CMAKE_MATCH_1}")
+      break()
+    elseif(linker_desc MATCHES "Microsoft \\(R\\) Incremental Linker Version ([0-9.]+)")
+      set(linker_id "MSVC")
+      set(linker_frontend "MSVC")
+      set(linker_version "${CMAKE_MATCH_1}")
+      break()
     endif()
-  elseif (linker_desc MATCHES "GNU ld \\([^)]+\\) ([0-9.]+)")
-    set(linker_id "GNU")
-    set(linker_frontend "GNU")
-    set(linker_version "${CMAKE_MATCH_1}")
-  elseif (linker_desc MATCHES "GNU gold \\([^)]+\\) ([0-9.]+)")
-    set(linker_id "GNUgold")
-    set(linker_frontend "GNU")
-    set(linker_version "${CMAKE_MATCH_1}")
-  elseif (linker_desc MATCHES "Microsoft \\(R\\) Incremental Linker Version ([0-9.]+)")
-    set(linker_id "MSVC")
-    set(linker_frontend "MSVC")
-    set(linker_version "${CMAKE_MATCH_1}")
-  else()
+  endforeach()
+  if(NOT linker_id)
     # unknown linker
     set(linker_id "UNKNOWN")
   endif()