[fpc-devel] Cross compiling x86 on amd64, linking to crtbegin.o etc.

Konstantin newsbox1026 at web.de
Tue Jul 17 00:36:06 CEST 2012


Sven Barth schrieb:
> Am 11.07.2012 16:36, schrieb Konstantin:
>> Hello!
>>
>> Free Pascal has been designed to run on several platforms on many
>> architectures which is a neat feature. The executable name is chosen
>> accordingly - ppc386, ppcx64 etc. to be able to have many at the same
>> time on the same system. When building from source it automatically
>> detects the platform on which it is running. Unfortunately, when
>> building on amd64 you end up with the ppcx64 compiler which can not
>> compile for x86 targets.
>>
>> I'm using Free Pascal on Gentoo so I created ebuilds (see Gentoo bug
>> report here <https://bugs.gentoo.org/show_bug.cgi?id=322971>) to compile
>> FPC on amd64 machines for x86 as well if desired. Currently this
>> involves compiling everything twice and then install it together. This
>> way the advantage of the CPU to be able to run code in 32 bit and 64 bit
>> on the same system can be used.
>>
>> So first question, is there a better way instead of compiling everything
>> twice? Maybe something can be reused?
>
> I'm not used to Gentoo's ebuilds, so I'll tell you from FPC's normal
> perspective:
>
> if you do a "make all CPU_TARGET=i386" on a x86_64 Linux system then a
> x86_64 -> i386 cross compiler will be created with default system
> Linux and where the compiler binary will be called ppcross386 (instead
> of ppc386). [It works similar on Windows, other targets and other CPUs
> with the only exception that most non-i386 systems can not cross
> compile to i386, because of the missing Extended support; x86_64 on
> non-Windows can though] Only problem might be that the build process
> and/or the compiler does not find the correct binutils, so you might
> need to help it using BINUTILSPREFIX (e.g.
> "BINUTILSPREFIX=i686-linux-") and CROSSBINDIR (e.g.
> "CROSSBINDIR=/opt/gcc32" {just an example}). The crosscompiled
> compiler (and its units) is then installed using "make crossinstall
> CPU_TARGET=i386 INSTALL_PREFIX=/whereever/you/want".
Thanks for the information. Just a note - the Gentoo ebuilds are a kind
of compile and install scripts similar to shell scripts so even when
you're not used to they are easy to understand if you are familiar with
the compile and install process of a specific software.

I played around a bit to see what happens. On my x86_64 system i get it
compiled using the following:

make all CPU_TARGET=i386 BINUTILSPREFIX=x86_64-pc-linux-gnu-

So the answer to my first question is apparently: no, it must be
compiled twice.

The resulting ppcross386 seems to generate 32 bit code as ppc386 does on
a native system but there the same problem appears regarding my second
question - the resulting program can not be linked as in link.res
absolute paths are used for crti.o and crtn.o. Here the messages:

Linking program
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
/usr/bin/ld: skipping incompatible /usr/lib/crti.o when searching for
/usr/lib/crti.o
/usr/bin/ld: skipping incompatible /usr/lib/crti.o when searching for
/usr/lib/crti.o
/usr/bin/ld: cannot find /usr/lib/crti.o
vdim.pas(17,2) Error: Error while linking
vdim.pas(17,2) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted

I checked where this comes from and found, that in
compiler/systems/t_linux.pas the function TLinkerLinux.WriteResponseFile
generates the linker response file  link.res where it gives absolute
paths of [crtbegin.o,] crti.o, [crtend.o] and crtn.o. The bad thing is
that these paths are determined by the FPC function
librarysearchpath.FindFile and as this function does not honor the
target architecture. It always returns /usr/lib/..... as the default
architecture version of these files is located there. This of course
fails when compiling 32 bit on a 64 bit Gentoo machine where the 32 bit
versions are in /usr/lib32/..... and linking fails due to invalid files.

So again my second question is, why are absolute paths used for
crtbegin.o, crti.o, crtend.o and crtn.o? When no paths are specified the
linker automatically chooses the right version and everything it seems
to be OK. Is there any need for absolute paths?

I made a patch for this
https://bugs.gentoo.org/attachment.cgi?id=317900&action=diff to specify
the object files without paths. It would be nice to have a solution and
Gentoo devs would like to know from upstream what the "right" solution
for this linking issue is. You are welcome to add comments to the Gentoo
bug report above.

Have a nice day,
Konstantin




More information about the fpc-devel mailing list