swiftlang / swift-package-manager

The Package Manager for the Swift Programming Language
Apache License 2.0
9.7k stars 1.33k forks source link

Cannot cross compile when package contains dylib product #7893

Open rauhul opened 3 weeks ago

rauhul commented 3 weeks ago

Is it reproducible with SwiftPM command-line tools: swift build, swift test, swift package etc?

Description

swift-mmio contains a dynamic library product called SVD2LLDB. When trying to build a project that only uses the MMIO product of swift-mmio for armv7em-apple-none-macho I hit the following assertion:

Basics/Triple+Basics.swift:149: Fatal error: Cannot create dynamic libraries for os "noneOS".

Expected behavior

No response

Actual behavior

No response

Steps to reproduce

No response

Swift Package Manager version/commit hash

No response

Swift & OS version (output of swift --version ; uname -a)

No response

rauhul commented 3 weeks ago

So the current logic triggering this assertion is:

    /// The file extension for dynamic libraries (eg. `.dll`, `.so`, or `.dylib`)
    public var dynamicLibraryExtension: String {
        guard let os = self.os else {
            fatalError("Cannot create dynamic libraries unknown os.")
        }

        switch os {
        case _ where isDarwin():
            return ".dylib"
        case .linux, .openbsd:
            return ".so"
        case .win32:
            return ".dll"
        case .wasi:
            return ".wasm"
        default:
            fatalError("Cannot create dynamic libraries for os \"\(os)\".")
        }
    }

I wonder if this is actually switching on the wrong thing. Should the dylib extension be derived from the object file format?

@compnerd do you have thoughts here or any insight about how this works in cmake land?

dschaefer2 commented 3 weeks ago

Is the issue that we're building the entire swift-mmio package for that triple and not just the required product dependencies?

compnerd commented 3 weeks ago

@rauhul I think that is a totally fair assertion failure. I think that in the default case, we should switch on the file format. i.e. aarch64-unknown-none-elf should use .so even though the OS is none, aarch64-unknown-none-macho should likely use .dylib.

rauhul commented 3 weeks ago

@dschaefer2 I don't think SVD2LLDB is even getting built, the build system is trying to plan the build and failing to determine a file path for where SVD2LLDB dylib would be if it were to be used.

rauhul commented 3 weeks ago

@rauhul I think that is a totally fair assertion failure. I think that in the default case, we should switch on the file format. i.e. aarch64-unknown-none-elf should use .so even though the OS is none, aarch64-unknown-none-macho should likely use .dylib.

Well yeah, I do agree making a dylib for OS none is a bit nonsensical because there's no defined loader for such a platform, but I guess my question is: if you're building for <arch>-unknown-linux-coff what dynamic library extension should you expect?

compnerd commented 3 weeks ago

@rauhul well, I can build a system that has a PE kernel built with MachO object files (this is not a facetious example). The environment could be loading a DLL and have a PE loader even though the target for compilation would be ...-unknown-none-macho.