manolofdez / AsyncBluetooth

A small library that adds concurrency to CoreBluetooth APIs.
MIT License
160 stars 30 forks source link

Doesn't compile with BUILD_LIBRARY_FOR_DISTRIBUTION=YES #52

Closed mbvs closed 1 month ago

mbvs commented 3 months ago

Hi,

I am using AsyncBluetooth as a dependency for a Framework I am building

when I am trying to build the framework archive with

xcodebuild archive \
    SKIP_INSTALL=NO \
    BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
    -workspace Cube.xcworkspace \
    -scheme CubeReader \
    -destination "generic/platform=iOS" \
    -archivePath "build/CubeReader" 

I get Errors like this:

/Xcode/DerivedData/Cube-gebyvdjvuxpdpwhdrptryrgycpdm/Build/Intermediates.noindex/ArchiveIntermediates/CubeReader/IntermediateBuildFilesPath/AsyncBluetooth.build/Release-iphoneos/AsyncBluetooth.build/Objects-normal/arm64/AsyncBluetooth.swiftinterface:140:26: error: 'Characteristic' is not a member type of struct 'AsyncBluetooth.AsyncBluetooth'
extension AsyncBluetooth.Characteristic {
          ~~~~~~~~~~~~~~ ^

and the build fails.

without the BUILD_LIBRARY_FOR_DISTRIBUTION flag the build runs fine.

Any help appreciated.

buildlog.txt

manolofdez commented 3 months ago

Hi! You're seeing this issue because AsyncBluetooth doesn't support library evolution. Instead of providing a binary, AsyncBluetooth distributes the sources. And since clients will need to compile it every time, there's no need to guarantee ABI stability.

In order to use the package in one that supports library evolution, you'll need to hide the use of this framework by doing @_implementationOnly import AsyncBluetooth. Note this will work as long as you aren't exposing any of the types from this library in your public API.

Let me know if this works for you.

mbvs commented 3 months ago

Hi Manuel,

thx for your quick response and sorry for my late reply - had do do my homework.

As you suggested I prepended every import of AsyncBluetooth with @_implementationOnly and I don't expose any types from AsyncBluetooth publicly.

To build an xcframework I need one (or multiple) archives and I have two possibilities to make one: via CLI or via XCode GUI. I also have two possibilities to set the BUILD_LIBRARY_FOR_DISTRIBUTION flag: either in the Build Settings of the Target or as a build flag when invoking xcodebuild archive on the commandline.

My tests so far showed the following outcome: GUI:

CLI:

both archives have different sizes, but when I pack them with xcodebuild -create-xcframework they both generate the same xcFramework (at least diff -qr found no difference) and both work when I embed them in an app.

My understanding so far is that build library for distribution has two purposes:

I think I don't need library evolution, but I am certain that I need module stability.

So right now it puzzles me:

I am pretty aware that these questions exceed the scope of an issue of your lib - which btw was a great timesaver for me - by far but any insight in this stuff is greatly appreciated.

mbvs commented 2 months ago

fixed my problem by coding the async/await wrappers around the delegate methods myself and by this refactoring out the AsyncBluetooth Library.

Obviously AsyncBluetooth wasn't a match for my use case.

A short note that the lib doesn't support Library Evolution & Module Stability in the Readme would be great - but anyway thanks for your effort! Issue can be closed.

manolofdez commented 1 month ago

Apologies for coming back to this so late. Glad you were able to figure out a solution! I'll update the README to include a note about Library Evolution.