Module Not Found for Swift Package referenced by another Swift Package - swift

We have two swift packages that we've created. One has some bare bones swift code and the second has some Swift UI code. When we create a Swift UI application, it can see classes from either of the swift packages. However, we can't get the Swift UI package to see code from the other bare bones swift code package.
Both of the packages are being hosted on github. In the Swift UI package, we added a package dependency to package.swift like this:
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/myorg/myswiftpackage", from: "1.0.1")
],
When we try to use the classes from myswiftpackage, we get a "Module Not Found" error on the import statement.
What are we missing that allows a package to use code from another package?

Thanks Joakim, that was the answer. We had only listed it in the dependencies list, but both the targets also needed to have the package name listed as a dependency. Here's an example both references in case anyone needs it.
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/myorg/myswiftpackage", from: "1.0.1")
],
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 this package depends on.
.target(
name: "MySwiftUiPackage",
dependencies: ["MySwiftPackage"]),
.testTarget(
name: "MySwiftUiPackageTests",
dependencies: ["MySwiftUiPackage", "MySwiftPackage"]),
]

Related

How to create an SPM package based on ObjC code?

I'd like to create a SwiftPackageManager library based on Objective-C code but I can't seem to grasp what I'm missing.
My latest change to just vanilla ObjC interface .h file inside the include folder was to add an extra C header that includes de ObjC but still had no success. What am I missing?
The Package.swift file is the default generated one and from what I read it should automatically generate the module map from the include folder.
My swift-tools-version is 5.5
Figured it out.
I added a modulemap that specifies my ObjC header and it worked
Not sure if it is the correct way to do it since the include folder should already do this automatically.
So just had the same issue. (my 5 cent)
This is may Package.swift:
// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "AlgorithmSDK",
platforms: [
.iOS(.v13)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages. , "AlgorithmSDKObjc"
.library(
name: "AlgorithmSDK",
targets: ["AlgorithmSDK","AlgorithmSDKObjc" ]),
],
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 this package depends on.
.target(
name: "AlgorithmSDK",
dependencies: []),
.testTarget(
name: "AlgorithmSDKTests",
dependencies: ["AlgorithmSDK"]),
.target(
name: "AlgorithmSDKObjc",
dependencies: [],
publicHeadersPath:"include"),//<----- This path is relative to the target! (and can be ignored)
]
)
With the structure:
The publicHeadersPath should be publicHeadersPath:"include" OR ignored according to docs (it seems that it takes it relative to target and not the root). I don't think we should touch module.modulemap for such a simple structure

Conditional dependency for target in SwiftPM

I have a custom swift package I am building that has as one of its dependencies a package (Bugfender) that is an xcframework and is iOS only (and Mac Catalyst). Understandably, when I try to compile this package in Xcode (12.5) I get an error that a mac library for that package cannot be found (all iOS specific code is wrapped in a #if os(iOS) block).
Based on this (https://github.com/apple/swift-evolution/blob/master/proposals/0273-swiftpm-conditional-target-dependencies.md) addition to the Swift package spec, I thought I could use a condition to exclude the dependency for mac, but when I try the following Swift.package file, I still get the same error when building for mac. Is this a bug or am I doing something wrong? It seems like it should work based on this post as well (Swift package manager: How best to indicate platform dependent code?)
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "GTSApplicationLogging",
platforms: [
.iOS(.v12), .macOS(.v10_13),
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "GTSApplicationLogging",
targets: ["GTSApplicationLogging"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(name: "BugfenderPackage", url: "https://github.com/bugfender/BugfenderSDK-iOS", .exact("1.10.2")),
.package(url: "https://github.com/SwiftyBeaver/SwiftyBeaver.git", .exact("1.9.5")),
.package(url: "https://github.com/marmelroy/Zip.git", .exact("2.1.1")),
.package(path: "../GTSPureAppleExtensions"),
.package(path: "../GTSApplicationError"),
],
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 this package depends on.
.target(
name: "GTSApplicationLogging",
dependencies: ["SwiftyBeaver", "GTSPureAppleExtensions", "GTSApplicationError", "Zip", .product(name: "BugfenderLibrary", package: "BugfenderPackage", condition: .when(platforms: [.iOS]))]),
.testTarget(
name: "GTSApplicationLoggingTests",
dependencies: ["GTSApplicationLogging", "GTSApplicationError"]),
])

How to add a .framework as dependency to a swift package in Xcode?

I want to know if there is anyway to link a swift package against a framework like SQLite.framework in Xcode? I'm trying to make a swift package for a sqlite library wrapper.
Here is my current swift package manifest:
// swift-tools-version:5.1
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "SQLiteDB",
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "SQLiteDB",
targets: ["SQLiteDB"]),
],
dependencies: [
// .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: "SQLiteDB",
dependencies: []),
.testTarget(
name: "SQLiteDBTests",
dependencies: ["SQLiteDB"]),
]
)
I ended up creating my own Sqlite package by embedding the amalgamation sources of sqlite. This gives you the ability to have any arbitrary version of Sqlite in your apps.
With the Xcode 12 beta, you can do this if you update your swift-tools-version to 5.3, and then add a binaryTarget to your package's targets:
.binaryTarget(
name: "Stripe",
url: "https://github.com/stripe/stripe-ios/releases/download/v19.3.0/Stripe.xcframework.zip",
checksum: "fe459dd443beee5140018388fd6933e09b8787d5b473ec9c2234d75ff0d968bd"
)

Problem with Swift Package Manager - module map should be inside "Include" directory

This is my Package.swift file:
let package = Package(
name: "MyProject",
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/AlwaysRightInstitute/cows.git",
from: "1.0.0"),
.package(url: "https://github.com/NozeIO/MicroExpress.git",
.branch("branches/swift-nio-lib"))
],
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: "Demo",
dependencies: [
"cows", "MicroExpress"
],
path: ".")
]
)
I've already initialised the Package correctly (I think) and the git repos are fetched (using "Swift package fetch/resolve")
Now i'm trying to "Swift build" but I get the follosing error:
'MyTarget' /Users/nimrodshai/Documents/MyProject: error: package has unsupported layout; modulemap '/Users/nimrodshai/Documents/MyProject/Pods/FirebaseCrash/Frameworks/FirebaseCrash.framework/Modules/module.modulemap' should be inside the 'include' directory
Anyone has any idea how do I solve this?
Edit:
I've trying uninstalling everything from the Pod file (including firebase) and then build. This is what i'm getting:
'Toky' /Users/nimrodshai/Documents/TOKY-TOY: error: target at '/Users/nimrodshai/Documents/TOKY-TOY' contains mixed language source files; feature not supported
Try using the documentation found here for publicHeadersPath for targets. It says:
publicHeadersPath: This property defines the path to the directory containing public headers of a C target. This path is relative to the target path and default value of this property is include. Only valid for C family library targets.
You should be able to set that to the path to your module.modulemap and it will then be happy.

Unable to create a Swift Package Manager library

The documentation about SPM is quite poor and most of the articles about it were published when SPM began.
I have implemented an algorithm (Hungarian algorithm) in Swift and was looking forward to publish it as a library in Github. I have had to use the SPM for the first time in this project to resolve another dependency and once it has started to work, it was perfect.
Now, I am not being able to use my library from another project. I have decided to start with a new fresh git repo cause I couldn't get the previous to work.
The library is named Hume and it has inside a Hume.swift file which defines a Hume class.
The steps I have gone through are these:
Created directory for the library
swift package init --type library
Populated the files with the code
Pushed to a GitHub repo + tagged the version
Created directory for the executable which is going to use the library
swift package init --type executable
Add the dependency in Package.swift
swift build
At this point, swift clones the repo of the library and compiles it without problems (as main.swift contains just a Hello world).
swift package generate-xcodeproj
An when I open the project and try to import my library, it seems the module name is recognized but when I try to declare an object, it says I can't declare a variable of a type that is a module.
This is the Package.swift file in the library:
// 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: "Hume",
products: [
.library(
name: "Hume",
targets: ["Hume"]),
],
dependencies: [
.package(url: "https://github.com/aleph7/Upsurge.git", from: "0.10.2"),
],
targets: [
.target(
name: "Hume",
dependencies: ["Upsurge"]),
.testTarget(
name: "HumeTests",
dependencies: ["Hume"]),
]
)
The Library has only one file with this style:
import Upsurge
class Hume {
// Attributes
....
init(matriz:[[Double]]){
....
}
public func resuelve() -> (Double, [(Int, Int)]){
....
}
}
This is the Package.swift in the dummy executable:
// 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: "aa",
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/Jasagredo/Hume.git", from: "0.1.1"),
],
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: "aa",
dependencies: ["Hume"]),
]
)
The output when building:
~/Desktop/aa  swift build
Fetching https://github.com/Jasagredo/Hume.git
Fetching https://github.com/aleph7/Upsurge.git
Cloning https://github.com/Jasagredo/Hume.git
Resolving https://github.com/Jasagredo/Hume.git at 0.1.1
Cloning https://github.com/aleph7/Upsurge.git
Resolving https://github.com/aleph7/Upsurge.git at 0.10.2
Compile Swift Module 'Upsurge' (30 sources)
Compile Swift Module 'Hume' (1 sources)
Compile Swift Module 'aa' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/aa
~/Desktop/aa 
But when I edit main.swift in the dummy executable, I find this error:
import Hume
var a = Hume(matriz: [[1,1],[1,1]]) //Cannot call value of non-function type 'module<Hume>'
Also, Xcode doesn't auto-suggest me the class Hume. I just don't know what I'm doing wrong.
Any help is appreciated.
I have finally managed to get things to work. The problem was the class (and it's init method) weren't declared as public. The rest of the configuration is correct.