[fpc-devel] Building compiler, rtl, host, target... (cross compiling)
Skybuck Flying
skybuck2000 at hotmail.com
Thu Apr 7 03:06:21 CEST 2011
Ok,
I thought about it a bit and I think I now logically understand what's going
on and what needs to happen when one wants to build a new compiler, possibly
for cross compiling and such in relation to the RTL.
First of all "free pascal compiler" is not a "multi-target cross compiler"
but it is a "dual-target cross compiler" (dual meaning host and target can
be different ;))
So starting with the basics: Suppose somebody would get the free pascal
source codes only and now executables then that person would first need to
compile:
1. The compiler
and
2. The run time library
For let's say windows.
The compiler is a little bit like an application, applications need a system
unit, the runtime library provides that system unit.
However the "external/user compiler" might already have a system unit... so
for that purposes the "external/user compiler run time library/system unit
might be used". The free pascal compiler dependancies on it's own RTL could
be fixed/modified/temporarely changed to use the external compiler's system
unit to get the first compiler build working.
So step 1 would then produce:
A free pascal compiler executable which runs on windows.
The target to keep things easy was set to windows to first produce a "native
compiler" (which runs on windows and compiles to windows)
Now the mission/job/idea is to produce a cross-compiler which can
cross-compile to a new architecture/processor/platform let's called it
NewCPU and NewRTL in short: NewTarget.
Step 2 is a repeat of step 1. However it would be helpfull if the RTL itself
was also compileable to the new target... but let's see how far we can go
without it.
Step 2 specifies somehow to the build enviroment that the compiler sources
are to be re-compiled but this time the compiler which is build from it
should compile to the NewTarget... for that the new compiler needs "new
architecture support"... So that's where the new instructions and new
assembler come in... and perhaps new linker... but let's start with new
assembler and such...
Since the executable to be produced must still run on windows it can and
probably must still use the windows RTL to be able to produce the
executable.
If the same RTL was used to specify the target build... then it would be a
bit strange because then NewCPU would try to use a Windows RTL...
So this would then produce a "half-cross compiler" which would be kinda
funny... it would probably be "defunct"/"not working" perhaps such
executables produce by such a half compiler could be patched etc... but
that's probably a bit stupid to do.
What is needed is a "full-cross compiler" which also uses the NewRTL for the
NewPlatform.
Apperently specifieing the NewRTL can be done by compiler command line
options or configuration files.
Thus there are now probably two RTL's involved:
One RTL for the host, One RTL for the target.
How the compiler makes sense of this I am not yet sure... Perhaps it's a
question of linking in the NewRTL when a NewPlatform application is being
build by the new compiler.
So perhaps it's the "internal linker" which needs the NewRTL to be present
to do it's work ?!? How else could it work ??
However perhaps the new compiler also needs to do type checking against the
NewRTL for NewPlatform applications...
Thus somehow the new compiler must be using the new RTL.
The new RTL didn't exist yet... so it needs to be compiled.
Apperently this is where a "half-cross compiler comes in ?"
The new RTL cannot depend on "other platform RTL's" ?
So if I am correct in my assumption then the any RTL for that matter must be
"self-standing" and not rely on anything else except it's own platform that
it was written for.
It must also not depend on RTL functionality itself ?
How would otherwise a compiler be able to compile it ? (without creating
some kind of platform depedency)
So I guess this is where a "half-cross-compiler" comes in... The half-cross
compiler is capable of compiling a NewRTL and producing some kind of
assembly text which can then be used to compile the NewRTL to some kind of
binary (a pascal unit binary?)
This is perhaps where the linker also comes into play or maybe not...
Anyway once the NewRTL is compiled into pascal unit binaries it can be
used/include in a new compiler build.
So the compiler sources are again recompiled... but this time the compiler
sources are "told" or "modified via includes/search paths" to use the NewRTL
units so that it itself is compiled towards the new platform and uses the
new rtl for that platform.
This will then produce a "full cross compiler" which is capable of compiling
from running on host towards a target.
Once that's done... it's possible to recompile the compiler towards a native
compiler... produce native executable and native target (compilation
mode)... so that last step is the easy step.
So if I am correct "porting free pascal compiler and rtl towards a new
platform" requires the following steps:
1. Step 1 (preparing for first native free pascal compiler)
Install a "external pascal compiler" so that free pascal compiler sources
can be compiled.
(ignore free pascal's own rtl if necessary), make changes to the free pascal
compiler source code if necessary to use the external pascal compiler's RTL.
2. Step 2 (building free pascal compiler)
Build the free pascal compiler with the "external pascal compiler". This
produces a free pascal compiler executable for whatever platform step1 was
running on.
(These two steps can be skipped if "free pascal compiler executable" already
available (in this case external compiler=free pascal compiler executable))
3. Step 3 (building half-cross compiler)
Add new target's cpu instructions/assembler to free pascal compiler sources
so that the free pascal compiler can compile source code into free pascal
unit binaries.
Re-build the compiler. (This creates what I would call a "half-cross
compiler")
A half-cross compiler is a compiler which cannot yet produce
"target-executables" but it can produce "target-free pascal binary units".
(Seems to make logical sense: target-executables not yet possible because
target-rtl missing)
4. Step 4 (building full-cross compiler)
Add new target's rtl to free pascal compiler sources so that the free pascal
compiler can compile source into into target-(executable or
package/dll)-binaries.
Re-build the compiler and tell it to use the new-target's-rtl as it's uses
clausule. (This can be via "target-free pascal binary units in combination
with the interface" or simply new-target's RTL full source code, since the
compiler should now be able to handle/compile it.
This will produce a "full-cross compiler". The full cross compiler knows how
to compile towards target-cpu and it also knows how to use the target-rtl.
Optional repeating steps (fixing up):
These steps can then be repeated to undo the changes that where made at step
1, a native RTL could first be made which works with the native/external
compiler and perhaps with free pascal compiler itself as well.
Perhaps these steps are even manditory to be able to easily switch
targets... all code should in principe follow the same RTL layout/interfaces
;)
(But this might be conflicting with external compilers which already have
their own RTL, so that's why step1 might/would be necessary)
It might also be necessary to change all other target code's rtl's to use a
new-non-conflicting api/layout for external compilers.
5. Step 5 (building any native compiler)
Use the cross compiler to rebuild the free pascal compiler source codes.
Specify the target's cpu and target's rtl. (Which in this case should be the
cpu and rtl for which a native compiler should be build).
The reason for the native compiler is so that user's of this new target can
now be used to develop on itself... (assuming the target has such
capabilities)
(Some targets might not have such capabilities like embedded system, perhaps
console, gameboys, phones, refrigderators/whatever so form them step 4 is
already enough ;))
Missing from this list is ofcourse:
debuggers/cross debuggers which would still be needed for serious platform
development but that is beyond the scope of this posting ;)
And unfortunately me very little to almost no experience with writing
debuggers myself... perhaps a nice thing for me to explore in the future ;)
Bye,
Skybuck ;)
More information about the fpc-devel
mailing list