1# SPDX-License-Identifier: Apache-2.0
2#
3# Copyright (c) 2022, Nordic Semiconductor ASA
4# Copyright (c) 2023, Intel Corporation
5
6# FindGnuLd module for locating LLVM lld linker.
7#
8# The module defines the following variables:
9#
10# 'LLVMLLD_LINKER'
11# Path to LLVM lld linker
12# Set to 'LLVMLLD_LINKER-NOTFOUND' if ld was not found.
13#
14# 'LlvmLld_FOUND', 'LLVMLLD_FOUND'
15# True if LLVM lld was found.
16#
17# 'LLVMLLD_VERSION_STRING'
18# The version of LLVM lld.
19
20include(FindPackageHandleStandardArgs)
21
22# See if the compiler has a preferred linker
23execute_process(
24  COMMAND ${CMAKE_C_COMPILER} --print-prog-name=ld.lld
25  OUTPUT_VARIABLE LLVMLLD_LINKER
26  OUTPUT_STRIP_TRAILING_WHITESPACE
27)
28
29if(NOT EXISTS "${LLVMLLD_LINKER}")
30  # Need to clear it or else find_program() won't replace the value.
31  set(LLVMLLD_LINKER)
32
33  if(DEFINED TOOLCHAIN_HOME)
34    # Search for linker under TOOLCHAIN_HOME if it is defined
35    # to limit which linker to use, or else we would be using
36    # host tools.
37    set(LLD_SEARCH_PATH PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
38  endif()
39
40  # Note that, although there is lld, it cannot be used directly
41  # as it would complain about it not being a generic linker,
42  # and asks you to use ld.lld instead. So do not search for lld.
43  find_program(LLVMLLD_LINKER ld.lld ${LLD_SEARCH_PATH})
44endif()
45
46if(LLVMLLD_LINKER)
47  # Parse the 'ld.lld --version' output to find the installed version.
48  execute_process(
49    COMMAND ${LLVMLLD_LINKER} --version
50    OUTPUT_VARIABLE llvmlld_version_output
51    ERROR_VARIABLE  llvmlld_error_output
52    RESULT_VARIABLE llvmlld_status
53  )
54
55  set(LLVMLLD_VERSION_STRING)
56  if(${llvmlld_status} EQUAL 0)
57    # Extract GNU ld version. Different distros have their
58    # own version scheme so we need to account for that.
59    # Examples:
60    # - "GNU ld (GNU Binutils for Ubuntu) 2.34"
61    # - "GNU ld (Zephyr SDK 0.15.2) 2.38"
62    # - "GNU ld (Gentoo 2.39 p5) 2.39.0"
63    string(REGEX
64      MATCH "LLD ([0-9]+[.][0-9]+[.]?[0-9]*).*"
65      out_var ${llvmlld_version_output}
66    )
67    set(LLVMLLD_VERSION_STRING ${CMAKE_MATCH_1})
68  endif()
69endif()
70
71find_package_handle_standard_args(LlvmLld
72  REQUIRED_VARS LLVMLLD_LINKER
73  VERSION_VAR LLVMLLD_VERSION_STRING
74)
75