swiftwasm / carton

📦 Watcher, bundler, and test runner for your SwiftWasm apps
Apache License 2.0
442 stars 45 forks source link

Document how to export a function #281

Open onedayitwillmake opened 2 years ago

onedayitwillmake commented 2 years ago

From reading the docs, it does not appear possible to pass an extra -Xlinker flag when running carton bundle or carton dev

The SwiftWASM book which encourages users to install and Carton, does not mention it when it describes how to export a function: https://book.swiftwasm.org/examples/exporting-function.html

augustsaintfreytag commented 2 years ago

Jumping in from other implications to this question, I found that even when functions are exported and available at instance.exports[name], the functions can not be called and lead to an “Unreachable executed” error in my case. Executing the same code through wasi.start(…) works fine.

Is adding linker flags (i.e. -Xlinker -export-dynamic) really the only issue on your end?

onedayitwillmake commented 2 years ago

Answering my own above question, and leaving here for posterity I found that setting the linker flags in the Package.swift allowed Carton to pick them up and export them properly. It's also more ergonomic than carrying around the typo prone string of flags.

Example of projects Package.swift

// swift-tools-version:5.3

import PackageDescription

let package = Package(
  name: "my-project",
  platforms: [
    .macOS(.v11)
  ],
  products: [
    .executable(
      name: "MyProjectWASMWeb",
      targets: ["MyProjectWASMWeb"])
  ],
  dependencies: [
    .package(name: "JavaScriptKit", url: "https://github.com/swiftwasm/JavaScriptKit", from: "0.10.1")
  ],
  targets: [ 
    .target(
      name: "MyProjectWASM",
      dependencies: [
        .product(name: "JavaScriptKit", package: "JavaScriptKit")
      ],
      linkerSettings: [
        .unsafeFlags(
          [
            "-Xlinker", "--export=myFunction",
            "-Xlinker", "--export=myOtherFunction",
             // Had to add the `Xlinker` flags below to work around compilation issue
            "-Xlinker", "-licuuc",
            "-Xlinker", "-licui18n",
            "-Xlinker", "-lCoreFoundation",
          ],
          .when(platforms: [.wasi])
        )
      ]
    ),
    .target(
      name: "MyProjectWASMWeb",
      dependencies: [
        "MyProjectWASM",
        .product(name: "JavaScriptKit", package: "JavaScriptKit")
      ]),
    .testTarget(
      name: "MyProjectWASMTests",
      dependencies: ["MyProjectWASM"]),
  ]
)