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 likeimport MyTarget
. (It does not need to match the directory names or file structure of your product. Specifypath
orsources
to arrange your project differently than the default.) - “Products” correspond to the resulting compiled binaries. Defining
.library(name: "MyLibrary", ...)
would create an actuallibMyLibrary.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.