johnno1962 / injectionforxcode

Runtime Code Injection for Objective-C & Swift
MIT License
6.55k stars 565 forks source link

"Learnt Compile Failed" after Xcode 7.3 for targets with > 128 swift sources #114

Closed diegomontoyas closed 7 years ago

diegomontoyas commented 8 years ago

Hi, I am getting this error after updating to Xcode 7.3

injecting_class.o 

***

Learnt compile failed ***

 at /Users/Diego/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/common.pm line 57.
 main::error('Learnt compile failed') called at /Users/Diego/Library/Application Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 349
*** Bundle build failed ***


There doesn't seem to be any sign of an error in the stack trace apart from a fairly comprehensive list of files

Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -filelist ... list of files

Any clues on this? Thank you very much.

johnno1962 commented 8 years ago

Not sure what this would be. Can I suggest clearing out DerivedData and rebuilding the project?

blommegard commented 8 years ago

I seem to get the same error in 7.3: https://gist.github.com/blommegard/081167615b45121487ea0cb354483d0a#file-gistfile1-txt

Cleaned and deleted DerivedData.

dtrukr commented 8 years ago

I'm getting the same error "Learnt compile failed". Seems like swift compiler segfaults:

sh: line 1: 2830 Segmentation fault: 11 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -filelist /var/folders/35/lqvht8mn5j14dxg7gqsfb62m0000gn/T/sources-996c37 -primary-file "/Users/den/gitmomo/Mobile.iOS.Search/Phone/View Management/Calendar And Pricegraph/PricegraphSelectorViewController.swift" -target x86_64-apple-ios8.0 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator9.3.sdk -I /Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Products/Debug-iphonesimulator -F /Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Products/Debug-iphonesimulator -F /Users/den/gitmomo/Mobile.iOS.Search/Shared/External -F /Users/den/gitmomo/Mobile.iOS.Search -F /Users/den/gitmomo/Mobile.iOS.Search/Carthage/Build/iOS -F /Users/den/gitmomo/Mobile.iOS.Search/Pods/HockeySDK/HockeySDK-iOS/HockeySDK.embeddedframework -F /Users/den/gitmomo/Mobile.iOS.Search/Pods/Reveal-iOS-SDK/Reveal-Framework-iOS-1.6.2 -enable-testing -g -import-objc-header "/Users/den/gitmomo/Mobile.iOS.Search/Supporting Files/Bridge.h" -module-cache-path /Users/den/Library/Developer/Xcode/DerivedData/ModuleCache -D DEBUG -serialize-debugging-options -Xcc -I/Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/swift-overrides.hmap -Xcc -iquote -Xcc /Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/Momondo-generated-files.hmap -Xcc -I/Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/Momondo-own-target-headers.hmap -Xcc -I/Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/Momondo-all-non-framework-target-headers.hmap -Xcc -ivfsoverlay -Xcc /Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/all-product-headers.yaml -Xcc -iquote -Xcc /Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/Momondo-project-headers.hmap -Xcc -I/Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Google/Headers -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/Google -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/GoogleAnalytics -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/GoogleAppUtilities -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/GoogleAuthUtilities -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/GoogleInterchangeUtilities -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/GoogleNetworkingUtilities -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/GoogleSignIn -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/GoogleSymbolUtilities -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/GoogleTagManager -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/GoogleUtilities -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/HockeySDK -Xcc -I/Users/den/gitmomo/Mobile.iOS.Search/Pods/Headers/Public/Reveal-iOS-SDK -Xcc -I/Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/DerivedSources/x86_64 -Xcc -I/Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/DerivedSources -Xcc -DDEBUG -Xcc -DCOCOAPODS=1 -Xcc -working-directory/Users/den/gitmomo/Mobile.iOS.Search -emit-module-doc-path /Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/Objects-normal/x86_64/PricegraphSelectorViewController~partial.swiftdoc -Onone -module-name Momondo -emit-module-path /Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/Objects-normal/x86_64/PricegraphSelectorViewController~partial.swiftmodule -serialize-diagnostics-path /Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/Objects-normal/x86_64/PricegraphSelectorViewController.dia -emit-dependencies-path /Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/Objects-normal/x86_64/PricegraphSelectorViewController.d -emit-reference-dependencies-path /Users/den/Library/Developer/Xcode/DerivedData/Momondo-gpxoaeysoxhvtuetcjqynebdiqfe/Build/Intermediates/Momondo.build/Debug-iphonesimulator/Momondo.build/Objects-normal/x86_64/PricegraphSelectorViewController.swiftdeps -o iOSInjectionProject/x86_64/injecting_class.o 2>&1

real 0m0.299s
user 0m0.005s
sys 0m0.290s
0 swift 0x000000010d1354eb llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 43
1 swift 0x000000010d1347d6 llvm::sys::RunSignalHandlers() + 70
2 swift 0x000000010d135b4f SignalHandler(int) + 287
3 libsystem_platform.dylib 0x00007fff8eaa5eaa _sigtramp + 26
4 libsystem_platform.dylib 0x000000000000ffff _sigtramp + 1901502831
5 swift 0x000000010b332809 readFileList(std::1::vector<std::1::basic_string<char, std::1::char_traits, std::1::allocator >, std::1::allocator<std::__1::basic_string<char, std::1::char_traits, std::_1::allocator > > >&, llvm::opt::Arg const, llvm::opt::Arg const_) + 153
6 swift 0x000000010b32d459 swift::CompilerInvocation::parseArgs(llvm::ArrayRef<char const>, swift::DiagnosticEngine&, llvm::StringRef) + 1273
7 swift 0x000000010ae85ccb frontend_main(llvm::ArrayRef<char const>, char const, void) + 907
8 swift 0x000000010ae81e3c main + 1932
9 libdyld.dylib 0x00007fff8fbaa5ad start + 1
10 libdyld.dylib 0x000000000000006c start + 1883593408
Stack dump:

johnno1962 commented 8 years ago

Thanks for the log. Looks like a compiler crash to me.. Actually it’s a problem. Large projects use "-filelist” with 7.3. You’re going to have problems injecting this project unless you can break it a smaller target + framework. I’ll look into it. Can you check if the file referred to in the -filelist argument exists?

blommegard commented 8 years ago

@johnno1962 File in the path exists. :(

johnno1962 commented 8 years ago

If you paste the command to the command line does it crash? (cd’ing to project directory)

johnno1962 commented 8 years ago

This looks like it might be a bit of a problem for larger projects.. If you want to “TeamView” I can take a look. Send ID to injection at johnholdsworth.com

blommegard commented 8 years ago

Segfaults in the command line as well, removing -filelist and the argument, in my case /var/folders/bh/z66b6cjn42q884slml0fjd7h0000gn/T/sources-bba41b seems to work.

Cant seem to find that much info about that switch anywhere, what does it do?

I you think a TeamView session might help we can set that up!

johnno1962 commented 8 years ago

AFAIK -filelist is something new to swift rather than long lists of files for a target to be compiled together. Code is below, does contents of -filelist contain primary file?

static unsigned readFileList(std::vector<std::string> &inputFiles,
                             const llvm::opt::Arg *filelistPath,
                             const llvm::opt::Arg *primaryFileArg = nullptr) {
  bool foundPrimaryFile = false;
  unsigned primaryFileIndex = 0;
  StringRef primaryFile;
  if (primaryFileArg)
    primaryFile = primaryFileArg->getValue();

  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
      llvm::MemoryBuffer::getFile(filelistPath->getValue());
  assert(buffer && "can't read filelist; unrecoverable");

  for (StringRef line : make_range(llvm::line_iterator(*buffer.get()), {})) {
    inputFiles.push_back(line);
    if (foundPrimaryFile)
      continue;
    if (line == primaryFile)
      foundPrimaryFile = true;
    else
      ++primaryFileIndex;
  }

  if (primaryFileArg)
    assert(foundPrimaryFile && "primary file not found in filelist");
  return primaryFileIndex;
}
blommegard commented 8 years ago

/var/folders/bh/z66b6cjn42q884slml0fjd7h0000gn/T/sources-bba41b doesn't seem to exists at all, and I suppose thats the reason it crashes. The path is the same across multiple injections at least.

johnno1962 commented 8 years ago

Yes, it’s only created on the fly which is a problem for injection. I’m afraid you’ll need to hive some of your main target off into a framework so the file list remains on the command line if you need to continue using injection :(

diegomontoyas commented 8 years ago

Thank you very much for the quick response. If I can be of any help I'm also ready.

johnno1962 commented 8 years ago

It seems like the maximum number of swift files per target is 128 to be able to use injection. After that Xcode 7.3 uses the -filelist option. Consolidating sources or moving some into a framework is the only way I can think of around this. Thanks the report. I may raise a radar to see if this limit can be raised.

pridra commented 8 years ago

If you change line 43, can you make it work? i haven't tried though... https://github.com/apple/swift/blob/master/lib/Driver/ToolChains.cpp

johnno1962 commented 8 years ago

Interesting, Thanks! I imagine that is where the tweak needs to go. “Blame” traces the fix to this issue: https://bugs.swift.org/browse/SR-280 (>1500 Swift files!) Perhaps this could be upped to 256 or 512… Anybody want to file a PR? Probably too late for Swift 2.2 though.

JakeSc commented 8 years ago

I'm seeing this issue as well. The swift compile command crashes when run in the command line, and Injection Plugin.

kaustubhkabra commented 7 years ago

@JakeSc Is this still an open issue ? My project has 1200 files, out of which about 200 would be swift. Any quicker workaround apart from creating multiple targets ?

JakeSc commented 7 years ago

I haven't run this plugin on Xcode 8 @kaustubh-kabra, so I can't answer that.

zenangst commented 7 years ago

Seeing the same issue here using Xcode 8 with a project that contains 320 swift files.

johnno1962 commented 7 years ago

I’ll raise a PR to see if I can get the limit raised to 512 and see if we can get it merged.

kaustubhkabra commented 7 years ago

Please do - it is rendering the plugin of no further help.

On Thu, Nov 10, 2016 at 3:33 PM, John Holdsworth notifications@github.com wrote:

I’ll raise a PR to see if I can get the limit raised to 512 and see if we can get it merged.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/johnno1962/injectionforxcode/issues/114#issuecomment-259799588, or mute the thread https://github.com/notifications/unsubscribe-auth/AAnOgt_sN-T-zw1iq7sPzPw0VdhbCGC-ks5q83-LgaJpZM4H7-rk .

zenangst commented 7 years ago

Trying to build my own Xcode toolchain now based of the Swift 3.0.1 with the value set to 512 just to confirm if it works or not.

johnno1962 commented 7 years ago

Great, thanks @zenangst, that’s a big help!

zenangst commented 7 years ago

Man... this take a lot of time, still compiling 😁

kaustubhkabra commented 7 years ago

Yeah, can easily make coffee by then :D

stephensilber commented 7 years ago

@zenangst if that were to work (which would be huge for the project I'm working on!), what's involved with swapping toolchains for Xcode?

zenangst commented 7 years ago

Well, install the toolchain and tell Xcode to use it 😁

stephensilber commented 7 years ago

@zenangst did changing 128 --> 512 in the toolchain end up working?

zenangst commented 7 years ago

I've been unable to build the 3.0.1 version of Swift so far. Struggling with the library ninja. I'll keep trying.

johnno1962 commented 7 years ago

I’ve looked into this some more and I’m not sure bumping that value up is such a good idea and come up with a differentt fix which I’ve just pushed.

Would someone like to rebuild their injection plugin from the new sources and give it a try? It’s just a script change so you won’t even need to restart Xcode!!

https://github.com/johnno1962/injectionforxcode/commit/9195fc7e77e5d4a9a2681d9fa36490a2bc2952ca

zenangst commented 7 years ago

@johnno1962 Trying it now, I'll keep you posted :)

zenangst commented 7 years ago

Still having issues with larger Xcode projects but now I'm getting a different error;

Injection log

Connection from: /Users/christofferwinterkvist/Library/Developer/CoreSimulator/Devices/5243D7F2-026A-4A2D-AB2D-440C0E9DA892/data/Containers/Data/Application/864CEFB6-B030-4017-ADE2-7E03997DA851 x86_64 (46)
buidRoot: /Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/Projectname-ftouyqybgvhfcpglpkrrvfgykuzj/Build
logDir: /Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/Projectname-ftouyqybgvhfcpglpkrrvfgykuzj/Logs/Build


*\ Could not locate compile command for Projectname/Source/Library/Extensions/SpotsController+Extension.swift


If you have switched xcode versions, please cmd-shift-k to clean then rebuild the project so there is a complete build history logged and try again.


/Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/Projectname-ftouyqybgvhfcpglpkrrvfgykuzj/Logs/Build/2A88B839-C07D-47EF-ADA7-CEBC00F010B4.xcactivitylog _

 at /XcodePath/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/common.pm line 57.
 main::error('Could not locate compile command for /Users/christofferwinter...') called at /XcodePath/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 269
_ Bundle build failed ***

I removed DerivedData before making a fresh build and tried to inject.

johnno1962 commented 7 years ago

You can’t inject extensions! What are the issues with the larger projects?

zenangst commented 7 years ago

The injection is only there to trigger the listener command. I get the same result if I try to inject views.

johnno1962 commented 7 years ago

I’m sorry I don’t understand what you are saying.. can you spell it out please

zenangst commented 7 years ago

Sorry for the confusion, I was not trying to inject the extension or expecting that to work. I just hit the inject button while having that file open. The extension, in my scenario, is only to add functionality like;

public func addInjection() {
  NotificationCenter.default.addObserver(self, selector: #selector(hasInjected), name: NSNotification.Name(rawValue: "INJECTION_BUNDLE_NOTIFICATION"), object: nil)
}

func hasInjected() {
  reload(dictionary)
}

Hope that clears up the confusion surrounding my previous comment.

But I do get the same result if I try to inject a view:

*\ Could not locate compile command for /PATH_TO_PROJECT/Source/Library/Spots/List/MenuCell.swift


If you have switched xcode versions, please cmd-shift-k to clean then rebuild the project so there is a complete build history logged and try again.
/Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/PROJECT-NAME-ftouyqybgvhfcpglpkrrvfgykuzj/Logs/Build/10072D3E-0E8D-452C-B425-52CA6F3BE67B.xcactivitylog /Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/PROJECT-NAME-ftouyqybgvhfcpglpkrrvfgykuzj/Logs/Build/DEF928C9-CD08-45C7-B2E1-FEDC33625D79.xcactivitylog /Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/PROJECT-NAME-ftouyqybgvhfcpglpkrrvfgykuzj/Logs/Build/993374EA-A409-4E69-964B-2669BC1AA461.xcactivitylog _

 at /XCODE-PLUGIN-FOLDER/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/common.pm line 57.
 main::error('Could not locate compile command for /Users/christofferwinter...') called at /XCODE-PLUGIN-FOLDER/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 269
_ Bundle build failed ***

johnno1962 commented 7 years ago

Strange. I’m not seeing a problem. Is the compile command for the file you are trying to inject in the Build logs for the project if you select them on the left hand side in Xcode? Is it in the same project?

zenangst commented 7 years ago

It has the target membership or maybe that's not what you meant? It is hard to find it in the build logs as it just make it into a one-liner.

screen shot 2016-11-13 at 11 51 49 screen shot 2016-11-13 at 11 15 13
johnno1962 commented 7 years ago

Is this to do with whole module optimisation/compilation perhaps? If it’s not in the logs you can’t inject. gunzip </Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/PROJECT-NAME-ftouyqybgvhfcpglpkrrvfgykuzj/Logs/Build/10072D3E-0E8D-452C-B425-52CA6F3BE67B.xcactivitylog to see whats actually in the logs that injection uses

zenangst commented 7 years ago

You are totally right, I had whole module optimization enabled. I disabled that and got a different error.

Connection from: /Users/christofferwinterkvist/Library/Developer/CoreSimulator/Devices/5243D7F2-026A-4A2D-AB2D-440C0E9DA892/data/Containers/Bundle/Application/15CF2897-92F6-4FD5-9BF6-5725AB19BA05/APP_NAME.app/APP_NAME x86_64 (29)
buidRoot: /Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/APP_NAME-ftouyqybgvhfcpglpkrrvfgykuzj/Build
logDir: /Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/APP_NAME-ftouyqybgvhfcpglpkrrvfgykuzj/Logs/Build




* Could not open filemap 'PROJECT_PATH

 at XCODE_PATH/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/common.pm line 57.
 main::error('Could not open filemap ×sers/christofferwinterkvist/Librar...') called at /XCODE_PATH/Xcode/Plug-ins/InjectionPlugin.xcplugin/Contents/Resources/injectSource.pl line 248
* Bundle build failed *

Any additional details that I can provide to further debug?

zenangst commented 7 years ago

I'm now perl expert but from some tiny tinkering, it looks like, and do correct me here if I'm totally wrong but, it cannot find the build folder because the application name contains a space.

My build folder looks like this:

/Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/APPNAME-ftouyqybgvhfcpglpkrrvfgykuzj/Build/Intermediates/APPNAME.build/Debug-iphonesimulator/APPNAME Staging.build

But it is trying to resolve:

/Users/christofferwinterkvist/Library/Developer/Xcode/DerivedData/APPNAME-ftouyqybgvhfcpglpkrrvfgykuzj/Build/Intermediates/APPNAME.build/Debug-iphonesimulator/APPNAMEStaging.build
johnno1962 commented 7 years ago

aha, escaping is always a problem. let me see if I can replicate this.

johnno1962 commented 7 years ago

I can inject ok with a space in the app name. How are you ending up with this path?

zenangst commented 7 years ago

Seems like there was a mismatch between the target name and the display name (don't know how they are connected). If I change them to match it worked! This on a project that has 320 swift files!!

Great job @johnno1962 ❤️

johnno1962 commented 7 years ago

Hallelujah! This is great news 👍 https://github.com/johnno1962/injectionforxcode/commit/9195fc7e77e5d4a9a2681d9fa36490a2bc2952ca

zenangst commented 7 years ago

@johnno1962 time to close this bad-boy and celebrate?

johnno1962 commented 7 years ago

Might as well. Apologies for your lost weekend recompiling Swift. This is a much better solution.

zenangst commented 7 years ago

Don't worry about it, I learned a lot in the process 😎