[llvm] Add `NO_VERSIONING` feature in `add_llvm_library` (PR #124588)
Parth Arora via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 27 08:42:00 PST 2025
https://github.com/partaror updated https://github.com/llvm/llvm-project/pull/124588
>From 7a1d439b5529c125e852235c977c0107c86f315a Mon Sep 17 00:00:00 2001
From: Parth Arora <quic_partaror at quicinc.com>
Date: Mon, 27 Jan 2025 08:33:21 -0800
Subject: [PATCH] Add NO_VERSIONING feature in add_llvm_library
This commit adds NO_VERSIONING feature in add_llvm_library. With
NO_VERSIONING, symbols are exported without versioning when creating a
shared library using add_llvm_library with LLVM_EXPORTED_SYMBOL_FILE.
This makes add_llvm_library functionality more flexible.
We need this functionality to optimally maintain one of our downstream LLVM
tool.
---
llvm/cmake/modules/AddLLVM.cmake | 19 ++++--
.../modules/AddNoVersionSymbolExports.cmake | 63 +++++++++++++++++++
2 files changed, 76 insertions(+), 6 deletions(-)
create mode 100644 llvm/cmake/modules/AddNoVersionSymbolExports.cmake
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index d3e9377c8d2f7e..a6be908dfa46ab 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -3,17 +3,18 @@ include(LLVMDistributionSupport)
include(LLVMProcessSources)
include(LLVM-Config)
include(DetermineGCCCompatible)
+include(AddNoVersionSymbolExports)
# get_subproject_title(titlevar)
# Set ${outvar} to the title of the current LLVM subproject (Clang, MLIR ...)
-#
+#
# The title is set in the subproject's top-level using the variable
# LLVM_SUBPROJECT_TITLE. If it does not exist, it is assumed it is LLVM itself.
# The title is not semantically significant, but use to create folders in
# CMake-generated IDE projects (Visual Studio/XCode).
function(get_subproject_title outvar)
if (LLVM_SUBPROJECT_TITLE)
- set(${outvar} "${LLVM_SUBPROJECT_TITLE}" PARENT_SCOPE)
+ set(${outvar} "${LLVM_SUBPROJECT_TITLE}" PARENT_SCOPE)
else ()
set(${outvar} "LLVM" PARENT_SCOPE)
endif ()
@@ -520,10 +521,12 @@ endfunction(set_windows_version_resource_properties)
# This is used to specify that this is a component library of
# LLVM which means that the source resides in llvm/lib/ and it is a
# candidate for inclusion into libLLVM.so.
+# NO_VERSIONING
+# This is used to remove symbol versioning info while exporting symbols for a shared object.
# )
function(llvm_add_library name)
cmake_parse_arguments(ARG
- "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB"
+ "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;NO_VERSIONING;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB"
"OUTPUT_NAME;PLUGIN_TOOL;ENTITLEMENTS;BUNDLE_PATH"
"ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
${ARGN})
@@ -645,11 +648,11 @@ function(llvm_add_library name)
endif()
set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Libraries")
- ## If were compiling with clang-cl use /Zc:dllexportInlines- to exclude inline
+ ## If were compiling with clang-cl use /Zc:dllexportInlines- to exclude inline
## class members from being dllexport'ed to reduce compile time.
## This will also keep us below the 64k exported symbol limit
## https://blog.llvm.org/2018/11/30-faster-windows-builds-with-clang-cl_14.html
- if(LLVM_BUILD_LLVM_DYLIB AND NOT LLVM_DYLIB_EXPORT_INLINES AND
+ if(LLVM_BUILD_LLVM_DYLIB AND NOT LLVM_DYLIB_EXPORT_INLINES AND
MSVC AND CMAKE_CXX_COMPILER_ID MATCHES Clang)
target_compile_options(${name} PUBLIC /Zc:dllexportInlines-)
if(TARGET ${obj_name})
@@ -737,7 +740,11 @@ function(llvm_add_library name)
set_target_properties( ${name} PROPERTIES DEFINE_SYMBOL "" )
if (LLVM_EXPORTED_SYMBOL_FILE)
- add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
+ if(ARG_NO_VERSIONING AND LLVM_ON_UNIX)
+ add_no_version_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
+ else(ARG_NO_VERSIONING AND LLVM_ON_UNIX)
+ add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
+ endif(ARG_NO_VERSIONING AND LLVM_ON_UNIX)
endif()
endif()
diff --git a/llvm/cmake/modules/AddNoVersionSymbolExports.cmake b/llvm/cmake/modules/AddNoVersionSymbolExports.cmake
new file mode 100644
index 00000000000000..b0b1185e654bf6
--- /dev/null
+++ b/llvm/cmake/modules/AddNoVersionSymbolExports.cmake
@@ -0,0 +1,63 @@
+# Handy function to export symbols without versioning
+function(add_symbol_exports target_name export_file)
+ if(LLVM_HAVE_LINK_VERSION_SCRIPT)
+ # Gold and BFD ld require a version script rather than a plain list.
+ set(native_export_file "${target_name}.exports")
+ add_custom_command(
+ OUTPUT ${native_export_file}
+ COMMAND echo "{" > ${native_export_file}
+ COMMAND grep -q "[[:alnum:]]" ${export_file} && echo " global:" >>
+ ${native_export_file} || :
+ COMMAND sed -e "s/$/;/" -e "s/^/ /" < ${export_file} >>
+ ${native_export_file}
+ COMMAND echo " local: *;" >> ${native_export_file}
+ COMMAND echo "};" >> ${native_export_file}
+ DEPENDS ${export_file}
+ VERBATIM
+ COMMENT "Creating export file for ${target_name}")
+ set_property(
+ TARGET ${target_name}
+ APPEND_STRING
+ PROPERTY
+ LINK_FLAGS
+ " -Wl,--version-script,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\""
+ )
+ endif()
+
+ add_custom_target(${target_name}_exports DEPENDS ${native_export_file})
+ set_target_properties(${target_name}_exports PROPERTIES FOLDER "Misc")
+
+ get_property(
+ srcs
+ TARGET ${target_name}
+ PROPERTY SOURCES)
+ foreach(src ${srcs})
+ get_filename_component(extension ${src} EXT)
+ if(extension STREQUAL ".cpp")
+ set(first_source_file ${src})
+ break()
+ endif()
+ endforeach()
+
+ # Force re-linking when the exports file changes. Actually, it forces
+ # recompilation of the source file. The LINK_DEPENDS target property only
+ # works for makefile-based generators. FIXME: This is not safe because this
+ # will create the same target ${native_export_file} in several different file:
+ # - One where we emitted ${target_name}_exports - One where we emitted the
+ # build command for the following object. set_property(SOURCE
+ # ${first_source_file} APPEND PROPERTY OBJECT_DEPENDS
+ # ${CMAKE_CURRENT_BINARY_DIR}/${native_export_file})
+
+ set_property(
+ DIRECTORY
+ APPEND
+ PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${native_export_file})
+
+ add_dependencies(${target_name} ${target_name}_exports)
+
+ # Add dependency to *_exports later -- CMake issue 14747
+ list(APPEND LLVM_COMMON_DEPENDS ${target_name}_exports)
+ set(LLVM_COMMON_DEPENDS
+ ${LLVM_COMMON_DEPENDS}
+ PARENT_SCOPE)
+endfunction(add_symbol_exports)
More information about the llvm-commits
mailing list