Having just spent a week trying to resolve some similar problems, I finally solved this issue. I'm using EIgen, Ceres and other open source and in housecpp libraries which have a complex dependency structure.
I used Conan to resolve the all dependencies beforehand and build the libraries using a single package for all my libraries, which should be output in a flat structure, all libs in the same directory.
Each library is wrapped into xcframeworks and placed in a Binaries directory. I had to do some scripting to get headers imported correctly to the xcframeworks that needed them.
I create a swift package that has a binary target, and a published product library for each, so there's no dependency handling in SPM at this point.
Something like:
let package = Package(
name: "CPP-Libraries",
products: [
.library(name: "libceres", targets: [ "libceres" ] ),
...
.library(name: "Eigen", targets: [ "Eigen" ] ),
],
targets: [
.binaryTarget(name: "libceres", path: "Binaries/libceres.xcframework"),
...
.target(
name: "Eigen",
cxxSettings: [
.headerSearchPath("Sources/Eigen/include/Eigen")
]
),
],
cxxLanguageStandard: .cxx17
)
Eigen I found a bit problematic as it was a header only file, and SPM didn't like it as is. It needs it's own target, with headerSearchPath in cxxsettings set, plus adding an Eigen.cpp file which just includes the Eigen Umbrella header, and I provided a module.modulemap file that also specified the umbrella header and exported it all.
Now in seperate higher level packages, which represent the top level bridge code of the libraries/modules I want to use, I add all the original dependencies of the libraries using product(name: "libceres", package: "CPP-Libraries") . the hierarchy doesn't matter