Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake multi-module shared library build does not build with -Wl,-z,defs and -Wl,--no-undefined,--no-allow-shlib-undefined on Linux #440

Open
2 tasks done
ADKaster opened this issue Dec 19, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@ADKaster
Copy link

ADKaster commented Dec 19, 2024

I'm trying to start building my project with all of -z,defs, --no-undefined and --no-allow-shlib-undefined on ELF platforms.

I'm pulling in swift-collections via FetchContent.

libDequeModule.so fails to link with an "undefined symbol: ceil" error when linking with lld from a main-snapshot.

Information

  • Package version: 1.1.2
  • Platform version: Ubuntu 24.04
  • Swift version: Swift version 6.2-dev (LLVM 1b38440e27d7b93, Swift 0a9ab413a091180)
  • Swiftly list output: main-snapshot-2024-12-16 (in use)

Checklist

  • If possible, I've reproduced the issue using the main branch of this package.
  • I've searched for existing GitHub issues.

Steps to Reproduce

Create a directory with the following CMakeLists.txt

CMakeLists.txt

cmake_minimum_required(VERSION 3.31)

project(example LANGUAGES Swift CXX)

macro(add_cxx_compile_options)
  set(args "")
  foreach(arg ${ARGN})
    string(APPEND args ${arg}$<SEMICOLON>)
    add_compile_options("SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xcc ${arg}>")
  endforeach()
  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX,ASM>:${args}>)
endmacro()

set(BUILD_SHARED_LIBS ON)

if (NOT WIN32 AND NOT APPLE)
    # NOTE: Assume ELF
    add_link_options(LINKER:-z,defs)
    add_link_options(LINKER:--no-undefined)
    add_link_options(LINKER:--no-allow-shlib-undefined)
endif()

include(FetchContent)

set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE OPT_IN)
FetchContent_Declare(SwiftCollections
    GIT_REPOSITORY https://github.com/apple/swift-collections.git
    GIT_TAG main
    OVERRIDE_FIND_PACKAGE
)

FetchContent_MakeAvailable(SwiftCollections)

Generate a build:

cmake -Bbuild -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++

Run the build:

ninja -C build

Expected behavior

Successful build of all the swift-collections modules

Actual behavior

andrew@Andrew-Workstation:~/ladybird-org/testing/swift-tests/swift-collections-no-undefined$ cmake -Bbuild -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
-- The Swift compiler identification is Apple 6.2
-- The CXX compiler identification is Clang 17.0.0
-- Check for working Swift compiler: /home/andrew/.local/bin/swiftc
-- Check for working Swift compiler: /home/andrew/.local/bin/swiftc - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /home/andrew/.local/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
Cloning into 'swiftcollections-src'...
Already on 'main'
Your branch is up to date with 'origin/main'.
-- The C compiler identification is Clang 17.0.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /home/andrew/.local/bin/clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done (2.9s)
-- Generating done (0.0s)
-- Build files have been written to: /home/andrew/ladybird-org/testing/swift-tests/swift-collections-no-undefined/build
andrew@Andrew-Workstation:~/ladybird-org/testing/swift-tests/swift-collections-no-undefined$ ninja -C build/
ninja: Entering directory `build/'
[6/16] Building Swift Module 'DequeModule' with 17 sources
/home/andrew/ladybird-org/testing/swift-tests/swift-collections-no-undefined/build/_deps/swiftcollections-src/Sources/DequeModule/Deque+Collection.swift:26:18: warning: stored property '_storage' of 'Sendable'-conforming struct 'Iterator' has non-sendable type 'Deque<Element>._Storage'; this is an error in the Swift 6 language mode
 24 |   public struct Iterator: IteratorProtocol {
 25 |     @usableFromInline
 26 |     internal var _storage: Deque._Storage
    |                  `- warning: stored property '_storage' of 'Sendable'-conforming struct 'Iterator' has non-sendable type 'Deque<Element>._Storage'; this is an error in the Swift 6 language mode
 27 | 
 28 |     @usableFromInline

/home/andrew/ladybird-org/testing/swift-tests/swift-collections-no-undefined/build/_deps/swiftcollections-src/Sources/DequeModule/Deque._Storage.swift:15:10: note: consider making struct '_Storage' conform to the 'Sendable' protocol
 13 |   @frozen
 14 |   @usableFromInline
 15 |   struct _Storage {
    |          `- note: consider making struct '_Storage' conform to the 'Sendable' protocol
 16 |     @usableFromInline
 17 |     internal typealias _Buffer = ManagedBufferPointer<_DequeBufferHeader, Element>
/home/andrew/ladybird-org/testing/swift-tests/swift-collections-no-undefined/build/_deps/swiftcollections-src/Sources/DequeModule/Deque+Collection.swift:26:18: warning: stored property '_storage' of 'Sendable'-conforming struct 'Iterator' has non-sendable type 'Deque<Element>._Storage'; this is an error in the Swift 6 language mode
 24 |   public struct Iterator: IteratorProtocol {
 25 |     @usableFromInline
 26 |     internal var _storage: Deque._Storage
    |                  `- warning: stored property '_storage' of 'Sendable'-conforming struct 'Iterator' has non-sendable type 'Deque<Element>._Storage'; this is an error in the Swift 6 language mode
 27 | 
 28 |     @usableFromInline

/home/andrew/ladybird-org/testing/swift-tests/swift-collections-no-undefined/build/_deps/swiftcollections-src/Sources/DequeModule/Deque._Storage.swift:15:10: note: consider making struct '_Storage' conform to the 'Sendable' protocol
 13 |   @frozen
 14 |   @usableFromInline
 15 |   struct _Storage {
    |          `- note: consider making struct '_Storage' conform to the 'Sendable' protocol
 16 |     @usableFromInline
 17 |     internal typealias _Buffer = ManagedBufferPointer<_DequeBufferHeader, Element>
[8/16] Linking Swift shared library lib/libDequeModule.so
FAILED: lib/libDequeModule.so 
: && /home/andrew/.local/bin/swiftc -j 32 -num-threads 32 -emit-library   -Xlinker -z -Xlinker defs -Xlinker --no-undefined -Xlinker --no-allow-shlib-undefined  -Xlinker -soname -Xlinker libDequeModule.so -o lib/libDequeModule.so _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque+Codable.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque+Collection.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque+CustomReflectable.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque+Descriptions.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque+Equatable.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque+ExpressibleByArrayLiteral.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque+Extras.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque+Hashable.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque+Sendable.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque+Testing.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque._Storage.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque._UnsafeHandle.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/_DequeBuffer.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/_DequeBufferHeader.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/_DequeSlot.swift.o _deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/_UnsafeWrappedBuffer.swift.o -L /home/andrew/ladybird-org/testing/swift-tests/swift-collections-no-undefined/build/lib -Xlinker -rpath -Xlinker /home/andrew/ladybird-org/testing/swift-tests/swift-collections-no-undefined/build/lib:  lib/libInternalCollectionsUtilities.so && :
error: link command failed with exit code 1 (use -v to see invocation)
_deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque._Storage.swift.o:Deque._Storage.swift.o:function $s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF:(.text.$s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF+0x208): error: undefined reference to 'round'
_deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque._Storage.swift.o:Deque._Storage.swift.o:function $s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF:(.text.$s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF+0x21f): error: undefined reference to 'rint'
_deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque._Storage.swift.o:Deque._Storage.swift.o:function $s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF:(.text.$s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF+0x233): error: undefined reference to 'trunc'
_deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque._Storage.swift.o:Deque._Storage.swift.o:function $s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF:(.text.$s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF+0x261): error: undefined reference to 'ceil'
_deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque._Storage.swift.o:Deque._Storage.swift.o:function $s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF:(.text.$s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF+0x275): error: undefined reference to 'floor'
_deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque._Storage.swift.o:Deque._Storage.swift.o:function $s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF:(.text.$s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF+0x2e3): error: undefined reference to 'ceil'
_deps/swiftcollections-build/Sources/DequeModule/CMakeFiles/DequeModule.dir/Deque._Storage.swift.o:Deque._Storage.swift.o:function $s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF:(.text.$s11DequeModule0A0V8_StorageV13_growCapacity2to8linearlyS2i_SbtF+0x2f7): error: undefined reference to 'floor'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
[11/16] Building Swift Module 'HashTreeCollections' with 85 sources
ninja: build stopped: subcommand failed.

Failed link due to missing libm symbols. Adding a link_libraries(m) before FetchContent_MakeAvailable fixes the issue.

@ADKaster ADKaster added the bug Something isn't working label Dec 19, 2024
@ADKaster
Copy link
Author

If a BUILD_SHARED_LIBS=ON config on linux is not supported, then this can be worked around by explicitly setting it to off for SwiftCollections like so:

set(BUILD_SHARED_LIBS_SAVE ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS OFF)

FetchContent_MakeAvailable(SwiftCollections)

set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_SAVE})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant