Swift Package Manager with multiple executables and shared directory

I have two main.swift files in two different directories. I want to have two executables for each.
There's are classes shared by two main files and they are all organized in sharedFolder.

Below is my project structure:

Source
|_dir1
    |_ main.swift
    |_...
|_dir2
   |_ main.swift
   |_...
|_sharedFolder
  |_ClassA.swift
  |_ClassB.swift

I tried something like this and failed to make it work...

    products: [
        .executable(
            name: "dir1",
            targets: ["dir1"]),
        .executable(
            name: "dir2",
            targets: ["dir2"])
    ],
    ...
    targets: [
        .target(
            name: "dir1", 
            dependencies: ["sharedFolder"]
        ),
        .target(
            name: "dir2",
            dependencies: ["sharedFolder"]
        )
    ]

is something like this possible?

Is this what you are looking for?

products: [
  .executable(
    name: "dir1",
    targets: ["dir1"]),
  .executable(
    name: "dir2",
    targets: ["dir2"])
],
/* ... */
targets: [
  .target(
    name: "dir1", 
    dependencies: ["sharedFolder"]
  ),
  .target(
    name: "dir2",
    dependencies: ["sharedFolder"]
  )
  // ↓ This is what defines the library.
  .target(
    name: "sharedFolder"
  )
]
2 Likes

May I ask how to share resource file? like libsome.dylib or table.json.
I tried place .copy(../../file) into resources: to copy file in root directory, but it not work.
For multiple targets would copy same file, I have to copy file to each target directory.

I would make a resources library, whose only source file exposes public methods to access whatever the resources are. The other targets add that library as a dependency, and request the resources using its public interface.

P.S. .dylib does not sound like a resource. Do you want a binary target?

You don't share the resource files directly. Instead, you declare public methods in the target that contains the resource files that expose the resources.

Declare the resources as part of the sharedFolder target:

// ↓ This is what defines the library.
.target(
  name: "sharedFolder",
  resources: [
    .process("Resources") 
  ]
)

(The rest of the file is the same as what @SDGGiesbrecht posted.)

You should then put all of your resource files inside the folder Sources/sharedFolder/Resources. Next, add a file to the sharedFolder target with public methods that expose all of the resources.

It works! :grinning:

In additional, compiler guide me did these:

  • mkdir Sources/sharedFolder
  • make new swift file in it but do nothing.

I packaged some C functions into the dylib on macOS and so on linux, since I cannot found a way to make xcframework (using in binaryTarget) contains these C functions and working on linux.
So I copy the dylib and so as resources, and use dlopen and dlsym then call them.

xcframework only supports apple platforms.