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

Document how to use Swift Packages on Linux #313

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

b521f771d8991e6f1d8e65ae05a8d783

No description provided.

Copy link
Owner

@chinedufn chinedufn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this.

I left some minor feedback around fleshing out the section a bit more.

After that looks good to me and we can land this.

Comment on lines +262 to +270
* this ensures that the flags that are normally passed via swiftc are forwarded during swift-build
* Since the path of the resulting rust library "target/debug" depends on the build type, you can set a global variable like this:
```swift
#if DEBUG
let buildType = "debug"
#else
let buildType = "release"
#endif
```
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this global variable set?

linkerSettings: [
.unsafeFlags([
"generated/SwiftBridgeCore.swift", "generated/proj-rs/proj-rs.swift",
"-import-objc-header", "bridging-header.h", "-Ltarget/debug", "-lcorpus",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change this example so that it supports both debug and release builds

linkerSettings: [
.unsafeFlags([
"generated/SwiftBridgeCore.swift", "generated/proj-rs/proj-rs.swift",
"-import-objc-header", "bridging-header.h", "-Ltarget/debug", "-lcorpus",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's explain what this -lcorpus flag does

* Set up swift-bridge according to the guide (see chapter "swiftc and cargo")
* Link against swift-bridge and your library, like the one below:
```swift
targets: [
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's paste a complete file, unless there are so many lines that it's hard to understand.

This helps the reader better orient themselves towards what they're looking at.

Also, say what this file is. Explicitly say that this is a Package.swift

i.e. "like the Package.swift file below:"

# Usage on Linux
Usage on Linux is a little bit different than on macOS. This guide will help you set up SwiftPM and Cargo. The general workflow is:
* Set up Package.swift so that "cargo build" is called (You can use something like this here: "https://stackoverflow.com/questions/26971240/how-do-i-run-a-terminal-command-in-a-swift-script-e-g-xcodebuild" to invoke cargo during a swift build)
* Set up swift-bridge according to the guide (see chapter "swiftc and cargo")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set up swift-bridge how? What does the user need to do? Everything in the guide? A couple things in the guide? Can be more explicit here.


# Usage on Linux
Usage on Linux is a little bit different than on macOS. This guide will help you set up SwiftPM and Cargo. The general workflow is:
* Set up Package.swift so that "cargo build" is called (You can use something like this here: "https://stackoverflow.com/questions/26971240/how-do-i-run-a-terminal-command-in-a-swift-script-e-g-xcodebuild" to invoke cargo during a swift build)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not depend on external sources.

Users should not need to hop around other links/sites/pages to figure out how this works, unless inlining the information is undesirable for some reason.

Let's instead just inline an example of what you mean here, vs. making the user go find and interpret a stackoverflow page.

@@ -238,3 +233,38 @@ cd SwiftProject
swift run
# You should see "Hello from Rust!" in your terminal.
```

# Usage on Linux
Usage on Linux is a little bit different than on macOS. This guide will help you set up SwiftPM and Cargo. The general workflow is:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's explicitly mention the ways that it is different.

So, up here instead of saying it's "a little bit different" just summarize the main way(s) that it is different.

Then your guide below walks the user through addressing those differences.

@chinedufn chinedufn changed the title Added sample to the book that describes my method on how to use swift-bridge inside a package on linux Document how to use Swift Packages on Linux Jan 30, 2025
@chinedufn chinedufn added the linux-support Supporting using `swift-bridge` for Linux targets label Jan 30, 2025
@colinmarc
Copy link

I just opened an issue about generating a (linux-compatible) SPM package: #315

@colinmarc
Copy link

colinmarc commented Feb 2, 2025

FWIW, I tried this approach for the new testing harness, but I couldn't get it working.

Package.swift:

import PackageDescription

let package = Package(
    name: "IntegrationTests",
    targets: [
        .target(
            name: "Fixtures",
            swiftSettings: [
                .interoperabilityMode(.C),
                .unsafeFlags([
                    "-import-objc-header", "Sources/Fixtures/bridge.h",
                ])
            ],
            linkerSettings: [
                // Link our rust static library...
                .linkedLibrary("rust_fixtures"),
                // And tell the linker where to look for it.
                .unsafeFlags(["-L../target/debug"]),
            ]
        ),
        .testTarget(
            name: "Tests",
            dependencies: ["Fixtures"]
        )
    ]
)

Sample output of swift test -v:

<snip>
/usr/lib/swift/bin/swift-frontend -frontend -c -primary-file /home/colinmarc/dev/swift-bridge/integration-tests/Tests/Primitive.swift -emit-dependencies-path /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/Tests.build/Primitive.d -emit-reference-dependencies-path /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/Tests.build/Primitive.swiftdeps -target x86_64-unknown-linux-gnu -disable-objc-interop -I /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/Modules -color-diagnostics -enable-testing -g -debug-info-format=dwarf -dwarf-version=4 -module-cache-path /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/ModuleCache -swift-version 6 -Onone -D SWIFT_PACKAGE -D DEBUG -empty-abi-descriptor -resource-dir /usr/lib/swift/lib/swift -enable-anonymous-context-mangled-names -file-compilation-dir /home/colinmarc/dev/swift-bridge/integration-tests -Xcc -fPIC -Xcc -g -Xcc -fno-omit-frame-pointer -module-name Tests -package-name integration_tests -plugin-path /usr/lib/swift/lib/swift/host/plugins -plugin-path /usr/lib/swift/local/lib/swift/host/plugins -parse-as-library -o /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/Tests.build/Primitive.swift.o -index-store-path /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/index/store -index-system-modules
/usr/lib/swift/bin/swift-frontend -frontend -emit-module -experimental-skip-non-inlinable-function-bodies-without-types /home/colinmarc/dev/swift-bridge/integration-tests/Tests/Primitive.swift -target x86_64-unknown-linux-gnu -disable-objc-interop -I /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/Modules -color-diagnostics -enable-testing -g -debug-info-format=dwarf -dwarf-version=4 -module-cache-path /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/ModuleCache -swift-version 6 -Onone -D SWIFT_PACKAGE -D DEBUG -empty-abi-descriptor -resource-dir /usr/lib/swift/lib/swift -enable-anonymous-context-mangled-names -file-compilation-dir /home/colinmarc/dev/swift-bridge/integration-tests -Xcc -fPIC -Xcc -g -Xcc -fno-omit-frame-pointer -module-name Tests -package-name integration_tests -plugin-path /usr/lib/swift/lib/swift/host/plugins -plugin-path /usr/lib/swift/local/lib/swift/host/plugins -emit-module-doc-path /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/Modules/Tests.swiftdoc -emit-module-source-info-path /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/Modules/Tests.swiftsourceinfo -emit-dependencies-path /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/Tests.build/Tests.emit-module.d -parse-as-library -o /home/colinmarc/dev/swift-bridge/integration-tests/.build/x86_64-unknown-linux-gnu/debug/Modules/Tests.swiftmodule
error: emit-module command failed with exit code 1 (use -v to see invocation)
/tmp/TemporaryDirectory.EystfI/bridge.pch:3:2: error: expected identifier or '('
   1 | # 1 "<built-in>"

   2 | # 1 "/tmp/TemporaryDirectory.EystfI/bridge.pch"

   3 | ELF>�@@CPCL
                  ��Ќ�+�-��+��/�+��(��C�B)�B(�B(�B(<0F+�)�+��/�B(�B)<DH+�)�+��/�B*�B)�-��,��t��+�B-�B)�B+�,��)�+��"�B+��+�-�3��,��)��+�+��)�+��CD��,��)��+�+��)�+��/�)<LE*�,�-��)�+��/��)��,�-��C���+�B-�B)��(��(�B)��*�B.<8�(��,��,��,��+��/�)<P�(��,�B*��(�B-�B)�-�B)��/�)�B�
     |  `- error: expected identifier or '('
   4 | �@
         ��
   5 | �0
         �

/tmp/TemporaryDirectory.EystfI/bridge.pch:3:2: warning: null character ignored
   1 | # 1 "<built-in>"

   2 | # 1 "/tmp/TemporaryDirectory.EystfI/bridge.pch"

   3 | ELF>�@@CPCL

// Many more similar errors...

/home/colinmarc/dev/swift-bridge/integration-tests/Tests/Primitive.swift:1:8: error: failed to import bridging header '/tmp/TemporaryDirectory.EystfI/bridge.pch'
 1 | import Fixtures
   |        `- error: failed to import bridging header '/tmp/TemporaryDirectory.EystfI/bridge.pch'
 2 | import Testing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
linux-support Supporting using `swift-bridge` for Linux targets
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants