Thank you so much, Quinn! I genuinely owe you for how often you unblock my from complicated issues :)
I agree that it would be best to let Xcode do the heavy lifting, and perhaps I will investigate that in the future - for now, since I already have a build pipeline set up for OpenSSL and Curl, I went with your suggestion of looking at what Xcode does and making a similar structure.
I can confirm that once I defined the module map within the platform-specific frameworks I can now use the libraries in Swift, both a Swift framework and a Swift package.
Post
Replies
Boosts
Views
Activity
Thanks Quinn,
I tried what you suggested and made a barebones C library that contains a single header and exports 1 method. I exported that into an xcframework.
If I make an iOS Framework using Objective-C then I can import that xcframework and use it in my code. The only modification I needed to make was to set the "framework search path" build setting.
However, if I try to make the same library using Swift, I can't use the xcframework within my code. I think it's the same issue as before where there's no module defined. I tried to make a module map file, but it again doesn't seem to even be recognized by the build.
I put everything up on a GitHub repo to make reviewing easier: https://github.com/ecnepsnai/Temp-Swift-Library-Issue
"ExampleLibrary" is the C library and "MyFramework" is the framework I'm trying to use it in.
Hi Quinn, let me elaborate.
When using a binary target, my Package.swift file looks like:
/Package.swift:
// swift-tools-version: 5.10
import PackageDescription
let package = Package(
name: "MyLibrary",
products: [
.library(
name: "MyLibrary",
targets: ["MyLibrary"]),
],
targets: [
.target(
name: "MyLibrary",
dependencies: ["OpenSSL", "Curl"]
),
.binaryTarget(name: "OpenSSL", path: "openssl.xcframework"),
.binaryTarget(name: "Curl", path: "curl.xcframework"),
.testTarget(
name: "MyLibraryTests",
dependencies: ["MyLibrary"]),
]
)
When I try to import either OpenSSL or Curl within any source files for MyLibrary it can't find those modules, for example:
/Sources/MyLibrary/Versions.swift:
import Foundation
import OpenSSL // No such module 'OpenSSL'
import Curl // No such module 'Curl'
public final class Versions {
public static func openssl() -> String {
return OPENSSL_VERSION_STR
}
public static func curl() -> String {
return LIBCURL_VERSION
}
}
I'm assuming that I need to define a module map file, but that doesn't seem to have any effect. If I create a module map for OpenSSL:
Sources/MyLibrary/openssl.modulemap:
module OpenSSL [system] {
header "opensslv.h"
link "ssl"
link "crypto"
export *
}
It doesn't seem to do anything, as I get the same error as above. In fact, I'm not even sure this file is being used at all, as if I fill it with gibberish, I don't get an expected syntax error.
Looking at the source of the ecdsa package in go, I can see the logic they use for prepending the 0 byte to either value:
if bytes[0]&0x80 != 0 {
c.AddUint8(0)
}
c.AddBytes(bytes)
So I'm assuming this is defined is some spec somewhere, but for now I suppose this is good enough for me to go on.
Thanks Matt, I submitted a TSI with ID #757876124
Thank you so much Quinn!
My problem was I was calling my code from the .preparing state, rather than ready. Happy to know I was on the right track, and that it's SO much easier to get the peer IP than with CFStreams (something I also struggled with a while ago: https://stackoverflow.com/questions/55436951/how-can-i-get-the-remote-address-from-a-cfstream-in-ios)