johnno1962 / InjectionIII

Re-write of Injection for Xcode in (mostly) Swift
MIT License
4.08k stars 319 forks source link

Loading .dylib has failed #485

Closed joshuawright11 closed 9 months ago

joshuawright11 commented 9 months ago

Hello 👋

First off thanks for the amazing library - it's been a game changer.

However, I'm hitting this issue when hot reloading a module in a larger (~100k LoC) project. I've tried re-running to no avail, and I also tried removing the indicated type (MockSampleService) but a similar error is thrown with another type.

Any ideas on how I could fix?

💉 Loading .dylib ...

⚠️ dlopen() error: dlopen(/Users/jwright/Library/Developer/CoreSimulator/Devices/2D52E204-AAB5-413D-9089-5DFDC3B89053/data/Containers/Data/Application/096D4D0C-738E-44A4-B0A3-BCC495789135/tmp/eval101.dylib, 0x0002): symbol not found in flat namespace '_$s10Networking18MockSampleServiceVAA0cD0AAMc'

💉 ⚠️ Loading .dylib has failed, This is likely because Swift code being injected references a function using a default argument or a member with access control that is too restrictive or perhaps an XCTest that depends on code not normally linked into your application. Rebuilding and re-running your project (without a build clean) can resolve this.

johnno1962 commented 9 months ago

There is some code to "make these symbols visible" but for a large project it might take some time to run, When you get this error, perhaps leaving the app to run for a bit it will be able to complete. Which version of the app are you.using? AppStore/Downloaded from GitHub/standalone? Try the GitHub version.

joshuawright11 commented 9 months ago

Thanks for the fast reply!

I wasn't able to get it to work after letting it run for a bit (~60 seconds). I'm using the GitHub version.

Is this specifically because of a .dylib in our project that I could tinker with to debug? Also would be interested in the "make these symbols visible approach" or any other suggestions by which I could debug.

johnno1962 commented 9 months ago

How do you mean ".dylib in our project". Does it contain MockSampleService?

joshuawright11 commented 9 months ago

How do you mean ".dylib in our project". Does it contain MockSampleService?

Out of our ~50 swift packages, 2 are setup as dynamic frameworks, however, MockSampleService is not in either of them. I'm mainly spitballing as to why Inject might be trying to load a .dylib, per the error message.

Also, we're using The Composable Architecture in our project. I heard offhand from a tutorial by Krzysztof Zabłocki that Injection may not work with TCA out of the box. Not sure if this would cause the issue I'm experiencing - however, the sample View I'm trying to test with doesn't use TCA features.

johnno1962 commented 9 months ago

You can inject TCA out of the box now if you are using the new ReducerProtocol and you have the -Xlinker -inteposable flags set. That isn't the problem here though. It's difficult to know what to say without seeing your project using TeamView.

joshuawright11 commented 9 months ago

Okay good to know.

Got it - happy to book time for that if you're down and have a way to do so!

johnno1962 commented 9 months ago

When you're good to go you can email your login details to github at johnholdsworth.com. I'm on European time zone.

joshuawright11 commented 9 months ago

Actually I may have figured out part of the issue - I'm a bozo and forgot to add the -Xlinker & -interposable flags to some local packages and the top level app.

Once I added those flags to the top level app and all local dependencies the error changed to:

symbol not found in flat namespace '_$s22ComposableArchitecture5StoreCMn'

Only referencing types in 3rd party dependencies. Is there something I need to do to pass the linker flags to those third party deps? (for example, if I remove the TCA dependency a symbol from another 3rd party dep - '_$s6Inject16ObserveInjectionVMn' isn't found since I'm using the Inject wrapper around your library)

If you don't have any ideas there I'll see about email creds over - turns out it may be more complicated than I realized with company policy etc.

johnno1962 commented 9 months ago

At this point I'd do a build clean and try again and see where you're situated.

joshuawright11 commented 9 months ago

Did a full clean / derived data nuke. Same issue:

symbol not found in flat namespace: SomeMangled3rdPartyDependencyType

johnno1962 commented 9 months ago

An idea a bit from left field, have you tried adding "Other linker flags": -Xlinker -undefined -Xlinker dynamic_lookup?

joshuawright11 commented 9 months ago

Same issue unfortunately.

joshuawright11 commented 9 months ago

I've got the flags only enabled in DEBUG, I assume that isn't a problem?

.unsafeFlags(["-Xlinker", "-interposable"], .when(configuration: .debug)),

johnno1962 commented 9 months ago

Looks OK but without seeing your project it's difficult to say more. It could be many things. Seems like your project is pushing the envelope a bit.

joshuawright11 commented 9 months ago

I ended up figuring out the issue - the Xcode project was generated with XcodeGen and I'd mistyped other linker flags causing the -Xlinker and -interposable flags not to be recognized.

Thanks for the pointers!