From c34b67250ca5f18a438a1ddfafa09809dda13dd8 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 19 Jan 2026 20:28:10 +0100 Subject: [PATCH] cmake: use `readelf` to extract soname from shared elf library --- cmake/macros.cmake | 68 ++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/cmake/macros.cmake b/cmake/macros.cmake index 48891979b6..a375649063 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -208,9 +208,14 @@ function(target_get_dynamic_library DEST TARGET) 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. 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 + # 2. if readelf is available, parse the output of `readelf -d` and output the "(SONAME)" line + # 3. Else: + # 1. find all other files in the same folder that symbolic link to it + # 2. sort all these files, and select the 1st item on Linux, and last on macOS set(location_properties IMPORTED_LOCATION) if(CMAKE_BUILD_TYPE) list(APPEND location_properties IMPORTED_LOCATION_${CMAKE_BUILD_TYPE}) @@ -228,33 +233,44 @@ function(target_get_dynamic_library DEST TARGET) get_target_property(library_path "${TARGET}" ${location_property}) message(DEBUG "get_target_property(${TARGET} ${location_property}) -> ${library_path}") if(EXISTS "${library_path}") - 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}") + 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}") 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) + 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}") + 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()