Skip to content

Instantly share code, notes, and snippets.

@rodionovd
Last active August 29, 2015 14:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rodionovd/f9b18bbbd98e9623bffc to your computer and use it in GitHub Desktop.
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)
#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