Last active
August 29, 2015 14:04
-
-
Save rodionovd/f9b18bbbd98e9623bffc to your computer and use it in GitHub Desktop.
Xcode plugin snippet for dumping compiler/linker arguments for the given file(s)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <objc/runtime.h> | |
void dump_compiler_and_linker_args_for_file(NSString *file) | |
{ | |
Class PBXReference = NSClassFromString(@"PBXReference"); | |
if (! PBXReference) return; | |
id file_ref = [[PBXReference alloc] initWithPath: file]; | |
Class PBXProject = NSClassFromString(@"PBXProject"); | |
if (! PBXProject) return; | |
id suggested_targets = [PBXProject performSelector: NSSelectorFromString(@"targetsInAllProjectsForFileReference:justNative:") | |
withObject: file_ref | |
withObject: nil]; | |
// If you want to iterate all targets within a project, use smth like this: | |
// ----------------- CUT HERE ----------------- | |
// id open_projects = [PBXProject performSelector: NSSelectorFromString: @"openProjects"]; | |
// [open_projects enumerateObjectsUsingBlock:^(id project, NSUInteger idx, BOOL *stop) | |
// { | |
// id all_targets = [project valueForKey: @"_targets"]; | |
// [all_targets enumerateObjectsUsingBlock:^(id target, NSUInteger idx, BOOL *stop) | |
// { | |
// id build_context = [target performSelector: NSSelectorFromString(@"targetBuildContext")]; | |
// // dealing with a context (see below) | |
// } | |
// } | |
// ----------------- CUT HERE ----------------- | |
// But that's just a demo, so don't bother | |
id target = suggested_targets[0]; | |
id build_context = [target performSelector: NSSelectorFromString(@"targetBuildContext")]; | |
NSArray *commands = [build_context performSelector: NSSelectorFromString(@"commands")]; | |
[commands enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) | |
{ | |
NSArray *rule_info = [obj performSelector: NSSelectorFromString(@"ruleInfo")]; | |
// Dump compiler arguments for the file | |
if ([[rule_info firstObject] isEqualToString: @"CompileC"]) { | |
/** | |
* Commands can contain build rules for multiple files so | |
* make sure we got the right one. | |
*/ | |
NSString *sourcefile_path = [rule_info objectAtIndex: 2]; | |
if ( ! [sourcefile_path isEqualToString: file]) { | |
return; | |
} | |
NSString *compiler_path = [obj valueForKey: @"_commandPath"]; | |
NSArray *compiler_args = [obj valueForKey: @"_arguments"]; | |
NSLog(@"\nCompile file '%@' with command line:\n%@ %@", | |
[sourcefile_path lastPathComponent], [compiler_path lastPathComponent], | |
[compiler_args componentsJoinedByString:@" "]); | |
} | |
// Linker arguments | |
if ([[rule_info firstObject] isEqualToString: @"Ld"]) { | |
/* | |
* Xcode doesn't pass object files (.o) directly to the linker (it uses | |
* a dependency info file instead) so the only thing we can do here is to grab | |
* the linker arguments. | |
*/ | |
NSString *linker_path = [obj valueForKey: @"_commandPath"]; | |
NSArray *linker_arguments = [obj valueForKey: @"_arguments"]; | |
NSLog(@"\nLinker: %@ %@", [linker_path lastPathComponent], [linker_arguments componentsJoinedByString: @" "]); | |
} | |
}]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment