Skip to content

In C++ interop mode, specifying --static-swift-stdlib causes the build to fail #78003

Open
@omochi

Description

@omochi

Description

In C++ interop mode, when compiling certain code on Linux and specifying --static-swift-stdlib, the build fails.

The error occurs during the linking phase of the executable, reporting that symbols such as std.string.init(_: Swift.String) and Swift.String.init(_: std.string) cannot be found.

These functions are marked with @_alwaysEmitIntoClient, but the issue seems to arise when references to these functions are generated from code with function signature specialization optimizations. These references are not resolved properly during linking.

Below is the code causing the issue. While slightly complex, altering its structure results in different behavior, and the issue disappears.

// CxxCats.hpp
#pragma once

#include <string>
#include <optional>

using string_optional = std::optional<std::string>;

class Cat {
public:
    int foo;
};

std::optional<Cat> Cat_create(const std::string & name, std::optional<std::string> & e);
// Demo.swift
import CxxCats
import CxxStdlib

struct MessageError: Error {
    var description: String
}

func withCxxException<R>(_ body: (inout string_optional) -> R) throws -> R {
    var error = string_optional()

    let result = body(&error)

    if let message = Optional(fromCxx: error) {
        throw MessageError(description: String(message))
    }

    return result
}

func withCxxOptionalOrException<R>(_ body: (inout string_optional) -> some CxxOptional<R>) throws -> R {
    let result = try withCxxException(body)
    return Optional(fromCxx: result)!
}

public class WrapperCat {
    public init() throws {
        self.cat = try withCxxOptionalOrException { (e) in
            Cat_create(std.string("tama"), &e)
        }
    }

    var cat: Cat
}

Building this code results in the following error:

/usr/bin/ld.gold: error: cannot find -lswiftCxx
/usr/bin/ld.gold: error: cannot find -lswiftCxxStdlib
/usr/bin/ld.gold: error: cannot find -lswiftCxx
/usr/bin/ld.gold: error: cannot find -lswiftCxxStdlib
/work/.build/aarch64-unknown-linux-gnu/release/Demo.build/Demo.swift.o:Demo.swift.o:function $s4Demo10WrapperCatCACyKcfc:(.text.$s4Demo10WrapperCatCACyKcfc+0x38): error: undefined reference to '$sSo3stdO7__cxx11O0071basic_stringCCharchar_traitsCCharallocatorCChar_mHGHsqaGJcraCCfsaqChraaV9CxxStdlibE13stringLiteralAFSS_tcfC'
/work/.build/aarch64-unknown-linux-gnu/release/Demo.build/Demo.swift.o:Demo.swift.o:function $s4Demo10WrapperCatCACyKcfc:(.text.$s4Demo10WrapperCatCACyKcfc+0x100): error: undefined reference to '$sSS9CxxStdlibEySSSo3stdO7__cxx11O0071basic_stringCCharchar_traitsCCharallocatorCChar_mHGHsqaGJcraCCfsaqChraaVcfC'

Reproduction

I have created a repository to reproduce the issue.
https://github.com/omochi/swift-bug-cxx-staticstd

You can replicate the problem using the following commands:

git clone https://github.com/omochi/swift-bug-cxx-staticstd
cd swift-bug-cxx-staticstd
docker run -it --rm -v$(pwd):/work -w /work swift:6.0.2 bash
# in container
swift build -c release --static-swift-stdlib -v
...
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Expected behavior

Build completes successfully without errors.

Environment

Swift version 6.0.2 (swift-6.0.2-RELEASE)
Target: aarch64-unknown-linux-gnu

Additional information

By providing the search path with linker options as shown below, the build succeeds.
However, this is likely not the correct solution.

swift build -c release --static-swift-stdlib -v -Xlinker -L/usr/lib/swift/linux

Additionally, this might be a separate issue, but the linker command line includes a large number of repeated -lswiftCxx and -lswiftCxxStdlib flags.

In the provided sample, they appear twice each, but in my real project, they are repeated up to 16 times.

Metadata

Metadata

Assignees

No one assigned

    Labels

    LinuxPlatform: LinuxbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.c++ interopFeature: Interoperability with C++static stdlibtoolchain

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions