1# SPDX-License-Identifier: Apache-2.0
2
3if(NOT SYSROOT_DIR)
4  # When using cross-compile, the generic toolchain will be identical to the
5  # target toolchain, hence let's ask the compiler if it knows its own sysroot.
6  # Some gcc based compilers do have this information built-in.
7  execute_process(COMMAND ${CMAKE_C_COMPILER} --print-sysroot
8                  RESULT_VARIABLE return_val
9                  OUTPUT_VARIABLE reported_sysroot
10                  OUTPUT_STRIP_TRAILING_WHITESPACE
11  )
12  if(NOT return_val AND NOT "${reported_sysroot}" STREQUAL "")
13    set(SYSROOT_DIR "${reported_sysroot}" CACHE INTERNAL "Sysroot reported by ${CMAKE_C_COMPILER}")
14  else()
15    # Let's try to lookup a sysroot.
16    # Compiler is expected to be located in `bin/` so we go one folder up for search.
17    cmake_path(GET CMAKE_C_COMPILER PARENT_PATH search_path)
18    cmake_path(SET search_path NORMALIZE "${search_path}/..")
19    file(GLOB_RECURSE libc_dirs RELATIVE ${search_path} ${search_path}/**/libc.a )
20
21    # Did we find any candidates ?
22    list(LENGTH libc_dirs libc_dirs_length)
23    if(${libc_dirs_length} GREATER 0)
24      list(TRANSFORM libc_dirs REPLACE "libc.a$" "")
25      list(SORT libc_dirs COMPARE NATURAL)
26      list(GET libc_dirs 0 sysroot)
27      set(sysroot_candidates ${sysroot})
28
29      foreach(dir ${libc_dirs})
30        string(FIND "${dir}" "${sysroot}" index)
31        if(${index} EQUAL -1)
32          set(sysroot ${dir})
33          list(APPEND sysroot_candidates ${sysroot})
34        endif()
35      endforeach()
36
37      # We detect the lib folders, the actual sysroot is up one level.
38      list(TRANSFORM sysroot_candidates REPLACE "/lib[/]?$" "")
39
40      list(LENGTH sysroot_candidates sysroot_candidates_length)
41      if(sysroot_candidates_length GREATER 1)
42        list(TRANSFORM sysroot_candidates PREPEND "${search_path}")
43        string(REPLACE ";" "\n" sysroot_candidates_str "${sysroot_candidates}")
44
45        message(WARNING "Multiple sysroot candidates found: ${sysroot_candidates_str}\n"
46                        "Use `-DSYSROOT_DIR=<sysroot-dir>` to select sysroot.\n"
47        )
48      endif()
49
50      # Use first candidate as sysroot.
51      list(GET sysroot_candidates 0 chosen_sysroot)
52      cmake_path(SET SYSROOT_DIR NORMALIZE "${search_path}/${chosen_sysroot}")
53    endif()
54
55    if(SYSROOT_DIR)
56      set(SYSROOT_DIR "${SYSROOT_DIR}" CACHE INTERNAL "Sysroot discovered")
57      message(STATUS "Found sysroot: ${SYSROOT_DIR}")
58    else()
59      message(WARNING "No sysroot found, build may not work.\n"
60                      "Use `-DSYSROOT_DIR=<sysroot-dir>` to specify sysroot to use.\n"
61      )
62    endif()
63  endif()
64endif()
65