Building freetype2 (cross-compiling for i686-elf)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
max
Member
Member
Posts: 616
Joined: Mon Mar 05, 2012 11:23 am
Libera.chat IRC: maxdev
Location: Germany
Contact:

Building freetype2 (cross-compiling for i686-elf)

Post by max »

Hey guys,

as I've noticed that some of you have issues building freetype2 for their userspace, I'd like to open this thread for finding solutions/discussing.

This is how I built it, maybe you'll find differences to how you did it and can solve the problems yourself.
- my environment for this build was cygwin
- using a OS specific toolchain
- building freetype 2.5.3 (get the .tar.gz)

To build freetype2, all you really need to do is:

Code: Select all

tar -xf freetype-2.5.3.tar.gz
mkdir build-freetype
cd build-freetype

export PREFIX=/your/preferred/path
# insert your toolchain variables here
export CC=i686-ghost-gcc
export CXX=i686-ghost-g++
export LD=i686-ghost-ld
export CPP=i686-ghost-cpp
export AR=i686-ghost-ar
export AS=i686-ghost-as

../freetype-2.5.3/configure --host=i686-elf --without-zlib --with-png=no --prefix=$PREFIX
make all
make install
Now the library is installed to the prefix folder and can be used from there.

Notes:
- you should really use tar to untar the tarball, as the archive is a little weird and other programs produce stuff that just wont work
- the only thing freetype depends on is a working C library, I strongly suggest building a toolchain specific for your OS (it will make your life soo much easier)

So, post your problems and maybe we'll find a solution :)

Pic: my first .ttf file loaded in my UI, well I could use some alpha in my rendering :mrgreen:
Image

Greets, Max
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Building freetype2 (cross-compiling for i686-elf)

Post by sortie »

Hi max,

Beware - you are not experienced in cross-compiling software. You make some rookie mistakes when cross-compiling that will cause issues later on (perhaps only in some packages).

First, you can't cross-compile user-space software to i686-elf as it is a bare target without a standard library. You know this and made your custom i686-ghost target, this is very well. But you still pretend you are i686-elf when you are cross-compiling. That's wrong. Use the same tricks taught in the OS specific toolchain tutorial and patch the config.sub file to know about your OS (you can often find it in a subdirectory like build-aux). Then you pass --host=i686-ghost instead. You should never mention the -elf targets, you are not using those. This also means you have no need to (and perhaps shouldn't) set the CC variables as the configure script can figure it out on your own (you may actually wish to unset CC in case you set it yourself to a local compiler).

Mind that patching config.sub is a necessary evil and it's perfectly alright. You need to be able to have local patches for all the software you ported. I have a pretty big set of patches at this point. :)

Secondly, the --prefix=/foo is where the library will be at runtime. That means the library expects to find itself (and its datafiles) when running on your operating system at /foo/lib and /foo/share/package-name. A lot of packages remember the prefix in this fashion. When cross-compiling the place the software ultimately ends up is not where the software gets installed. Instead, you put all the cross-compiled software into the system root (sysroot, where you set your cross-compiler --with-sysroot to).

The correct way would be something like:

Code: Select all

tar -xf freetype-2.5.3.tar.gz
mkdir build-freetype
cd build-freetype

../freetype-2.5.3/configure --host=i686-ghost --prefix=/usr --without-zlib --with-png=no
make
make install DESTDIR=$SYSROOT
Perhaps I should write a wiki article on how to do this stuff properly. I see a lot of people getting this stuff wrong.
User avatar
max
Member
Member
Posts: 616
Joined: Mon Mar 05, 2012 11:23 am
Libera.chat IRC: maxdev
Location: Germany
Contact:

Re: Building freetype2 (cross-compiling for i686-elf)

Post by max »

sortie wrote:Beware - you are not experienced in cross-compiling software. You make some rookie mistakes when cross-compiling that will cause issues later on (perhaps only in some packages).
You are absolutely right :mrgreen:
sortie wrote:First, you can't cross-compile user-space software to i686-elf as it is a bare target without a standard library. You know this and made your custom i686-ghost target, this is very well. But you still pretend you are i686-elf when you are cross-compiling. That's wrong. Use the same tricks taught in the OS specific toolchain tutorial and patch the config.sub file to know about your OS (you can often find it in a subdirectory like build-aux). Then you pass --host=i686-ghost instead. You should never mention the -elf targets, you are not using those. This also means you have no need to (and perhaps shouldn't) set the CC variables as the configure script can figure it out on your own (you may actually wish to unset CC in case you set it yourself to a local compiler).

Mind that patching config.sub is a necessary evil and it's perfectly alright. You need to be able to have local patches for all the software you ported. I have a pretty big set of patches at this point. :)
Aaaah okay, that sounds a lot more "right" than how I managed to build it :D I'll take a deeper look into that
sortie wrote:Secondly, the --prefix=/foo is where the library will be at runtime. That means the library expects to find itself (and its datafiles) when running on your operating system at /foo/lib and /foo/share/package-name. A lot of packages remember the prefix in this fashion. When cross-compiling the place the software ultimately ends up is not where the software gets installed. Instead, you put all the cross-compiled software into the system root (sysroot, where you set your cross-compiler --with-sysroot to).
But, when the library is static and independent of where it runs, this shouldn't matter, right?
I don't have a sysroot because this structure does not exist on my target system as it is not unix-like.. but okay, I could for example give it the prefix /libraries/somelib when building, and put it there on the OS's filesystem, then it would work
sortie wrote:Perhaps I should write a wiki article on how to do this stuff properly. I see a lot of people getting this stuff wrong.
that would be awesome, and I think you could help quite a lot people with that :)

Thank you sortie! :)

EDIT: Wuza, edited the config.sub, now it builds just as you said. :mrgreen: Also created a patch to reproduce it.. easier than I thought :P
Peterbjornx
Member
Member
Posts: 116
Joined: Thu May 06, 2010 4:34 am
Libera.chat IRC: peterbjornx
Location: Leiden, The Netherlands
Contact:

Re: Building freetype2 (cross-compiling for i686-elf)

Post by Peterbjornx »

In reply to sortie: you really should write that guide, I could have used one when I was porting software for the first time, at the moment I am using a hackish way too but it is atleast a little bit cleaner than his trick ;)

To max: Great to see someone else working on a userland GUI and porting libs, also, I think it is quite impressive that you got this far using cygwin, It is a nice platform but (in my experience) got too many weird quirks to work properly for OSDev, then again, last time I tried that was back in '09
User avatar
max
Member
Member
Posts: 616
Joined: Mon Mar 05, 2012 11:23 am
Libera.chat IRC: maxdev
Location: Germany
Contact:

Re: Building freetype2 (cross-compiling for i686-elf)

Post by max »

Peterbjornx wrote:To max: Great to see someone else working on a userland GUI and porting libs, also, I think it is quite impressive that you got this far using cygwin, It is a nice platform but (in my experience) got too many weird quirks to work properly for OSDev, then again, last time I tried that was back in '09
Thank you! :) saw your stuff in the screenie-thread, really nice progress too!

I only work with cygwin when I have no real OS at hand :mrgreen: its really not as horribly (maybe, anymore) as it seems to be, it has some pitfalls (remove goddamn MinGW, or you'll cry trying to build a cross-GCC because the config-scripts may secretly use MinGW's binaries), but it does what it should. ;)
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Building freetype2 (cross-compiling for i686-elf)

Post by sortie »

Hi,

I wrote that guide: http://wiki.osdev.org/Cross-Porting_Software

It covers the basic template for cross-building autoconf-based packages properly and reliably in an ideal world. It then proceeds to list a lot of problems that happens in the real world and how you can fix software to avoid them. There's a nice list of tricks here. If you run into some odd problems in packages not covered here, check my patch collection or ping me, and I'll document how to resolve such broken packages.
max wrote:But, when the library is static and independent of where it runs, this shouldn't matter, right?
It does matter, for instance if the library needs configuration files or data files. In general it matters, but in a few simple libraries it might not (but it's hard to know). It's not too much trouble to do things properly.
max wrote:I don't have a sysroot because this structure does not exist on my target system as it is not unix-like.. but okay, I could for example give it the prefix /libraries/somelib when building, and put it there on the OS's filesystem, then it would work
You should. It could be pretty bare, /usr/lib and /usr/include. This place is pretty much just where your compiler normally looks for things. Surely you use --with-sysroot when building your OS-specific toolchain (having installed your standard library headers there ahead of time) - that's the right way to do things. You can customize where ld looks for libraries and gcc looks for headers. Ping me if you want to see how I customize that to /include and /$HOST_TRIPLET/lib instead of just /usr/include and /usr/lib. :)
Post Reply