diff --git a/README.md b/README.md index a4caf53..a1ca0af 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ xcodemake -project YourApp.xcodeproj -scheme YourApp -destination 'platform=iOS * **What happens:** * It runs xcodebuild ... clean first. * It then runs xcodebuild ... build, capturing both standard output and standard error. - * The captured output is saved to a log file (e.g., xcodemake -project YourApp....log). + * The captured output is saved to a log file whose name is derived from the xcodebuild arguments, sanitized and suffixed with a short hash for uniqueness (e.g., xcodemake_-project_YourApp-.log). * It parses this log file. * It generates a Makefile in the current directory based on the parsed build commands. @@ -68,7 +68,7 @@ xcodemake is designed to automatically re-run the xcodebuild capture process and * If make fails, xcodemake will attempt to run xcodebuild directly. If *that* succeeds, it implies project changes necessitated a full rebuild, so xcodemake will re-capture the log and regenerate the Makefile before trying make one last time. ## How it Works -1. **Log Capture:** Executes xcodebuild clean followed by xcodebuild build [args...], piping the combined output (stdout & stderr) to both the terminal (like tee) and a log file (xcodemake [args...].log). It avoids using env -i to ensure xcodebuild runs in a standard environment. +1. **Log Capture:** Executes xcodebuild clean followed by xcodebuild build [args...], piping the combined output (stdout & stderr) to both the terminal (like tee) and a log file. The log file name is derived from the xcodebuild arguments, sanitized to remove path separators and other filesystem-unsafe characters, and suffixed with a short MD5 hash of the arguments for uniqueness. It avoids using env -i to ensure xcodebuild runs in a standard environment. 2. **Parsing:** Reads the generated log file line by line. 3. **Command Identification:** Looks for key lines indicating compilation or linking steps: * CompileC ...: For C, C++, Objective-C/C++ files. diff --git a/xcodemake b/xcodemake index 03c8b91..70fdf33 100755 --- a/xcodemake +++ b/xcodemake @@ -17,6 +17,7 @@ use IO::File; use strict; use JSON::PP; +use Digest::MD5 qw(md5_hex); my @original_ARGV = @ARGV; @@ -44,7 +45,18 @@ sub shellEscape { } # --- Global Variables --- -my $log = "xcodemake @original_ARGV.log"; +my $log_tag = join "_", ("xcodemake", @original_ARGV); +$log_tag =~ s{[/:]+}{_}g; +$log_tag =~ s{[^[:alnum:]._+=,@ -]+}{_}g; +$log_tag =~ s{\s+}{_}g; +$log_tag =~ s{_+}{_}g; +$log_tag =~ s{^_+|_+$}{}g; +$log_tag ||= "xcodemake"; +my $max_log_name_length = 150; +my $log_suffix = "-" . md5_hex(join "\0", @original_ARGV) . ".log"; +$log_tag = substr($log_tag, 0, $max_log_name_length - length($log_suffix)); +$log_tag =~ s{_+$}{}; +my $log = ($log_tag || "xcodemake") . $log_suffix; my $make = "Makefile"; my $xcodebuild = ($ENV{DEVELOPER_BIN_DIR}||'/usr/bin')."/xcodebuild"; @@ -321,6 +333,8 @@ HEADER escape("\$& ", $make_target_object); dollarEscape($make_dep_source); unescape("'", $make_dep_source); + unescape(" ", $make_dep_source); + escape(" ", $make_dep_source); # Add rule to Makefile print $make_fh "\n$make_target_object: $make_dep_source\n"; @@ -413,6 +427,8 @@ HEADER escape("\$& ", $make_target_object); dollarEscape($make_dep_source); unescape("'", $make_dep_source); + unescape(" ", $make_dep_source); + escape(" ", $make_dep_source); # Use make-escaped version for the hash key check next if $rules{$make_target_object}++; @@ -461,6 +477,8 @@ HEADER escape("\$& ", $make_target_object); dollarEscape($make_dep_source); unescape("'", $make_dep_source); + unescape(" ", $make_dep_source); + escape(" ", $make_dep_source); # Use make-escaped version for hash key check next if $rules{$make_target_object}++;