[Solved] Re: Building a class hierarchy in Xcode
[Solved] Re: Building a class hierarchy in Xcode
- Subject: [Solved] Re: Building a class hierarchy in Xcode
- From: Olivier Scherler <email@hidden>
- Date: Thu, 12 Aug 2004 02:13:02 +0200
Cross post from the Java Dev list.
> Olivier Scherler <email@hidden> wrote:
>
> >I am using a shell script build phase *after* the usual Java build
> >phase, to generate a TINI executable out of the class files for the
> >TINI. Due to very limited resources, the TINI does not execute class
> >or jar files but a special, very stripped down kind of file. The
> >normal (manual) compilation process is therefore:
> >
> > javac -target 1.1 -d classes sources/*.java java TINIConvertor -f
> > classes -o tinifile.tini
> >
> >I'm using a shell build phase only for the second step.
> >
> >For this, I need Xcode to give me a class hierarchy. Therefore, I
> >configured the standard Java target to not make a jar file (Java
> >Archive Settings -> Product type -> Class hierarchy). But the
> >classes are not updated when I modify the sources and rebuild the
> >project.
>
> BTW, my guess is that the class-files you're running TINIConvertor on
> aren't the latest ones compiled, but are leftovers from some other part of
> the XCode build. To track the problem down, you'll have to look into the
> details of XCode's build-system, especially how it uses build-variables
> (basically, env-vars) to decide where to put files and such:
>
<http://developer.apple.com/documentation/DeveloperTools/Conceptual/Build_System
/>
Thanks for the pointer, that was an interesting read. I think I now understand
what's happening.
I used xcodebuild in the shell to watch the built in more details. Here's the
parts I found interesting:
/usr/bin/javac [...] -sourcepath [...]/TINITim/. -classpath
/"$classpath" -d /"[...]/TINITim/build/TINITim.build/TINITim.build/
JavaClasses" /'TINITim.java'
-> Classes are compiled in build/PROJECT_NAME.build/TARGET_NAME.build/
JavaClasses, a.k.a. CLASS_FILE_DIR. These are always up to date.
BuildPhase <JavaArchiveFiles>TINITim
echo Completed phase "<JavaArchiveFiles>" for
"<JavaArchiveFiles>TINITim"
Completed phase <JavaArchiveFiles> for <JavaArchiveFiles>TINITim
Mkdir [...]/TINITim/build/TINITim
/bin/mkdir -p [...]/TINITim/build/TINITim
Ditto [...]/TINITim/build/TINITim
/usr/bin/ditto [...]/TINITim/build/TINITim.build/TINITim.build/
JavaClasses [...]/TINITim/build/TINITim
-> This step copies the class files in build/TINITim if I chose to make a class
hierarchy instead of a jar file. When I build the project again, however, it is
NOT executed. It looks like a bug.
Grepping for ditto in /Developer unveiled this interesting file:
/Developer/Makefiles/pbx_jamfiles/ProjectBuilderJambase
It looks like the instructions for Xcode on how to build a project. The
following bit looks strangely familiar:
if $(JAVA_ARCHIVE_CLASSES) != YES {
# !!!:cmolick:20020123 product class file dir not always made?!
Mkdir $(PRODUCT_CLASS_FILE_DIR) ;
ProductFile $(PRODUCT_CLASS_FILE_DIR) ;
Ditto $(PRODUCT_CLASS_FILE_DIR) : $(CLASS_FILE_DIR) ;
if $(MERGED_ARCHIVES) {
DEPENDS $(PRODUCT_CLASS_FILE_DIR) : $(MERGED_ARCHIVES) ;
}
else {
DEPENDS $(PRODUCT_CLASS_FILE_DIR) : $(JAVA_COMPILE_TARGET) ;
}
}
It's the ditto instruction that's playing hide and seek with us. Apparently,
it's been bothering someone for a long time too:
# !!!:cmolick:20020123 product class file dir not always made?!
I figured out that Mkdir was interrupting the process if the directory it's
supposed to create already exists. Indeed, removing the directory was enough to
make the ditto step run once more. Emptying the directory, however, was not
sufficient.
Now here's the definition for Mkdir:
# Mkdir <directory>
# Creates <directory>
rule Mkdir
{
# Only existence of the directory matters
NOUPDATE $(1) ;
}
actions together piecemeal Mkdir
{
$(MKDIR) -p $(1:Q)
}
I don't know this language so I have no idea what this means, except that it
runs "mkdir -p arg" to create a directory. But I can guess from the comments
that the first part makes it do nothing if the directory already exists. This
"do nothing" seems to be the culprit. I could have removed it but I found it
cleaner to define a new action for this particular case. There's nothing but
programmers on this list so I will spare you the "make sure you backup the files
you modify" bit.
1. In the first snippet above (line 4269), change
Mkdir $(PRODUCT_CLASS_FILE_DIR) ;
to
ForceMkdir $(PRODUCT_CLASS_FILE_DIR) ;
2. Next, define ForceMkdir (e.g. at line 310):
# ForceMkdir <directory>
# Creates <directory>, even if it already exists.
#
# This modification if for the Ditto step that copies class files in Java
# projects. The original Mkdir action above seems to prevent ditto from
# executing when the directory already exists.
#
# Fix on 2004-08-12 by Olivier Scherler, who's quite proud of having fixed a
# glitch in a program written in a language he does not even know the
# name of.
actions together piecemeal ForceMkdir
{
$(MKDIR) -p $(1:Q)
}
Tadam, the classes are now copied every time the project is built.
Should I inform someone in particular about this?
Olivier
bB Unicode Ribbon CampaignB b No ASCII, anywhereB b
bB <http://ithink.ch/unicode> B b
:: Olivier Scherler :: NeuchC"tel - Switzerland :: http://ithink.ch/blog/ ::
_______________________________________________
xcode-users mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/xcode-users
Do not post admin requests to the list. They will be ignored.