[lld] [llvm] Add `NO_VERSIONING` feature in `add_llvm_library` (PR #124588)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 27 08:41:28 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-elf
@llvm/pr-subscribers-lld
Author: Parth Arora (partaror)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/124588.diff
5 Files Affected:
- (modified) lld/ELF/ScriptParser.cpp (+2)
- (modified) lld/test/ELF/linkerscript/diag.test (+2-2)
- (modified) lld/test/ELF/linkerscript/operators.test (+4)
- (modified) llvm/cmake/modules/AddLLVM.cmake (+13-6)
- (added) llvm/cmake/modules/AddNoVersionSymbolExports.cmake (+63)
``````````diff
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index f53515cc3f3c0d..06a22613ee93ac 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -1489,6 +1489,8 @@ Expr ScriptParser::readPrimary() {
Expr e = readPrimary();
return [=] { return -e().getValue(); };
}
+ if (consume("+"))
+ return readPrimary();
StringRef tok = next();
std::string location = getCurrentLocation();
diff --git a/lld/test/ELF/linkerscript/diag.test b/lld/test/ELF/linkerscript/diag.test
index fbc24659a53114..114f5c2c0820b7 100644
--- a/lld/test/ELF/linkerscript/diag.test
+++ b/lld/test/ELF/linkerscript/diag.test
@@ -12,9 +12,9 @@ SECTIONS {
}
# RUN: not ld.lld -shared 0.o -T 1.lds 2>&1 | FileCheck %s --check-prefix=CHECK1 --match-full-lines --strict-whitespace
-# CHECK1:{{.*}}:2: malformed number: +
+# CHECK1:{{.*}}:2: malformed number: {
# CHECK1-NEXT:>>> .text + { *(.text) }
-# CHECK1-NEXT:>>> ^
+# CHECK1-NEXT:>>> ^
#--- 2.lds
diff --git a/lld/test/ELF/linkerscript/operators.test b/lld/test/ELF/linkerscript/operators.test
index 27209a2e40f598..f84f23fd4d469d 100644
--- a/lld/test/ELF/linkerscript/operators.test
+++ b/lld/test/ELF/linkerscript/operators.test
@@ -73,6 +73,8 @@ SECTIONS {
log2ceil100000000 = LOG2CEIL(0x100000000);
log2ceil100000001 = LOG2CEIL(0x100000001);
log2ceilmax = LOG2CEIL(0xffffffffffffffff);
+ unaryadd = +3 + ++5;
+ unaryadd_and_unaryminus = 15 + +-5 + -+7;
}
# CHECK: 0000000000000002 A unary
@@ -126,6 +128,8 @@ SECTIONS {
# CHECK-NEXT: 0000000000000020 A log2ceil100000000
# CHECK-NEXT: 0000000000000021 A log2ceil100000001
# CHECK-NEXT: 0000000000000040 A log2ceilmax
+# CHECK-NEXT: 0000000000000008 A unaryadd
+# CHECK-NEXT: 0000000000000003 A unaryadd_and_unaryminus
## Mailformed number error.
# RUN: echo "SECTIONS { . = 0x12Q41; }" > %t.script
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)
``````````
</details>
https://github.com/llvm/llvm-project/pull/124588
More information about the llvm-commits
mailing list