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.
This commit is contained in:
Brad King
2023-12-08 12:28:01 -05:00
parent 1e42a0cf18
commit c1e48a19a5

View File

@@ -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()