Why does a Package expose the target's names for import instead of product/library name

To clarify, with the Swift Package Manager,

  • “Targets” correspond to what are more generally called “modules”, which are independently importable groups of functionality.* Defining .target(name: "MyTarget", ...) makes something that can be used like import MyTarget. (It does not need to match the directory names or file structure of your product. Specify path or sources to arrange your project differently than the default.)
  • “Products” correspond to the resulting compiled binaries. Defining .library(name: "MyLibrary", ...) would create an actual libMyLibrary.dylib file that can be linked against.† These are also the units that can be selected for the package manager to resolve and build first as a dependency: .target(..., dependencies: ["MyLibrary"])

In the most common case, a package’s libraries and targets will be matched one‐to‐one and likely share their names, but other arrangements are possible.

It is also important to note that not every target needs to be part of a product. They can be kept inaccessible from outside the package.

The way you have it set up you will end up with 4 separate compiled .dylib files, with the contents of each target duplicated in the last one.


In order to accomplish what you want, you will have to use the undocumented attribute @_exported. Your AllLibs would then be a distinct target, which depends on your other three targets and vends them each with @_exported import MyIndividualTarget. Then clients can just reference the AllLibs product and import AllLibs to get access to everything.

See here for a project that does it this way (look at the Package.swift too). That project also provides more fine grained access to each target individually, but you do not have to; you could have a single product containing only the target which has the exports.


* unless there is a main.swift file, turning it into a top‐level executable, which cannot be imported.
† assuming dynamic linking mode.

9 Likes