Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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-<hash>.log).
* It parses this log file.
* It generates a Makefile in the current directory based on the parsed build commands.

Expand All @@ -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.
Expand Down
20 changes: 19 additions & 1 deletion xcodemake
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use IO::File;
use strict;
use JSON::PP;
use Digest::MD5 qw(md5_hex);

my @original_ARGV = @ARGV;

Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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}++;
Expand Down Expand Up @@ -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}++;
Expand Down