SPM Using Prebuilt Libraries

Hello All,
I have a project that has several third-party packages that I do not have to source to. I know SPM prefers having the source distribution, but I don't have that option. Some of these are delivered as Frameworks, some are a bunch of header files and a static library. From what I read about SPM, it has System Modules which let you link in system libraries, but I am unsure if that will work with these third party code libraries.

So I have three questions.

  • Should SPM find the frameworks if they are in the Source folder for the project? It seems that I must pass in the frameworks path to the build command to get them to link.
  • How do define my own wrapper for the loose library? I don't think a system module will work because it must specify a fixed path in the module definition file. Is that correct?
  • Other modules I do have the source but it is in Objective-C. I am confused about how I tell SPM to build a Framework, and which files are the ones that should be exposed outside the module.

Thank you!

1 Like

Just to follow up on the last question, I created a simple Obj-C package with DeviceUtil. I use SPM to generate the Xcode project and change the IPHONEOS_DEPLOYMENT_TARGET=9.3, SDKROOT="iphoneos" then build.

.
├── DeviceUtil.xcodeproj
│ ├── DeviceUtilTests_Info.plist
│ ├── DeviceUtil_Info.plist
│ ├── GeneratedModuleMap
│ │ └── DeviceUtil
│ │ └── module.modulemap
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ └── possenb.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ ├── xcshareddata
│ │ └── xcschemes
│ │ ├── DeviceUtil-Package.xcscheme
│ │ └── xcschememanagement.plist
│ └── xcuserdata
│ └── possenb.xcuserdatad
│ └── xcschemes
│ └── xcschememanagement.plist
├── LICENSE.txt
├── Package.resolved
├── Package.swift
├── README.md
├── Rakefile
├── Sources
│ └── DeviceUtil
│ ├── DeviceList.plist
│ ├── DeviceUtil.m
│ └── include
│ └── DeviceUtil.h
└── Tests
└── DeviceUtilTests
└── DeviceUtilTests.swift

16 directories, 18 files

my Package.swift is this:

➜ DeviceUtil git:(SwiftPM) ✗ more Package.swift
// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "DeviceUtil",
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "DeviceUtil",
targets: ["DeviceUtil"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "DeviceUtil",
dependencies: ),
publicHeadersPath: "DeviceUtil/include"),
.testTarget(
name: "DeviceUtilTests",
dependencies: ["DeviceUtil"]),
]
)

I get a framework with the following:

.
├── DeviceUtil.framework
│ ├── DeviceUtil
│ ├── Info.plist
│ └── _CodeSignature
│ └── CodeResources
├── DeviceUtilPackageDescription.framework
│ ├── Headers
│ └── Modules
├── DeviceUtilTests.swiftmodule
│ ├── x86_64.swiftdoc
│ └── x86_64.swiftmodule
└── DeviceUtilTests.xctest
├── DeviceUtilTests
├── Frameworks
│ ├── libswiftCore.dylib
│ ├── libswiftCoreAudio.dylib
│ ├── libswiftCoreFoundation.dylib
│ ├── libswiftCoreGraphics.dylib
│ ├── libswiftCoreImage.dylib
│ ├── libswiftCoreMedia.dylib
│ ├── libswiftDarwin.dylib
│ ├── libswiftDispatch.dylib
│ ├── libswiftFoundation.dylib
│ ├── libswiftMetal.dylib
│ ├── libswiftObjectiveC.dylib
│ ├── libswiftQuartzCore.dylib
│ ├── libswiftSwiftOnoneSupport.dylib
│ ├── libswiftUIKit.dylib
│ ├── libswiftXCTest.dylib
│ └── libswiftos.dylib
├── Info.plist
├── _CodeSignature
│ └── CodeResources
└── libswiftRemoteMirror.dylib

9 directories, 25 files

I don't see my public Header in the resulting framework.

Thanks,
-- Paul

Ah, swift package generate-xcodeproj does not seem to add the Headers build phase and the defines module flag even though I added the publicHeadersPath.