[lld] [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:40:50 PST 2025
https://github.com/partaror created https://github.com/llvm/llvm-project/pull/124588
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.
>From 910509c9b787c3f96937e2b220b5aec9a062c5ec Mon Sep 17 00:00:00 2001
From: Parth Arora <quic_partaror at quicinc.com>
Date: Thu, 2 Jan 2025 09:32:23 -0800
Subject: [PATCH 1/2] [LLD] [ELF] Add support for linker script unary plus
operator
This commit adds support for linker script unary plus ('+') operator.
It is helpful for improving compatibility between LLD and GNU LD.
Closes #118047
---
lld/ELF/ScriptParser.cpp | 2 ++
lld/test/ELF/linkerscript/diag.test | 4 ++--
lld/test/ELF/linkerscript/operators.test | 4 ++++
3 files changed, 8 insertions(+), 2 deletions(-)
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
>From 6daa3d78aefebecd9854fc6a211e42bced05ebb5 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 2/2] 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