1# SPDX-License-Identifier: Apache-2.0
2#
3# Copyright (c) 2025, Nordic Semiconductor ASA
4
5# Template file for optional Zephyr compiler functions.
6#
7# This file will define optional compiler functions for toolchains that are not
8# defining these functions themselves.
9
10# Extract all of the compiler options which don't involve generator
11# expressions. We hope that none of the flags required to compute compiler
12# support library paths depend upon those.
13
14function(compiler_simple_options simple_options_out)
15
16  get_property(flags TARGET zephyr_interface PROPERTY INTERFACE_COMPILE_OPTIONS)
17
18  set(simple_options "")
19
20  foreach(flag ${flags})
21
22    # Include this flag if GENEX_STRIP has no effect,
23    # otherwise skip the whole thing
24
25    string(GENEX_STRIP "${flag}" sflag)
26    if(flag STREQUAL sflag)
27      if(flag MATCHES "^SHELL:[ ]*(.*)")
28        separate_arguments(flag UNIX_COMMAND ${CMAKE_MATCH_1})
29      endif()
30      list(APPEND simple_options ${flag})
31    endif()
32
33  endforeach()
34
35  set(${simple_options_out} "${simple_options}" PARENT_SCOPE)
36endfunction()
37
38if(NOT COMMAND compiler_file_path)
39
40  # Search for filename in default compiler library path using the
41  # --print-file-name option which is common to gcc and clang.  If the
42  # file is not found, filepath_out will be set to an empty string.
43  #
44  # This only works if none of the compiler flags used to compute
45  # the library path involve generator expressions as we cannot
46  # evaluate those in this function.
47  #
48  # Compilers needing a different implementation should provide this
49  # function in their target.cmake file
50
51  function(compiler_file_path filename filepath_out)
52
53    compiler_simple_options(simple_options)
54
55    execute_process(
56      COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} ${COMPILER_OPTIMIZATION_FLAG} ${simple_options}
57      --print-file-name ${filename}
58      OUTPUT_VARIABLE filepath
59      OUTPUT_STRIP_TRAILING_WHITESPACE
60      )
61    if(${filepath} STREQUAL ${filename})
62      set(filepath "")
63    endif()
64    set(${filepath_out} "${filepath}" PARENT_SCOPE)
65  endfunction()
66
67endif()
68
69if(NOT COMMAND compiler_set_linker_properties)
70
71  # Set the lib_include_dir and rt_library linker properties
72  # by searching for the runtime library in the compiler default
73  # library search path. If no runtime library is found, these
74  # properties will remain unset
75  #
76  # Compilers needing a different implementation should provide this
77  # function in their target.cmake file
78
79  function(compiler_set_linker_properties)
80
81    compiler_simple_options(simple_options)
82
83    # Compute complete path to the runtime library using the
84    # --print-libgcc-file-name compiler flag
85    execute_process(
86      COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} ${COMPILER_OPTIMIZATION_FLAG} ${simple_options}
87      --print-libgcc-file-name
88      OUTPUT_VARIABLE library_path
89      OUTPUT_STRIP_TRAILING_WHITESPACE
90      )
91
92    # Compute the library directory name
93
94    get_filename_component(library_dir ${library_path} DIRECTORY)
95    set_linker_property(PROPERTY lib_include_dir "-L${library_dir}")
96
97    # Compute the linker option for this library
98
99    get_filename_component(library_basename ${library_path} NAME_WLE)
100
101    # Remove the leading 'lib' prefix to leave a value suitable for use with
102    # the linker -l flag
103    string(REPLACE lib "" library_name ${library_basename})
104
105    set_linker_property(PROPERTY rt_library "-l${library_name}")
106  endfunction()
107
108endif()
109