Fix for Xcode dependency problems
Fix for Xcode dependency problems
- Subject: Fix for Xcode dependency problems
- From: John Daniel <email@hidden>
- Date: Sat, 24 Jun 2006 22:25:40 -0500
Hello,
I have been struggling lately with getting Xcode dependencies
working. I have an application that uses two static library projects.
When I change a header file in a subproject, dependent files in my
application project do not get rebuilt. This seems to be a common
problem that doesn't have a workable solution, so I wrote one.
To get this to work, create a new "run script" target. The script to
add is at the end of this message. Add this target as a dependency to
your application target. This is necessary to get the script to run
before Xcode tries to calculate its own dependencies.
The script uses the "makedepend" tool to generate a makefile for all
dependencies in your project. This tool is currently squirreled away
in /usr/X11R6/bin, so I guess you need X11 too. The script continues
and fixes said makefile so it is usable. Then it makes the makefile.
If it finds that an object file needs to be rebuilt, it will delete
that object file. Then, Xcode will rebuild it.
You have to change the first variable in the script to be the real
name of the associated application target. If you have multiple
application targets, as I do, you will need multiple dependency
targets. If anyone finds any bugs or has ideas about how to improve
this script, I would be most appreciative. Maybe someone at Apple
will be inspired enough to fix Xcode's dependency calculation.
John Daniel
#!/usr/bin/perl
use POSIX;
# For debug, fake these out.
#$ENV{CURRENT_ARCH}='ppc';
#$ENV{BUILD_VARIANTS}='normal';
#$ENV{CONFIGURATION_TEMP_DIR}='/Programming/MyApp/build/MyApp.build';
#$ENV{USER_HEADER_SEARCH_PATHS}='/Programming/MyApp/../Lib1 /
Programming/MyApp/../Lib2';
# Change this for each dependency target. THIS IS THE ONE TO CHANGE!!!!
my $targetBuildPath='MyApp (Universal Debug).build';
# Get my user search path.
my @searchPaths = grep s/(.*)/-I\1/, split ' ', $ENV
{USER_HEADER_SEARCH_PATHS};
# Get my object file directory.
my $objectFileDir = "$ENV{CONFIGURATION_TEMP_DIR}/$targetBuildPath/
Objects-$ENV{BUILD_VARIANTS}";
# Get my current architecture.
my $currentArch = $ENV{CURRENT_ARCH};
# Get my source files.
my @sourceFiles = grep /\.c$|\.cc$|\.cpp$|\.c\+\+$|\.C$|\.CC$|\.m$|
\.mm/, `find .`;
# Get rid of line endings.
chomp @sourceFiles;
# Define my prefix and suffix.
my $prefix = "$objectFileDir/$currentArch/";
my $suffix = '.o';
my $escapedPrefix = $prefix;
# Get rid of any special characters.
$escapedPrefix =~ s/(\s)/\\\1/g;
#$prefix =~ s/(\(|\))/\\\1/g;
my $makefile = tmpnam();
# Make sure I have an empty makefile.
system "touch $makefile";
# Build the makefile.
system "/usr/X11R6/bin/makedepend -f$makefile -a -o$suffix
@searchPaths @sourceFiles >& /dev/null";
# Now fix the makefile. What makedepend generates doesn't seem to be
usable.
# Slurp up the makefile.
my $oldsep = $/;
undef $/;
open(IN, $makefile) or die "Can't open $makefile for reading\n";
my $makefileData = <IN>;
close(IN);
$/ = $oldsep;
# Extract all the dependencies from the makefile.
my @elements = $makefileData =~ /^([^:]+):([^\n]*)$/gsm;
# Put the dependencies into a hash so the targets are unique.
my %targets;
while(my $element = shift @elements)
{
my ($target) = $element =~ /(?:.*\/)?(.*)$/;
my $prerequisites = shift @elements;
my @prerequisites = split ' ', $prerequisites;
# Put the prerequisites into a hash so they are unique too.
foreach my $prerequisite (@prerequisites)
{
$targets{$target}->{$prerequisite} = 1;
}
}
# Create the new makefile.
open(OUT,">$makefile") or die "Can't open $makefile for writing\n";
my @objectFiles = keys %targets;
print OUT "OBJS=@objectFiles\n\n";
print OUT "all: \$(addprefix $escapedPrefix, \$(OBJS))\n\n";
print OUT $rules;
while(my ($target, $prerequisites) = each %targets)
{
print OUT "$escapedPrefix$target :";
while(my ($prerequisite, $junk) = each %{$prerequisites})
{
print OUT " $prerequisite";
}
print OUT "\n\trm -f '$prefix$target'\n\n";
}
close(OUT);
# Now run make.
system "make -f $makefile";
unlink $makefile;
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden