Dependency only for Linux?

Hi,

More test reporting: The build work from command-line if I force path to SDK libxml includes.

For example, on MacOS:

swift build -Xcc -I/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/libxml2

or on Linux:

swift build -Xcc -I/usr/include/libxml2

I have no idea why the swift build command does not have the same complete path to system libraries includes, like XCode has.

Update: I tried building that package from an XCode 11 iOS project. and it does not work and fails because it cannot find the libxml2 headers.

I think the build is somewhat a bug as the Swift package build fine on XCode beta 11, but not an application depending on that same module.
I would also expect swift build to have the same behaviour as XCode build and build successfully the project as well.

I think I need to create a bug report.

Update: Submitted Feedback FB7213576

Thanks for filing a bug report on this! If you believe there is also a bug with swift build here, please also file a JIRA on SwiftPM (https://github.com/apple/swift-package-manager/blob/master/Documentation/Resources.md#reporting-a-swiftpm-bug). Thanks!

1 Like

Sure, I will fill the report on SwiftPM tracker tomorrow.

Thanks !

Here is the SwiftPM bug report: [SR-11427] Swift Package cannot depend on libxml2 from SDK reliably · Issue #4666 · apple/swift-package-manager · GitHub

I updated my bug reports with the latest Xcode 11 GM.
At least now, we have a consistent behaviour: Both Xcode or SwiftPM build cannot properly find the libxml2 headers.
Here is the Package.swift file: XMPP/Package.swift at master · FluuxIO/XMPP · GitHub

So, it is unclear now how to properly set this up. Was the fact that Xcode was building fine the project a bug and what would be the preferred way to build a code depending on libxml2 ?

I just tried getting libxml2 from the macOS SDK to work and failed. It's possible that's due to this comment in MacOSX10.15.sdk/usr/include/libxml2/module.modulemap:

module libxml2 [system] [extern_c] {
    // Add "-Xcc -I$(SDKROOT)/usr/include/libxml2" to OTHER_SWIFT_FLAGS in Xcode project.

@Aciid / @NeoNacho could you help us getting libxml2 from the SDK to work? If we get that to work, then I'm sure we can get Linux to work too.

I tried .systemLibrary as well as .target with linkerSettings/cSettings etc.

Is it even possible to add something like $(SDKROOT) to Package.swift?

1 Like

There is no solution for this at the moment, we're tracking this issue for packages in Xcode already as rdar://problem/52406575

Thanks for the feedback.
With the release "train" that is schedule to arrive soon, I bet you have other things on your plate, but if you need a hand to test this type of build at a later point in time, I would be glad to help.

I tried the exact same steps with the same results over time: Referring to libxml2 in Swift Package Description
I'm very interested in the resolution the Swift team might bring in time. Why not broaden the scope of .systemLibrary to something like .systemLibrary(name: "libxml2", constraints: ...) to target SDKs for platforms in Xcode while still maintaining a possibility to specify a different "source" for Linux.

I also have a couple cases where this would be useful. I'm building a cross-platform (macOS/Linux) app Using DNS service discovery. On macOS it uses the Bonjour API from Foundation, but this isn't available on Linux so instead I have a package that wraps dns-sd for Avahi. So for Linux I have the dns_sd dependency that references a header file and library that doesn't exist on macOS. It's less than ideal, but I'm currently doubling up my Package.swift definition with #if os(Linux) #else.
After updating the Linux side to Swift 5.1, I've found a need to go back the other way. The Linux code now needs to import FoundationNetworking but rather than wrap that in #if everywhere, I've created an empty FoundationNetworking package to import only into the macOS target.

So in my case, it would definitely be useful to be able to have a single Package definition with dependencies limited to particular platforms.

Hi Johannes,

Do you have any suggestions for when you have a library dependent on SSL library functions like hmac, sha256? Currently to get my library to compile for macOS, iOS and Linux I use openSSL on Linux and CommonCrypto on macOS and iOS. There is a switch in the Package.swift that includes GitHub - apple/swift-nio-ssl-support on Linux platforms. Then in the code I use

#if canImport(CommonCrypto)
// macOS/iOS code
#else
// Linux code
#endif

Nobody seems to have solved this satisfactorily. Swift NIO include their own SSL library, IBM-Swift/BlueCryptor include a #if os(Linux) in their Package.swift.

Any thoughts?

1 Like

@adam-fowler why don't you always depend on swift-nio-ssl-support, you can still use CommonCrypto (actually, CryptoKit should be preferred) or macOS, no?

@johannesweiss swift-nio-ssl-support requires the libressl library. This doesn't run on iOS. On macOS it requires end users to switch off disableLibraryValidation in the Hardened Runtime section of the signing and capabilities project settings on any project that uses our library. This isn't necessarily something I would like to require of our users.

As far as I know, SwiftPM doesn't actually enforce that you have the dependency; I think it just issues a warning that you may need a certain library. But I was thinking that if you don't actually use it, you may be able to get away with not having it installed. Am I missing something?

If I include swift-nio-ssl-support.git in package.dependencies I get the following error when I run on the iPhone simulator.

2019-10-17 23:25:49.451072+0100 xctest[84050:3582871] The bundle “AWSSDKSwiftCoreTests” couldn’t be loaded because it is damaged or missing necessary resources. Try reinstalling the bundle.
2019-10-17 23:25:49.451170+0100 xctest[84050:3582871] (dlopen_preflight(/Users/adamfowler/Library/Developer/Xcode/DerivedData/aws-sdk-swift-core-fncbnnplhybomqfjxxitigdsalcp/Build/Products/Debug-iphonesimulator/AWSSDKSwiftCoreTests.xctest/AWSSDKSwiftCoreTests): Library not loaded: /usr/local/opt/libressl/lib/libssl.47.dylib
  Referenced from: /Users/adamfowler/Library/Developer/Xcode/DerivedData/aws-sdk-swift-core-fncbnnplhybomqfjxxitigdsalcp/Build/Products/Debug-iphonesimulator/AWSSDKSwiftCoreTests.xctest/AWSSDKSwiftCoreTests
  Reason: no suitable image found.  Did find:
	/usr/local/opt/libressl/lib/libssl.47.dylib: mach-o, but not built for iOS simulator)

If I don't include it then I get the following errors when compiling for Linux

/aws-sdk-swift-core/Sources/AWSSDKSwiftCore/HMAC.swift:17: error: undefined reference to 'EVP_sha256'
/aws-sdk-swift-core/Sources/AWSSDKSwiftCore/HMAC.swift:17: error: undefined reference to 'HMAC_Init_ex'
/aws-sdk-swift-core/Sources/AWSSDKSwiftCore/HMAC.swift:20: error: undefined reference to 'HMAC_Update'
/aws-sdk-swift-core/Sources/AWSSDKSwiftCore/HMAC.swift:23: error: undefined reference to 'HMAC_Final'
/aws-sdk-swift-core/Sources/AWSSDKSwiftCore/Hash.swift:18: error: undefined reference to 'SHA256'
...

Oh and by the way I did try it without libressl installed and it did just show the warning and ran ok on iPhone. Depending on someone not having a library installed seems a little suspect though.

@adam-fowler ahh, right, apologies. The problem is that it tries to link it despite the fact that it's not used...

Yes that is the case.

Please see my reply at Referring to libxml2 in Swift Package Description - #9 by jakepetroules regarding libxml2.

That’s great news!
Thanks @jakepetroules, I will give it a try.