ReactiveX / RxSwift

Reactive Programming in Swift
MIT License
24.39k stars 4.17k forks source link

Error when using package manager in Xcode 11.4 beta #2127

Closed nhatlee closed 4 years ago

nhatlee commented 4 years ago

Short description of the issue:

I create new project for test using RxSwift via Swift package manager . In Xcode project I chose File -> Swift Packages -> Add Package Dependency... to add RxSwift repo. But after Xcode fetch the RxSwift lib successful. I press build and get the error:

ld: warning: Could not find or use auto-linked library 'XCTestSwiftSupport'
ld: warning: Could not find or use auto-linked framework 'XCTest'
Undefined symbols for architecture x86_64:
  "XCTest.XCTAssertEqual<A where A: Swift.Equatable>(_: @autoclosure () throws -> A, _: @autoclosure () throws -> A, _: @autoclosure () -> Swift.String, file: Swift.StaticString, line: Swift.UInt) -> ()", referenced from:
      RxTest.XCTAssertEqual<A where A: Swift.Equatable>(_: [RxSwift.Event<A>], _: [RxSwift.Event<A>], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertEqual<A where A: Swift.Equatable>(_: [RxSwift.SingleEvent<A>], _: [RxSwift.SingleEvent<A>], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertEqual<A where A: Swift.Equatable>(_: [RxSwift.MaybeEvent<A>], _: [RxSwift.MaybeEvent<A>], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertEqual(_: [RxSwift.CompletableEvent], _: [RxSwift.CompletableEvent], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertEqual<A where A: Swift.Equatable>(_: [RxTest.Recorded<RxSwift.Event<A>>], _: [RxTest.Recorded<RxSwift.Event<A>>], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertEqual<A where A: Swift.Equatable>(_: [RxTest.Recorded<RxSwift.Event<A?>>], _: [RxTest.Recorded<RxSwift.Event<A?>>], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertRecordedElements<A where A: Swift.Equatable>(_: [RxTest.Recorded<RxSwift.Event<A>>], _: [A], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      ...
  "XCTest.XCTFail(_: Swift.String, file: Swift.StaticString, line: Swift.UInt) -> ()", referenced from:
      RxTest.XCTAssertRecordedElements<A where A: Swift.Equatable>(_: [RxTest.Recorded<RxSwift.Event<A>>], _: [A], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
  "__swift_FORCE_LOAD_$_XCTestSwiftSupport", referenced from:
      __swift_FORCE_LOAD_$_XCTestSwiftSupport_$_RxTest in RxTest.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Showing All Messages
Could not find or use auto-linked library 'XCTestSwiftSupport'

Could not find or use auto-linked framework 'XCTest'

Undefined symbol: XCTest.XCTAssertEqual<A where A: Swift.Equatable>(_: @autoclosure () throws -> A, _: @autoclosure () throws -> A, _: @autoclosure () -> Swift.String, file: Swift.StaticString, line: Swift.UInt) -> ()

Undefined symbol: XCTest.XCTFail(_: Swift.String, file: Swift.StaticString, line: Swift.UInt) -> ()

Undefined symbol: __swift_FORCE_LOAD_$_XCTestSwiftSupport

Expected outcome:

Expected run success.

What actually happens:

Got the error with above log

RxSwift/RxCocoa/RxBlocking/RxTest version/commit

5.0.1

Platform/Environment

How easy is to reproduce? (chances of successful reproduce after running the self contained code)

Xcode version:

Xcode 11.4 beta 1

:warning: Fields below are optional for general issues or in case those questions aren't related to your issue, but filling them out will increase the chances of getting your issue resolved. :warning:

Installation method:

I have multiple versions of Xcode installed: (so we can know if this is a potential cause of your issue)

Level of RxSwift knowledge: (this is so we can understand your level of knowledge and formulate the response in an appropriate manner)

nhatlee commented 4 years ago

I post full logs : Build target LovePet_2020-02-09T11-24-15.txt

freak4pc commented 4 years ago

Hey there :) If it works on 11.4 (which is in beta) and doesn't have issues on 11.3, this is likely a bug inside SPM itself.

We only have so much capacity so we can't spend the time fixing specific package manager bugs, at least not until 11.4 goes out of beta.

If you have a PR that might fix this issue, I'm happy to review and merge it.

Thanks !

freak4pc commented 4 years ago

@nhatlee Do you have additional feedback on this issue?

nhatlee commented 4 years ago

I don't have time to investigating this issue since I posted it. I will try to find out when have time.

nhatlee commented 4 years ago

After some trying. It seem the issue related to problem with linking XCTest. Move RxTest from target to testTarget fixed the issue. The change for Package file like this commit: https://github.com/nhatlee/RxSwift/commit/19df574ac70e4ce3f758a807b8541097c7397398

freak4pc commented 4 years ago

It shouldn't be a testTarget, the reason it's working for you is that you removed all of its dependencies

There's an entire discussion around this here: https://twitter.com/freak4pc/status/1233560587176681472

freak4pc commented 4 years ago

From discussions in the SPM slack this seems like a bug. I've reported it here: https://bugs.swift.org/browse/SR-12303 And also filed a feedback: FB7608638

truizlop commented 4 years ago

I have the same issue after updating to Xcode 11.4 (stable version, not beta). Any way to solve/workaround this?

freak4pc commented 4 years ago

The workaround is to wrap all of your Rx dependencies in one product inside your own app, which would remove the duplications. I'm not sure this would work for RxTest and RxBloccking, though:

let package = Package(
  name: "Rx Wrapper",
  products: [
    .library(name: "Rx", targets: ["Rx"]),
    .library(name: "RxTesting", targets: ["RxTesting"])
  ],
  dependencies: [
    .package(
      url: "https://github.com/ReactiveX/RxSwift.git",
      .upToNextMajor(from: "5.0.0")
    )
  ],
  targets: [
    .target(
      name: "Rx",
      dependencies: ["RxSwift" , "RxCocoa", "RxRelay"]
    ),
    .target(
      name: "RxTesting",
      dependencies: ["RxTest", "RxBlocking"]
    )
  ]

I'm not sure this will work for the test target, as mentioned above. This workaround was added in the SPM Slack by @DevAndArtist, but I hope Apple will provide an actual solution at some point:

RxSPM_Mod.zip

antranapp commented 4 years ago

I have a similar problem now with Xcode 11.4.1

I can see now, if I integrate RxSwift using SPM, SPM will built RxSwift as a static library:

Screenshot 2020-05-06 at 22 04 31

I could workaround the issue by forcing SPM to build RxSwift as a dynamic framework in my fork: https://github.com/antranapp/RxSwift/commit/722615a926029289acd671dcf95a7494d41caf06

Screenshot 2020-05-06 at 22 05 07

Is there any reason that we are not building RxSwift as a dynamic library by default?

freak4pc commented 4 years ago

@antranapp From the tests I've ran it only solves half of the issues. Tests still don't run.

There's a long discussion in the SPM slack around this, and generally, it's an "open bug" . What we might have to do is basically not allow installing RxTest and RxBlocking via SPM until Apple solves this, and that should mostly solve it, I believe.

Genar commented 4 years ago

In addition it could be useful to assign both RxBlocking and RxTest only to test targets (not your app target). For example, in the previous image, it could be useful to assign RxBlocking and RxTest not to the target XCoordinator but to a "XCoordinatorTests".

freak4pc commented 4 years ago

This is still an issue in Xcode 11.5. I'm not sure if there is much to be done here or if there is reason to leave this open. Apple provides us no way to make this work well. The only workable option would be to break RxSwift into a bunch of smaller repos (5-6-7 repos) which isn't something I'm interested in doing. I hope they'll find a fix for this soon.

If anyone has any additional questions / feedback, feel free to comment and I can always reopen. Thanks!

phoe3nix commented 4 years ago

@nhatlee @freak4pc Hello! I have completely translated my project to SPM and have this issue. In this attachment test project with RxSwift Libraries and working tests with static linking RxTest. Enable Testing Search Path with flag YES in this package configuration with additional wrapper local package allows you to run unit tests. RxTestProj.zip

freak4pc commented 4 years ago

I'm not entirely sure what are the configuration changes you made. Does it work for your own project?

phoe3nix commented 4 years ago

@freak4pc Yes, for my project it work great. In build settings for main app in chapter build options I change Enable Testing Search Path from NO to YES. I think, that is allow to find path to XCTest framework and use necessary symbol.

freak4pc commented 4 years ago

So, did you make a fork of this repo changing the product type to static for everything?

phoe3nix commented 4 years ago

Yes, all library static. When archive or build this app, we dont see folder frameworks in .app. Also export app work good.

freak4pc commented 4 years ago

Do you have other dependencies that depend upon RxSwift? For example RxDataSources, RxSwiftExt, or others?

phoe3nix commented 4 years ago

In my project yes. RxDataSource, RxSwiftExt and RxGesture.

freak4pc commented 4 years ago

That helps. Thank you! I'll take a look.

loganwright commented 4 years ago

@phoe3nix 's suggestion worked great for me!

In build settings for main app in chapter build options I change Enable Testing Search Path from NO to YES. I think, that is allow to find path to XCTest framework and use necessary symbol.

kbw2204 commented 4 years ago

In my project, Excluding the RxTest and RxBlocking parts of RxSwift solved the error.

thiagocenturion commented 3 years ago

In my project, Excluding the RxTest and RxBlocking parts of RxSwift solved the error.

Best answer if you wouldn't use RxTest and RxBlocking in unit tests. It works perfectly for me.

usman-pucit commented 3 years ago

Testing Search Path

Works for me

freakdragon commented 2 years ago

If someone gets error "Missing libXCTestSwiftSupport.dylib" after set Enable Testing Search Path than you must readd the library (package dependency) and set targets of RxTest and RxBlocking to your test targets. Look here to see the example.