Xcode 2.1 building using an external compiler: solution
Xcode 2.1 building using an external compiler: solution
- Subject: Xcode 2.1 building using an external compiler: solution
- From: Jonas Maebe <email@hidden>
- Date: Mon, 20 Jun 2005 15:46:47 +0200
Hello,
I sent the mail below yesterday to the MacPascal list. One important
thing I forgot to mention: turn off zerolink, or it won't work. The
information below can in principle be used for any compiler which has
built-in make-like functionality (i.e., you pass it the main file and
it will sort out the dependencies by itself).
I've filed a bug about custom scripts not being called during
cleaning. If someone has a solution for that, I'd be glad to hear it.
I think it's also curious that this $(PROJECT_TEMP_DIR) is never ever
cleaned by Xcode, in spite of what the name of this variable implies.
That said, please do *NOT* add functionality to Xcode that cleans
this directory after every build, or my hacks below will no longer
work (unless you can provide a better way to make two targets
communicate with each other over the course of different builds.
Jonas
I've finished the Xcode 2.1 build rules. It uses two targets: one for
the main program file, and one for the units (on which the main
target depends). You have add all units to that units target, that's
the only hard part. Some problems I encountered:
a) FPC internally still uses regular (255 char) Pascal strings
internally, and Xcode generates quite deeply nested directory
structures. I solved this by changing the current working directory
to the directory in which the object files have to be generated.
b) getting XCode to recompile the main program if a unit has been
changed. I did this by creating a file at $PROJECT_TEMP_DIR/mainfile
with the name of the main program file inside the script which
compiles the main file. The units target rule simply checks if this
$PROJECT_TEMP_DIR/mainfile exists and if so, gets the contents of
that file and touches the actual main file. This will then trigger a
recompilation of it. If you rename the main file, you will have to
clean the project before you can build again though. The first time
you build the program this file won't exist, but that doesn't matter
since then the main file will be compiled anyway.
c) getting Xcode to link everything. I tell FPC to omit the linking
state (-Cn), add the names of all generated objects from the
generated link.res file to Xcode's LINK_FILE_LIST_... file. Now, to
make Xcode to actually link something, I specify "$
(DERIVED_FILES_DIR)/dummy.s" as output file from the build rule of
the main program, and create this file using 'touch
"$DERIVED_FILES_DIR"/dummy.s' in the script that builds the main
program.
The nice thing about Xcode doing the linking is that you can add
libraries and frameworks using the Xcode gui.
d) automatically passing all necessary unit paths to the compiler.
What I did was in the build rules of unit sources, add
echo \"-Fu$INPUT_FILE_DIR\" >> "$PROJECT_TEMP_DIR"/unitpaths
(the extra \" are to support unit file paths with spaces in the name)
In the build rule of the main program, I remove all duplicate lines
from that file. Pass its contents to the compiler was hard however,
because if you put the contents of that file on one line, put it in a
variable and then passed it to the compiler using something like
$UNIT_PATHS, the shell replaced things like
"-Fu/Data test/"
with (I hope you are using a fixed width font to read this)
'"-Fu/Data' 'test/"'
That's wrong of course. So what I did was create script with the
compiler command line in it, then echoed all unit search paths (with
proper quotes) into that file as well and finally executed that file.
There's one problem left: this $PROJECT_TEMP_DIR nor its contents are
ever deleted by Xcode, in spite of what the name implies. This means
that if you remove the last file from a certain directory from the
project, this directory will still be searched by the compiler. This
can possibly lead to very hard-to-find errors.
The documentation states that scripts are triggered during a clean
phase, but that is not the case, so I cannot use that either to
delete that file. I have not yet been able to come up with a way to
delete this file at a proper stage. Deleting it after a build has
completed is wrong, because if you afterwards change a unit on which
other units depend, the search paths to these other units are needed
as well.
Maybe the only way for now is to add a custom target "clean unit
search paths" or so, which when you build it, deletes that file.
Build rule for Pascal files in units target:
# trigger recompilation of the main file
mkdir -p "$PROJECT_TEMP_DIR"
if test -f "$PROJECT_TEMP_DIR/mainfile"
then
touch `cat "$PROJECT_TEMP_DIR/mainfile"`
fi
echo \"-Fu$INPUT_FILE_DIR\" >> "$PROJECT_TEMP_DIR"/unitpaths
With output file "$(PROJECT_TEMP_DIR)/unitpaths" (not sure if that's
necessary).
I've attached the build rule for the Pascal files in the main target,
to preserve the formatting. That one has, as explained earlier, one
output file called "$DERIVED_FILES_DIR"/dummy.s"Attachment:
rule.sh
Description: Binary data
_______________________________________________
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