-
Notifications
You must be signed in to change notification settings - Fork 451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Linking against static library that uses SwiftProtobuf causes linker errors #1101
Comments
At first glance, this doesn't really seem specific to Swift Protobuf and seems more like it is an issue mixing compile modes, so you might need to reach out on the Swift forums or some place else where folks might have more knowledge how how the different flags you might be using change how the compiler behaves. |
With the library you’re building for library distribution, are you using |
@Lukasa The generated code with |
Even if that would work, how can someone generate protos that contain a |
You cannot easily do this, and this limitation is ultimately derived from the fact that Swift Protobuf doesn’t really support being used in this way. In principle with sufficient design work it would be possible for Protobuf’s code generation to create types that would support this mode of operation, but it would require a separate mode for invoking the protoc plugin as it’s fundamentally incompatible with the current mode of operation. What are you trying to achieve by using library evolution mode? |
I'm trying to ship one binary Swift framework that uses SwiftProtobuf. I think this should be a pretty common use case. It's hard for me to believe that there's isn't a single SDK out there that uses SwiftProtobuf and is built for distribution as a XCFramework? |
There might be, but those distributions would need to hide the presence of SwiftProtobuf. Swift Protobuf does not support itself being built in library evolution mode, so it cannot be present in the public ABI of any framework that is built in library evolution mode. That means it can only ever be imported |
I'd love to hear more details about the "weird Objective-C runtime data corruption" you saw. Can you help us reproduce that? |
I just faced a similar problem. Our structure is the following:
Following the discussion above I switched Library A to expose a dynamic product instead of a static one and that seemed to resolve these issues. It's not clear to me though why this is happening and if there is something wrong on they way we are linking the different projects. |
@mkotsiandris How are you linking frameworks A and B? |
I am experiencing also multiple linking issues with the latest version of Firebase
I managed to reproduce it in a sample project. The sample project integrates To run the sample project install
I tested multiple integration alternatives for
TLDR:
So far I could not figure out the root cause of the linking issues, but it is clear that they only happen when |
I face a similar issue. I develop an SDK that at the present time uses Protobuf as an internal implementation detail. We ship this framework both as a dynamic .xcframework as well as a static .xcframework for our consumers that then build their own SDK which encapsulates ours. Using the I now face the situation where I need to make one of the Protobuf generated objects from this SDK
I guess the main question I am asking here is... what is the reason that
Is there anything that can be done to make that support possible? |
Ultimately this is just a project policy decision. The project can choose to define a stable ABI if it wishes to. In the short term this would require a pretty extensive audit of the ABI, to confirm that everything that is currently exposed should be. It also has performance implications that might be important as well, so the project should probably be investing in that effort too. |
Hi, I'm facing the same problem. Can you please provide any suggestions, how can I correctly add Swift Protobuf dependency as XCFramework to the project without having errors? |
so changing |
Yes, that will work. Note that you'll be unable to use any protobuf message types in your API. |
I'm using protobuf messages inside the library, so it's not exposed to the client via external API. Ok, thanks! I'll try it and let you know about the results. |
@Lukasa I changed |
That sounds like everything is working correctly. |
In this case app is compiled correctly, but during starting it in the iOS simulator, the following errors are thrown:
What should I do to make it working correctly? |
This appears to be an issue with the way the app is being built or with the xcframework. I don't know how you're packaging it or how you've built your XCFramework, but questions about how to get xcframeworks working in simulators are probably best handled on the Apple Developer Forums. |
I'm building my XCFramework with the following script below. It's pretty basic. Is there anything wrong with that? Moreover, I have more dependencies to my XCFramework and I provided them to the client via other XCFrameworks (SWCompression, RxCocoa, RxSwift) and there are problems only with SwiftProtobuf. #!/usr/bin/env bash
start_time=$(date +%s)
echo "▸ CLEAN"
rm -rf build/ || true
xcodebuild clean
echo "▸ BUILD"
xcodebuild build \
-workspace iOS-SDK.xcworkspace \
-scheme iOS-SDK \
-sdk iphoneos \
-configuration Release \
SKIP_INSTALL=NO \
echo "▸ ARCHIVE: iOS Device"
xcodebuild archive \
-workspace iOS-SDK.xcworkspace \
-scheme iOS-SDK \
-configuration Release \
-destination 'generic/platform=iOS' \
-archivePath './build/iOS-SDK.framework-iphoneos.xcarchive' \
SKIP_INSTALL=NO \
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
echo "▸ ARCHIVE: iOS Simulator"
xcodebuild archive \
-workspace iOS-SDK.xcworkspace \
-scheme iOS-SDK \
-configuration Release \
-destination 'generic/platform=iOS Simulator' \
-archivePath './build/iOS-SDK.framework-iphonesimulator.xcarchive' \
SKIP_INSTALL=NO \
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
echo "▸ CREATE XCFRAMEWORK"
xcodebuild \
-create-xcframework \
-framework './build/iOS-SDK.framework-iphonesimulator.xcarchive/Products/Library/Frameworks/iOS_SDK.framework' \
-framework './build/iOS-SDK.framework-iphoneos.xcarchive/Products/Library/Frameworks/iOS_SDK.framework' \
-output './build/iOS-SDK.xcframework'
echo "▸ CLEAN XCARCHIVES"
rm -rf build/*.xcarchive
echo "▸ COPY PODSPEC"
cp iOS-SDK.podspec.integration build/iOS-SDK.podspec
if [ -d "build/iOS-SDK.xcframework" ] ; then
echo "▸ SUCCESS"
else
echo "▸ FAILURE !!!"
exit 0
fi
end_time=$(date +%s)
elapsed=$(( end_time - start_time ))
echo "▸ DONE in $elapsed s" |
Where is the requirement to load SwiftProtobuf coming from? I'd normally expect that the above would not produce a SwiftProtobuf dylib directly, if you're using Swift Package Manager, as typically SwiftPM statically links dependencies. |
Unfortunately, I don't have the access to the final app code. I'm just providing my XCFramework. Client sent me errors pasted above and said that he compiled app successfully and got these errors when app was starting in the iOS simulator. I know that they don't use any iOS package managers like Swift PM or CocoaPods due to some corporate/security regulations and they're adding all dependencies manually as XCFrameworks in the XCode. |
Ok, so they'll need a detailed build log to work out what is trying to load |
Ok, I got build logs. When they don't attach SwiftProtobuf as XCFramework and they attach my library only as XCFramework, then nothing is trying to load SwiftProtobuf. There's no SwiftProtobuf in the build log, but build finishes with success. When app is starting, the following error is thrown in the runtime:
In the log above Can you give any suggestions, how to make it work without Cocoa Pods or Swift PM? |
So this seems to imply that your custom library is expecting a |
I'm not using Swift PM. I'm using Cocoa Pods in my project and I'm adding SwiftProtobuf as a CocoaPod dependency. In my code, the only place where I import SwiftProtobuf are files representing protobuf messages with My Podfile looks like that:
|
Unfortunately I'm not really able to help here: I don't know how to build an xcframework that bundles multiple frameworks. |
By |
I can't, because I don't know. All I can tell you is what I can see: your framework |
I don't believe this is possible; since the compiler's search path logic requires exactly one module per framework, I don't think the To folks distributing SwiftProtobuf as an The downside is that there's a binary size increase if someone is using your SDK and SwiftProtobuf because they'll need to link both, but there's not really another option if you want your SDK to be completely self-contained. I don't know Cocoapods well enough to get an idea of the extra work required there. But if you're just using Cocoapods to distribute the static library xcframework artifacts, it shouldn't require any additional effort; all the changes would be to which flags you pass to |
Thanks for the response @allevato. Can you give some hints how can I apply module alias in CocoaPods based project? Examples from the link are dedicated to Swift PM as far as I see. I tried to search a solution for using module alias in Cocoa Pods, but could not find anything... I'm using Cocoa Pods mostly for managing project dependencies (pods) and generating xcworkspace for XCode for development. |
I'm not sure how Cocoapods would handle it, exactly. I'm assuming there's a mechanism that lets you pass arbitrary command line flags to Sorry I can't offer more specific guidance; I have next to zero experience with Cocoapods. |
Hello!
I'm seeing a pretty weird linker error related to
SwiftProtobuf
symbols. I'm going to describe the situation as much as possible.SwiftProtobuf
generated code. This library is built for library distribution, since we want to support multiple Xcode and Swift versions.SwiftProtobuf
from source (we had problems with distributingSwiftProtobuf
as a binary built with library distribution in the past since it would cause some weird Objective-C runtime data corruption), the compilation works fine.SwiftProtobuf
. We are using the same version everywhere, so I'm pretty sure it's not a version mismatch kind of error.(I redacted the
from
references since they contain internal code, but these symbols are referenced from the static library built with library distribution turned on)SwiftProtobuf
is built as a static library in our project, and I noticed that building it withSwiftProtobuf
with library distribution in our project would fix the issue, but given the other issue raised above, we can't do that.Do you have any idea how what the problem could be here? I'm pretty sure someone has used
SwiftProtobuf
in a Swift SDK before, so this problem should have surfaced.Why would building some Swift proto generated code for library distribution include some symbols that are not present when linking it to a
SwiftProtobuf
which is not built for library distribution.macOS 10.15.
xcodebuild -version
),for Linux, what version of Swift (
swift --version
)Xcode 12.0 but reproducible on 12.2.
settings, etc.)
Swift 5.2
1.12.0 but can reproduce with 1.14.0 as well.
Thanks for the help!
The text was updated successfully, but these errors were encountered: