This commit is contained in:
Anonymous Maarten 2026-06-05 11:24:34 +08:00 committed by GitHub
commit 78c4eeafa6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 120 additions and 94 deletions

View file

@ -101,13 +101,13 @@ function(SDL_detect_linker)
endfunction()
function(read_absolute_symlink DEST PATH)
file(READ_SYMLINK "${PATH}" p)
if(NOT IS_ABSOLUTE "${p}")
file(READ_SYMLINK "${PATH}" target)
if(NOT IS_ABSOLUTE "${target}")
get_filename_component(pdir "${PATH}" DIRECTORY)
set(p "${pdir}/${p}")
set(target "${pdir}/${target}")
endif()
get_filename_component(p "${p}" ABSOLUTE)
set("${DEST}" "${p}" PARENT_SCOPE)
get_filename_component(target "${target}" ABSOLUTE)
set("${DEST}" "${target}" PARENT_SCOPE)
endfunction()
function(win32_implib_identify_dll DEST IMPLIB)
@ -181,8 +181,89 @@ function(get_actual_target)
set("${dst}" "${target}" PARENT_SCOPE)
endfunction()
function(elf_read_soname SONAME LIBRARY)
# Parse SONAME from library using `readelf`
set(result "${SONAME}-NOTFOUND")
if(EXISTS "${LIBRARY}")
find_program(READELF_BIN NAMES readelf)
if(READELF_BIN)
execute_process(COMMAND "${READELF_BIN}" -d "${LIBRARY}" RESULTS_VARIABLE readelf_result OUTPUT_VARIABLE readelf_output)
if(readelf_result EQUAL 0 AND readelf_output)
string(REGEX MATCH "\\(SONAME\\).*\\[([0-9A-Za-z_.-]+)\\]" soname "${readelf_output}")
if(soname)
set(result "${CMAKE_MATCH_1}")
endif()
endif()
endif()
endif()
message(DEBUG "elf_read_soname(\"${LIBRARY}\") -> ${SONAME}")
set("${SONAME}" "${result}" PARENT_SCOPE)
endfunction()
function(library_soname_from_symlink SONAME LIBRARY)
# 1. Find the target library a file might be symbolic linking to
# 2. find all other files in the same folder that symbolic link to it
# 3. sort all these files, and select the 1st item on Linux, and last on macOS
set(result "${SONAME}-NOTFOUND")
if(EXISTS "${LIBRARY}")
get_filename_component(abs_library "${LIBRARY}" ABSOLUTE)
while(IS_SYMLINK "${abs_library}")
read_absolute_symlink(abs_library "${abs_library}")
endwhile()
if(APPLE)
set(valid_shared_library_regex "\\.[0-9]+\\.dylib$")
else()
set(valid_shared_library_regex "\\.so\\.([0-9.]+)?[0-9]$")
endif()
get_filename_component(libdir "${abs_library}" DIRECTORY)
file(GLOB subfiles "${libdir}/*")
set(similar_files "${abs_library}")
foreach(subfile ${subfiles})
if(IS_SYMLINK "${subfile}")
read_absolute_symlink(subfile_target "${subfile}")
while(IS_SYMLINK "${subfile_target}")
read_absolute_symlink(subfile_target "${subfile_target}")
endwhile()
get_filename_component(subfile_target "${subfile_target}" ABSOLUTE)
if(subfile_target STREQUAL abs_library AND subfile MATCHES "${valid_shared_library_regex}")
list(APPEND similar_files "${subfile}")
endif()
endif()
endforeach()
list(SORT similar_files)
if(APPLE)
list(REVERSE similar_files)
endif()
message(DEBUG "files that are similar to \"${abs_library}\": ${similar_files}")
list(GET similar_files 0 item)
get_filename_component(result "${item}" NAME)
endif()
message(DEBUG "library_soname_from_symlink(${LIBRARY}) -> ${result}")
set(${SONAME} "${result}" PARENT_SCOPE)
endfunction()
function(library_soname_from_path DEST LIBRARY)
set(result "${DEST}-NOTFOUND")
if(WIN32)
win32_implib_identify_dll(result "${LIBRARY}")
else()
# 1. On elf platforms, if readelf is available, parse the output of `readelf -d` and return the "(SONAME)" line
# 2. Else:
# 1. Find the target library a file might be symbolic linking to
# 2. find all other files in the same folder that symbolic link to it
# 3. sort all these files, and select the 1st item on Linux, and last on macOS
if(UNIX AND NOT APPLE)
elf_read_soname(result "${LIBRARY}")
endif()
if(NOT result)
library_soname_from_symlink(result "${LIBRARY}")
endif()
endif()
set("${DEST}" "${result}" PARENT_SCOPE)
endfunction()
function(target_get_dynamic_library DEST TARGET)
set(result)
set(result "${DEST}-NOTFOUND")
get_actual_target(TARGET)
if(WIN32)
# Use the target dll of the import library
@ -200,17 +281,13 @@ function(target_get_dynamic_library DEST TARGET)
endforeach()
foreach(prop_to_check ${props_to_check})
if(NOT result)
get_target_property(propvalue "${TARGET}" ${prop_to_check})
if(propvalue AND EXISTS "${propvalue}")
win32_implib_identify_dll(result "${propvalue}" NOTFATAL)
endif()
if(result)
break()
endif()
endforeach()
else()
if(UNIX AND NOT APPLE)
find_program(READELF_BIN NAMES readelf)
endif()
# 1. find the target library a file might be symbolic linking to
# 2. if readelf is available, parse the output of `readelf -d` and output the "(SONAME)" line
# 3. Else:
@ -223,57 +300,29 @@ function(target_get_dynamic_library DEST TARGET)
foreach (config_type ${CMAKE_CONFIGURATION_TYPES} RELEASE DEBUG RELWITHDEBINFO MINSIZEREL)
list(APPEND location_properties IMPORTED_LOCATION_${config_type})
endforeach()
if(APPLE)
set(valid_shared_library_regex "\\.[0-9]+\\.dylib$")
else()
set(valid_shared_library_regex "\\.so\\.([0-9.]+)?[0-9]")
endif()
if(UNIX AND NOT APPLE)
foreach(location_property ${location_properties})
if(NOT result)
get_target_property(library_path "${TARGET}" ${location_property})
message(DEBUG "get_target_property(${TARGET} ${location_property}) -> ${library_path}")
if(EXISTS "${library_path}")
if(READELF_BIN)
execute_process(COMMAND "${READELF_BIN}" -d "${library_path}" RESULTS_VARIABLE readelf_result OUTPUT_VARIABLE readelf_output)
if(readelf_output)
string(REGEX MATCH "\\(SONAME\\).*\\[([0-9A-Za-z_.-]+)\\]" soname "${readelf_output}")
if(soname)
set(result "${CMAKE_MATCH_1}")
if(library_path AND EXISTS "${library_path}")
elf_read_soname(result "${library_path}")
if(result)
break()
endif()
endif()
endforeach()
endif()
if(NOT result)
get_filename_component(library_path "${library_path}" ABSOLUTE)
while (IS_SYMLINK "${library_path}")
read_absolute_symlink(library_path "${library_path}")
endwhile()
message(DEBUG "${TARGET} -> ${library_path}")
get_filename_component(libdir "${library_path}" DIRECTORY)
file(GLOB subfiles "${libdir}/*")
set(similar_files "${library_path}")
foreach(subfile ${subfiles})
if(IS_SYMLINK "${subfile}")
read_absolute_symlink(subfile_target "${subfile}")
while(IS_SYMLINK "${subfile_target}")
read_absolute_symlink(subfile_target "${subfile_target}")
endwhile()
get_filename_component(subfile_target "${subfile_target}" ABSOLUTE)
if(subfile_target STREQUAL library_path AND subfile MATCHES "${valid_shared_library_regex}")
list(APPEND similar_files "${subfile}")
foreach(location_property ${location_properties})
get_target_property(library_path "${TARGET}" ${location_property})
if(library_path AND EXISTS "${library_path}")
library_soname_from_symlink(result "${library_path}")
message(DEBUG "result=${result}")
if(result)
break()
endif()
endif()
endforeach()
list(SORT similar_files)
message(DEBUG "files that are similar to \"${library_path}\"=${similar_files}")
if(APPLE)
list(REVERSE similar_files)
endif()
list(GET similar_files 0 item)
get_filename_component(result "${item}" NAME)
endif()
endif()
endif()
endforeach()
endif()
if(result)
string(TOLOWER "${result}" result_lower)

View file

@ -5,7 +5,7 @@ macro(check_c_source_compiles_static SOURCE VAR)
set(CMAKE_TRY_COMPILE_TARGET_TYPE "${saved_CMAKE_TRY_COMPILE_TARGET_TYPE}")
endmacro()
macro(FindLibraryAndSONAME _LIB)
function(FindLibraryAndSONAME _LIB)
cmake_parse_arguments(_FLAS "" "" "LIBDIRS" ${ARGN})
string(TOUPPER ${_LIB} _UPPERLNAME)
@ -15,39 +15,18 @@ macro(FindLibraryAndSONAME _LIB)
# FIXME: fail FindLibraryAndSONAME when library is not shared.
if(${_LNAME}_LIB MATCHES ".*\\${CMAKE_SHARED_LIBRARY_SUFFIX}.*" AND NOT ${_LNAME}_LIB MATCHES ".*\\${CMAKE_STATIC_LIBRARY_SUFFIX}.*")
set(${_LNAME}_SHARED TRUE)
set(${_LNAME}_SHARED TRUE PARENT_SCOPE)
library_soname_from_path(soname "${${_LNAME}_LIB}")
else()
set(${_LNAME}_SHARED FALSE)
endif()
if(${_LNAME}_LIB)
# reduce the library name for shared linking
get_filename_component(_LIB_REALPATH ${${_LNAME}_LIB} REALPATH) # resolves symlinks
get_filename_component(_LIB_LIBDIR ${_LIB_REALPATH} DIRECTORY)
get_filename_component(_LIB_JUSTNAME ${_LIB_REALPATH} NAME)
if(APPLE)
string(REGEX REPLACE "(\\.[0-9]*)\\.[0-9\\.]*dylib$" "\\1.dylib" _LIB_REGEXD "${_LIB_JUSTNAME}")
else()
string(REGEX REPLACE "(\\.[0-9]*)\\.[0-9\\.]*$" "\\1" _LIB_REGEXD "${_LIB_JUSTNAME}")
endif()
if(NOT EXISTS "${_LIB_LIBDIR}/${_LIB_REGEXD}")
set(_LIB_REGEXD "${_LIB_JUSTNAME}")
endif()
set(${_LNAME}_LIBDIR "${_LIB_LIBDIR}")
message(STATUS "dynamic lib${_LIB} -> ${_LIB_REGEXD}")
set(${_LNAME}_LIB_SONAME ${_LIB_REGEXD})
set(${_LNAME}_SHARED FALSE PARENT_SCOPE)
set(soname "${_LNAME}_LIB_SONAME-NOTFOUND" PARENT_SCOPE)
endif()
set(${_LNAME}_LIB_SONAME "${soname}" PARENT_SCOPE)
message(DEBUG "DYNLIB soname: ${soname}")
message(DEBUG "DYNLIB OUTPUTVAR: ${_LIB} ... ${_LNAME}_LIB")
message(DEBUG "DYNLIB ORIGINAL LIB: ${_LIB} ... ${${_LNAME}_LIB}")
message(DEBUG "DYNLIB REALPATH LIB: ${_LIB} ... ${_LIB_REALPATH}")
message(DEBUG "DYNLIB JUSTNAME LIB: ${_LIB} ... ${_LIB_JUSTNAME}")
message(DEBUG "DYNLIB SONAME LIB: ${_LIB} ... ${_LIB_REGEXD}")
endmacro()
message(DEBUG "DYNLIB SONAME LIB: ${_LIB} ... $soname}")
endfunction()
macro(CheckDLOPEN)
check_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN_IN_LIBC)
@ -121,8 +100,6 @@ macro(CheckALSA)
endif()
endif()
if(NOT HAVE_ALSA_SHARED)
#FIXME: remove this line and property generate sdl3.pc
list(APPEND SDL_PC_PRIVATE_REQUIRES alsa)
sdl_link_dependency(alsa LIBS ALSA::ALSA CMAKE_MODULE ALSA PKG_CONFIG_SPECS "${ALSA_PKG_CONFIG_SPEC}")
endif()
set(HAVE_SDL_AUDIO TRUE)