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