Skip to content

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

@ADKaster

Description

@ADKaster

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions