| <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| <meta name="Author" content="David Turner"> |
| <meta name="GENERATOR" content="Mozilla/4.5 [fr] (Win98; I) [Netscape]"> |
| <title>FreeType 2 Internals - I/O Frames</title> |
| <basefont face="Georgia, Arial, Helvetica, Geneva"> |
| <style content="text/css"> |
| P { text-align=justify } |
| H1 { text-align=center } |
| H2 { text-align=center } |
| LI { text-align=justify } |
| </style> |
| </head> |
| |
| <body text="#000000" |
| bgcolor="#FFFFFF" |
| link="#0000EF" |
| vlink="#51188E" |
| alink="#FF0000"> |
| |
| <center> |
| <h1>FreeType 2.0 Build System</h1></center> |
| |
| <center> |
| <h3> |
| © 2000 David Turner (<a href="fichier :///david@freetype.org">david@freetype.org</a>)<br> |
| © 2000 The FreeType Development Team |
| (<a href="mailto:devel@freetype.org">devel@freetype.org</a>) |
| </h3></center> |
| |
| <center><table width=650><tr><td> |
| |
| <p><hr WIDTH="100%"></p> |
| |
| <h2>Table of Content</h2> |
| |
| <center><table><tr><td> |
| <p><font size="+1"><a href="#introduction">Introduction</a></font></p> |
| <p><font size="+1"><a href="#features">I. Features & Background</a></font></p> |
| <ul> |
| <li><a href="#features-1">1. Convenience, not Requirement</a> |
| <li><a href="#features-2">2. Compiler and platform independence</a> |
| <li><a href="#features-3">3. Uses GNU Make</a> |
| <li><a href="#features-4">4. Automatic host platform detection</a> |
| <li><a href="#features-5">5. User-selectable builds</a> |
| <li><a href="#features-6">6. Robustness</a> |
| <li><a href="#features-7">7. Simple modules management</a> |
| </ul> |
| <p><font size="+1"><a href="#overview">II. Overview of the build process</a></font></p> |
| <ul> |
| <p><li><a href="#overview-1">1. Build setup</a> |
| <ul> |
| <li><a href="#overview-1-a">a. Default build setup</a> |
| <li><a href="#overview-1-b">b. Selecting another build configuration</a> |
| </ul> |
| </p> |
| |
| <li><a href="#overview-2">2. Library compilation</a> |
| </ul> |
| <p><font size="+1"><a href="#setup">III. Build setup details</a></font></p> |
| <p><font size="+1"><a href="#compilation">IV. Library compilation details</a></font></p> |
| <ul> |
| <li><a href="#compilation-1">a. Compiling the <tt>ftsystem</tt> component</a> |
| <li><a href="#compilation-2">b. Compiling the base layer and optional components</a> |
| <li><a href="#compilation-3">c. Compiling the modules</a> |
| <li><a href="#compilation-4">d. Compiling the <tt>ftinit</tt> component</a> |
| </ul> |
| </ul> |
| </td></tr></table></center> |
| |
| <hr><a name="introduction"> |
| <h2>Introduction:</h2> |
| |
| <p>This document describes the new build system that was introduced |
| with FreeType 2.</p> |
| |
| <p><hr></p> |
| <a name="features"> |
| <h2>I. Features and Background:</h2> |
| |
| <p>The FreeType 2 build system is a set of Makefiles and sub-Makefiles that |
| are used to build the library on a very large variety of systems easily. |
| One of its main features are the following:</p> |
| |
| <a name="features-1"> |
| <h3>1. Convenience, not Requirement</h3> |
| <ul> |
| <p>Even though the build system is rather sophisticated, it simply is a |
| convenience that was written simply to allow the compilation of the |
| FreeType 2 library on as many platforms as possible, as easily as |
| possible. However, it is not a requirement and the library can be |
| compiled manually or in a graphical IDE without using it, with minimal |
| efforts</p> |
| |
| <p>(for more information on this topic, see the <tt>BUILD</tt> |
| document that comes with your release of FreeType, in its <em>Detailed |
| Compilation Guide</em> section).</p> |
| </ul> |
| |
| <a name="features-2"> |
| <h3>2. Compiler and platform independence</h3> |
| <ul> |
| <p>The FreeType 2 build system can be used with any compiler, on any platform. |
| It is independent of object file suffix, executable file suffix, directory |
| separator convention (i.e. "/" or "\"), and compiler flags for path |
| inclusion, macro definition, output naming, ansi compliance, etc..</p> |
| |
| <p>Supporting a new compiler is trivial and only requires writing a minimal |
| configuration sub-makefile that contains several Makefile variables |
| definitions that are later used by the rest of the build system. This is |
| described in details later in the document.</p> |
| </ul> |
| |
| <a name="features-3"> |
| <h3>3. Uses GNU Make</h3> |
| <ul> |
| <p>The build system works <em>exclusively</em> with <b>GNU Make</b>. Reason |
| is that it is the only make utility that has all the features required to |
| implement the build system as described below. Moreover, it is already |
| ported to hundreds of various distinct platforms and is widely and |
| freely available.</p> |
| |
| <p>It also uses the native command line shell. <em>You thus |
| don't need a Unix-like shell on your platform</em>. |
| For example, FreeType 2 already compiles on Unix, Dos, Windows |
| and OS/2 right "out of the box" (assuming you have GNU Make |
| installed).</p> |
| |
| <p>Finally, note that the build system is <em>specifically</em> designed |
| for gnu make and will <em>fail</em> with any other make tool. We have |
| <em>no plans</em> to support a different tools, as you'll rapidly |
| understand by reading this document or looking at the sub-makefiles |
| themselves.</p> |
| </ul> |
| |
| <a name="features-4"> |
| <h3>4. Automatic host platform detection</h3> |
| <ul> |
| <p>When you launch the build system for the first time, by simply invoking |
| GNU make in the top-level directory, it automatically tries to detect |
| your current platform in order to choose the best configuration |
| sub-makefile available. It then displays what it found. If everything |
| is ok, you can then launch compilation of the library, by invoking make |
| a second time.</p> |
| |
| <p>The following platforms are currently automatically detected:</p> |
| <ul> |
| <li>Dos (plain-dos, windows in Dos mode, or Dos session under OS/2) |
| <li>Windows 95, 98 + Windows NT (a.k.a win32) |
| <li>OS/2 |
| <li>Unix (uses Autoconf/Automake) |
| </ul> |
| |
| <p>Note that adding support for a new platform requires writing a minimal |
| number of very small files, and simply putting them in a new sub-directory |
| of <tt>freetype2/config</tt>.</p> |
| </ul> |
| |
| <a name="features-5"> |
| <h3>5. User-selectable builds</h3> |
| <ul> |
| <p>The platform auto-detection rules try to setup the build for a default |
| compiler (<em>gcc</em> for most platforms), with default build options |
| for the library (which normally is |
| <em>"all features enable, no debugging"</em>), as well as the default |
| list of modules (which is <em>"all modules in <tt>freetype2/src</tt>"</em>)</p> |
| |
| <p>There are cases where it is important to specify a different compiler, |
| different build options or simply a different module list. The FreeType 2 |
| build system is designed in such a way that all of this is easily possible |
| from the command line, <em>without having to touch a single file</em>. |
| The latter is crucial when dealing with projects that need specific |
| builds of the library without modifying a single file from the FreeType |
| distribution.</p> |
| |
| <p>The exact mechanism and implementation to do this is described later in |
| this document. It allows, for example, to compile FreeType with any of |
| the following compilers on Win32: gcc, Visual C++, Win32-LCC.</p> |
| </ul> |
| |
| <a name="features-6"> |
| <h3>6. Robustness</h3> |
| <ul> |
| <p>The build system uses a single top-level Makefile that includes |
| one or more sub-makefiles to build the entire library (base layer |
| plus all modules). |
| |
| <font color="red"> |
| To understand why this is important, we <em>strongly</em> recommend |
| the following article to all of our readers:</font></p> |
| <p> |
| <center> |
| <font size="+2"><a href="http://www.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html"> |
| Recursive Make Considered Dangerous |
| </a> |
| </font> |
| </center> |
| </p> |
| |
| <p>As an example, here's a short list of files that make up the |
| build system. Note that each sub-makefile contains rules corresponding |
| to a very specific purpose, and that they all use the "<tt>.mk</tt>" |
| suffix:</p> |
| <ul> |
| <li><tt>freetype2/Makefile</tt> |
| <li><tt>freetype2/config/detect.mk</tt> |
| <li><tt>freetype2/config/freetype.mk</tt> |
| <li><tt>freetype2/config/<em><system></em>/detect.mk</tt> |
| <li><tt>freetype2/src/<em><module></em>/rules.mk</tt> |
| <li><tt>freetype2/src/<em><module></em>/module.mk</tt> |
| </ul> |
| |
| </ul> |
| |
| <a name="features-7"> |
| <h3>7. Simple Module Management</h3> |
| <ul> |
| <p>FreeType 2 has a very modular design, and is made of a core |
| <em>base layer</em> that provides its high-level API as well as |
| generic services used by one or more <em>modules</em>. |
| |
| Most modules are used to support a specific font format (like TrueType |
| or Type 1), and they are called <em>font drivers</em>. However, some of |
| them do not support font files directly, but rather provide helper |
| services to the font drivers.</p> |
| |
| <p>FreeType 2 is designed so that adding modules at run-time is possible |
| and easy. Similarly, we expect many more modules to come in the near |
| future and wanted a build system that makes such additions to the |
| source package itself dead easy. |
| |
| Indeed, all source code (base + modules) is located in the |
| <tt>freetype2/src</tt> directory hierarchy. And the build system is |
| capable of re-generating automatically the list of known modules |
| from the contents of this directory. Hence, adding a new font driver |
| to the FreeType sources simply requires to:</p> |
| |
| <ul> |
| <li><p>Add a new sub-directory to <tt>freetype2/src</tt> |
| <li><p>Re-launch the build system</p> |
| </ul> |
| |
| <p>There is thus no need to edit a source file</p> |
| </ul> |
| |
| <p><hr><p> |
| <a name="overview"> |
| <h2>II. Overview of the build process(es):</h2> |
| |
| <p>Before describing in details how the build system works, it is essential |
| to give a few examples of how it's used. This section presents |
| what's the build process is to the typical developer:</p> |
| |
| <p>Compiling the library is normally done in two steps: the first one |
| configures the build according to the current platform and possible |
| additional parameters, while the second simply compiles the library with |
| the information gathered in the configuration step.</p> |
| |
| <a name="overview-1"> |
| <h3>1. Build Setup</h3> |
| |
| <a name="overview-1-a"> |
| <h4>a. Default build setup</h4> |
| <ul> |
| <p>To configure the build, simply invoke gnu make from the top-level FreeType |
| directory. This will launch a series of rules that will detect your current |
| host platform, and choose a configuration file for you. It will then display |
| what it found. For example, here's the output of typing the command "make" |
| on a win32 platform (assuming this calls GNU make):</p> |
| |
| <pre><font color="blue"> |
| <font color="purple">C:\FreeType> make</font> |
| |
| FreeType build system -- automatic system detection |
| |
| The following settings are used: |
| |
| platform win32 |
| compiler gcc |
| configuration directory ./config/win32 |
| configuration rules ./config/win32/w32-gcc.mk |
| |
| If this does not correspond to your system or settings please remove the file |
| 'config.mk' from this directory then read the INSTALL file for help. |
| |
| Otherwise, simply type 'make' again to build the library. |
| |
| <font color="purple">C:\FreeType></font> |
| </font></pre> |
| |
| <p>Note that this step copies the selected configuration file (here |
| <tt>./config/win32/w32-gcc.mk</tt>) to <em>the current directory</em>, under |
| the name <tt><b>config.mk</b></tt>. This file contains data that is used |
| to drive the library compilation of the second step. It correspond to |
| the platform and compiler selected by the auto-detection phase.</p> |
| |
| <p>Note that you can re-generate the <tt><b>config.mk</b></tt> file anytime |
| by invoking <tt>make setup</tt> whenever you need it, even when the file is |
| already present in the current directory.</p> |
| |
| <p>Finally, if your platform is not correctly detected, the build system will |
| display and use configuration information for the virtual "ansi" platform. |
| </p> |
| </ul> |
| <a name="overview-1-b"> |
| <h4>b. Selecting another build configuration</h4> |
| <ul> |
| <p>You may not be really satisfied by the configuration file selected by the |
| auto-detection routines. Typically, you might be using a compiler that is |
| not the default one for your platform. It is however possible to re-launch |
| the build setup phase with an additional argument, used to specify a |
| different compiler/config file. For example, you can type the following |
| commands on Win32 systems:</p> |
| |
| <p align=center><table width="80%" cellpadding=10><tr valign=top><td> |
| <p><b><tt>make setup</tt></b></p> |
| </td><td> |
| <p>re-run the platform detection phase, and select the default compiler for it. |
| On Win32, this is <em>gcc</em>.</p> |
| </td></tr><tr valign=top><td> |
| <p><b><tt>make setup visualc</tt></b></p> |
| </td><td> |
| <p>re-run the platform detection phase, and select a config file that |
| corresponds to the <em>Visual C++</em> compiler</p> |
| </td></tr><tr valign=top><td> |
| <p><b><tt>make setup lcc</tt></b></p> |
| </td><td> |
| <p>re-run the platform detection phase, and select a config file that |
| corresponds to the <em>Win32-LCC</em> compiler</p> |
| </td></tr></table> |
| </p> |
| |
| <p>Note that a specific configuration is selected with a command that |
| looks like : <tt><b>make setup <em>compiler</em></b></tt>, |
| where the <em><tt>compiler</tt></em> keywords depends on the platform. |
| Moreover, each one of them corresponds to a specific configuration |
| sub-makefile that is copied as <b><tt>config.mk</tt></b> in the current |
| directory.</p> |
| </ul> |
| |
| |
| <a name="overview-2"> |
| <h3>2. Library compilation</h3> |
| |
| <p>Once you're satisfied with the version of <b><tt>config.mk</tt></b> that |
| has been copied to your current directory, you can simply re-invoke |
| gnu make <em>with no arguments</em>. The top-level Makefile will |
| automatically detect the config sub-makefile in the current directory, |
| and use it to drive the library compilation. The latter can be seen |
| as a series of different steps decribed here:</p> |
| |
| <ul> |
| <li><p><b>Compiling the <tt>ftsystem</tt> component</b><br><ul> |
| It encapsulates all low-level operations (memory management + |
| i/o access) for the library. Its default version, located in |
| <tt>./src/base/ftsystem.c</tt> uses the ANSI C library but |
| system-specific implementations are also available to |
| improve performance (e.g. memory-mapped files on Unix). |
| </ul></p> |
| |
| <li><p><b>Compiling the <em>base layer</em> and optional components</b><br><ul> |
| They provide the library's high-level API as well as various useful |
| routines for client applications. Many features of the base layer can |
| be activated or not depending on a configuration file named |
| <tt>ftoption.h</tt> |
| </ul></p> |
| |
| <li><p><b>Compiling the <em>modules</em></b><br><ul> |
| Each module is used to support a specific font format (it is then |
| called a <em>font driver</em>), or to provide helper services to |
| the drivers (e.g. the auto-hinter). They are all located in |
| sub-directories of <tt>./src</tt>, like <tt>./src/truetype</tt>, |
| <tt>./src/type1</tt>. |
| </ul></p> |
| |
| <li><p><b>Compiling the <tt>ftinit</tt> component</b><br><ul> |
| This one is in charge of implementing <tt>FT_Init_FreeType</tt>, |
| the library initialisation routine. It also selects what modules |
| are activated when a new library instance is created. |
| </ul></p> |
| </ul> |
| <p><hr><p> |
| <a name="setup"> |
| <h2>II. Details of the build setup.</h2> |
| |
| <p>When the top-level <tt>Makefile</tt> is invoked, it looks for a |
| file named <b><tt>config.mk</tt></b> in the <em>current directory</em>. |
| If this file is found, it is used directly to build the library |
| (skip to <a href="library">Section III</a> for details then).</p> |
| |
| <p>Otherwise, the file <b><tt>./config/detect.mk</tt></b> is included |
| by the top-level <tt>Makefile</tt> and parsed. Its purpose is to drive the |
| platform-detection phase, by:</p> |
| |
| <ul> |
| <li><p>Defining the <tt>PLATFORM</tt> variable, which indicates |
| what the currently detected platform is. It is initially |
| set to the default value "<tt><b>ansi</b></tt>". |
| </p> |
| |
| <li><p>Searching for a <tt>detect.mk</tt> file in <em>all |
| subdirectories</em> of <b><tt>./config</tt></b>. |
| Each such file is included and parsed. Each of these files must |
| try to detect if the host platform is a system it knows |
| about. If so, it changes the value of the <tt>PLATFORM</tt> variable |
| accordingly.</p> |
| |
| <li><p>Copying the selected configuration submakefile to the current directory |
| under the name <tt><b>config.mk</b></tt>.</p> |
| </ul> |
| <p>This is illustrated by the following graphics :</p> |
| <p><center> |
| <img src="platform-detection.png" border=0> |
| </center></p> |
| |
| <p>Each system-specific <b><tt>detect.mk</tt></b> works as follows:</p> |
| <ul> |
| <li><p>It checks that the value of <tt>PLATFORM</tt> is currently set |
| to <b>ansi</b>, which indicates that no platform was detected |
| for now. If this isn't true, it doesn't do anything</p> |
| |
| <li><p>Otherwise, it runs a series of test to see wether it is on a |
| system it knows about. Here are a few examples of tests:</p> |
| |
| <p><center><table width="80%" cellpadding=5><tr valign=top><td> |
| <em><b>Unix</b></em> |
| </td><td> |
| <p>checks for a file named <tt>/sbin/init</tt>, and runs, when it found |
| it, a 'configure' script to generate the relevant config sub-makefile</p> |
| </td></tr><tr valign=top><td> |
| <em><b>Dos</b></em> |
| </td><td> |
| <p>checks for the <tt>COMSPEC</tt> environment variable, then tries to |
| run the "<tt>ver</tt>" command on the current shell to check that there |
| is a "Dos" substring in its output; if not, it tries to find the |
| substring "<tt>MDOS\COMMAND</tt>" in <tt>COMSPEC</tt>, which indicates |
| a Dos session under OS/2.</p> |
| </td></tr><tr valign=top><td> |
| <em><b>Win32</b></em> |
| </td><td> |
| <p>if the environment variable <tt>OS</tt> is defined and has the value |
| <tt>Windows_NT</tt>, or if <tt>COMSPEC</tt> is defined and the |
| "<tt>ver</tt>" returns a string that contains <tt>Windows</tt> in it, |
| we're on a Win32 system.</p> |
| </td></tr></table></center> |
| </p> |
| |
| <li><p>It sets the value of <tt>PLATFORM</tt> to a new value corresponding |
| to its platform.</p> |
| |
| <li><p>It then tries to select a configuration |
| sub-makefile, depending on the current platform and any optional |
| make target (like "visualc" or "devel", etc..). Note that it can |
| even generate the file, as on Unix through Autoconf/Automake.</p> |
| |
| <li><p>It copies the selected configuration sub-makefile to the current |
| directory, under the name <tt><b>config.mk</b></tt> |
| </ul> |
| |
| <p>If one wants to support a new platform in the build system, it simply needs |
| to provide:</p> |
| |
| <ul> |
| <li>A new subdirectory, in <tt>./config</tt>, with a file named |
| <tt>detect.mk</tt> in it, containing relevant checks for the system. |
| |
| <li>One or more configuration sub-makefiles that will get copied to |
| <tt>config.mk</tt> at build setup time. You can use the one in |
| <tt>./config/ansi/config.mk</tt> as a template. |
| </ul> |
| |
| <p>Similary, supporting a new compiler on an existing system simply means:</p> |
| <ul> |
| <li>Writing a new config sub-makefile that contains definitions used to |
| specify the compiler and flags for the build. |
| |
| <li>Change your <tt>./config/<em>system</em>/detect.mk</tt> to recognize |
| a new optional build target that will copy your new config sub-makefile |
| instead of the default one. |
| </ul> |
| |
| |
| <p><hr><p> |
| <h2>III. Details of the library compilation.</h2> |
| |
| <p>When the top-level Makefile is invoked, it looks for a file named |
| <tt>config.mk</tt> in the current directory. If one is found, it |
| defines the <tt>BUILD_FREETYPE</tt> variable, then includes and parses it. |
| The structure of this file is the following: |
| </p> |
| |
| <ul> |
| <li><p>First, it defines a series of Make variables that describe |
| the host environment, like the compiler, compilation flags, |
| object file suffix, the directory where all object files are |
| placed, etc..</p> |
| |
| <li><p>If <tt>BUILD_FREETYPE</tt> is defined, it includes the file |
| <tt><b>./config/freetype.mk</b></tt>, which is in charge of |
| defining all the rules used to build the library object files. |
| (The test is useful to use the <tt>config.mk</tt> file to |
| compile other projects that rely on FreeType 2, like its |
| demonstration programs).</p> |
| |
| <li><p>Finally, it defines the rule(s) used to link FreeType 2 object files |
| into a library file (e.g. <tt>libfreetype.a</tt>, <tt>freetype.lib</tt>, |
| <tt>freetype.dll</tt>, ...). Unfortunately, the command line interface of link tools is |
| a <em>lot less</em> standardized than those of compilers, which |
| explains why this rule must be defined in the system-specific |
| <tt>config.mk</tt>.</p> |
| </ul> |
| |
| <p>The following is an explanation of what <tt><b>./config/freetype.mk</b></tt> |
| does to build the library objects: |
| </p> |
| |
| <h4>a. Include paths</h4> |
| <ul> |
| <p>To avoid namespace pollution, the <tt><em>freetype</em></tt> directory prefix |
| is used to include all public header files of the library. This means |
| that a client application will typically use lines like:</p> |
| |
| <pre><font color="blue"> |
| #include <freetype/freetype.h> |
| #include <freetype/ftglyph.h> |
| </font></pre> |
| |
| <p>to include one the FreeType 2 public header files. <tt>freetype.mk</tt> |
| uses a variable named <tt><b>INCLUDES</b></tt> to hold the inclusion |
| paths list, and thus starts by adding <tt>./include</tt> to it. However, |
| nothing prevents |
| |
| <p><tt>freetype.mk</tt> uses a variable named <tt><b>INCLUDES</b></tt> |
| to hold directory inclusion-path to be used when compiling the library. |
| It always add <tt>./include</tt> to this variable, which means |
| |
| </ul> |
| |
| <h4>b. Configuration header files:</h4> |
| <ul> |
| <p>Three header files used to configure the compilation of the |
| FreeType 2 library. Their default versions are all located in the |
| directory <tt><b>./include/freetype/config/</b></tt>, even though |
| project specific versions can be provided on a given build, as |
| described later:</p> |
| |
| <ul> |
| <p><b><tt>#include <freetype/config/ftoption.h></tt></b><br><ul> |
| This file contains a set of configuration macro definitions that |
| can be toggled to activate or deactivate certain features of the |
| library. By changing one of these definitions, it is possible to |
| compile <em>only the features that are needed</em> for a specific |
| project. Note that by default, all options are enabled. |
| <br><br> |
| You might need to provide an alternative version of <tt>ftoption.h</tt> |
| for one of your own projects. |
| </ul></p> |
| |
| <p><b><tt>#include <freetype/config/ftconfig.h></tt></b><br><ul> |
| This file includes <tt>ftoption.h</tt> but also contains some automatic |
| macro definitions used to indicate some important system-specific |
| features (e.g: word size in bytes, DLL export prefix macros, etc..). |
| <br><br> |
| You shouldn't normally need to change or provide an alternative |
| version of this file. |
| </ul></p> |
| |
| |
| <p><b><tt>#include <freetype/config/ftmodule.h></tt></b><br><ul> |
| This file is very special, as it is normally machine-generated, and |
| used by the <tt>ftinit</tt> component that is described below. To |
| understand it, one must reminds that FreeType 2 has an extremely |
| modular design and that it's possible to change, <em>at run-time</em>, |
| the modules it's using. The <tt>ftmodule.h</tt> file simply contains |
| the list of modules that are registered with each new instance of |
| the library. |
| <br><br> |
| Note that the file can be re-generated automatically by invoking |
| <tt>make setup</tt> from the top-level directory. The re-generated |
| list contains all the modules that were found in subdirectories of |
| <tt>./src</tt>. |
| </ul></p> |
| </ul> |
| |
| <p>Note that we strongly advise you to avoid modifying the config files |
| within the FreeType 2 source directory hierarchy. Rather, it's possible |
| to specify alternative versions through the help of a build-specific |
| include path that is include before <tt>./include</tt> in the inclusion |
| path.</p> |
| |
| <p>For example, imagine that your platform, named <em>foo</em>, needs a |
| specific version of <tt>ftoption.h</tt> |
| </ul> |
| |
| <h4>a. Compiling the <b><tt>ftsystem</tt></b> component:</h4> |
| <ul> |
| <p>FreeType 2 encapsulates all low-level operations (i.e. memory management |
| and i/o access) within a single component called <tt><b>ftsystem</b></tt>. |
| Its default implementation uses the <em>ANSI C Library</em> and is located |
| in <tt>./src/base/ftsystem.c</tt>.</p> |
| |
| <p>However, some alternate, system-specific, implementations of |
| <tt>ftsystem</tt> are provided with the library in order to support more |
| efficient and advanced features. As an example, the file |
| <tt>./config/unix/ftsystem.c</tt> is an implementation that |
| uses memory-mapped files rather than the slow ANSI <tt>fopen</tt>, |
| <tt>fread</tt> and <tt>fseek</tt>, boosting performance significantly.</p> |
| |
| <p>The build system is thus capable of managing alternate implementations |
| of <tt>ftsystem</tt></p> |
| </ul> |
| |
| <h4>b. Compiling the base layer and optional components:</h4> |
| <ul> |
| <p>The high-level API of the library is provided by a component called the |
| <em>base layer</em>, whose source is located in <tt>./src/base</tt>. This |
| directory also contains one or more components that are optional, i.e. |
| that are not required by the library but provide valuable routines to |
| client applications.</p> |
| |
| <p>The features of the base library and other components are selected through |
| a single configuration file named |
| <tt><b>./include/freetype/config/ftoption.h</b></tt>. It contains a list |
| of commented configuration macro definitions, that can be toggled to |
| activate or de-activate a certain feature or component at build time.</p> |
| |
| <p>For example, the code in <tt>./src/base/ftdebug.c</tt> will be compiled |
| only if one of these two macros are defined in <tt>ftoption.h</tt>: |
| <tt>FT_DEBUG_LEVEL_ERROR</tt> or <tt>FT_DEBUG_LEVEL_TRACE</tt></p> |
| </ul> |
| |
| <h4>c. Compiling the modules:</h4> |
| <ul> |
| <p>Once the base layer is completed, the build system starts to compile each |
| additional module independently. These are simply defined as all source |
| code located in a sub-directory of <tt>./src</tt> that contains a file |
| named <tt><b>rules.</b></tt>, for example: |
| <tt>src/sfnt</tt>, <tt>src/truetype</tt>, <tt>src/type1</tt>, ...</p> |
| |
| <p>The <tt><b>rules.</b></tt> file simply contains directives used by the |
| build system to compile the corresponding module into a single object |
| file.</p> |
| </ul> |
| |
| <h4>d. Compiling the <b><tt>ftinit</tt></b> component:</h4> |
| <ul> |
| <p>The file <tt><b>./src/base/ftinit.c</b></tt> is special because it is used |
| to implement the library initialisation function <tt>FT_Init_FreeType</tt>. |
| </p> |
| </ul> |
| |
| <p>Typically, you will end up with all object files, as well as the |
| corresponding library file, residing in the <tt>freetype2/obj</tt> |
| directory.</p> |
| |
| |
| <h3>1. Purpose of the configuration sub-makefile</h3> |
| |
| <h3>2. Managing module dependencies</h3> |
| |
| <h3>3. </h3> |
| |
| <p><hr><p> |
| <a name="modules"> |
| <h2>IV. Managing the modules list</h2> |
| |
| <p><hr><p> |
| The build system features some important points, which are all detailed |
| in the following sections:<p> |
| <ul> |
| <li><b>Automatic host platform detection</b><br> |
| The first time the top <tt>Makefile</tt> is invoked, it will |
| run a series of rules to detect your platform. It will then |
| create a system-specific configuration sub-Makefile in the |
| current directory, called <b><tt>config.mk</tt></b>. You can now |
| invoke the top <tt>Makefile</tt> a second time to compile the |
| library directly. |
| <p> |
| The configuration sub-makefile can be regenerated any time |
| by invoking "<tt>make setup</tt>", which will re-run the |
| detection rules even if a <tt>config.mk</tt> is already present. |
| <p> |
| |
| |
| <li><b>User-selectable builds</b><br> |
| <p> |
| |
| |
| |
| <li><b>Automatic detection of font drivers</b><br> |
| FreeType is made of a "base" layer that invokes several |
| separately-compiled modules. Each module is a given |
| font driver, in charge of supporting a given font format. |
| <p> |
| The list of font drivers is located in the file |
| "<tt>freetype2/config/<em>system</em>/ftmodule.h</tt>", however |
| it can be regenerated on-demand. Adding a new module to the |
| FreeType source tree is thus as easy as:<p> |
| <ul> |
| <li>create a new directory in "<tt>freetype2/src</tt>" and |
| put the new driver's source code and sub-makefiles there. |
| <p> |
| |
| <li>invoke the top <tt>Makefile</tt> with target |
| "<tt>modules</tt>" (as in "<tt>make modules</tt>"), |
| as this will automatically regenerate the list of |
| available drivers by detecting the new directory and |
| its content. |
| </ul> |
| <p> |
| </ul> |
| </ul> |
| |
| <p><hr><p> |
| |
| <h2>II. Host Platform Detection</h2> |
| <ul> |
| When the top-level <tt>Makefile</tt> is invoked, it looks for a |
| file named <tt>config.mk</tt> in the current directory. If this |
| file is found, it is used to build the library |
| (see <a href="library">Section III</a>). |
| <p> |
| Otherwise, the file <tt>freetype2/config/detect.mk</tt> is included |
| and parsed. Its purpose is to:<p> |
| <ul> |
| <li>Define the <tt>PLATFORM</tt> variable, which indicates |
| what is the currently detected platform. It is initially |
| set to the default value "<tt>ansi</tt>". |
| <p> |
| |
| <li>It searches for a <tt>detect.mk</tt> file in all |
| subdirectories of <tt>freetype2/config</tt>. Each such |
| file is included and parsed. Each of these files must |
| try to detect if the host platform is a system it knows |
| about. If so, it changes the value of the <tt>PLATFORM</tt> |
| accordingly. |
| </ul> |
| <p> |
| This is illustrated by the following graphics :<p> |
| <center> |
| <img src="platform-detection.png" border=0> |
| </center> |
| <p> |
| Note that each system-specific <tt>detect.mk</tt> is in charge |
| of copying a valid configuration makefile to the current directory |
| (i.e. the one where <tt>make</tt> was invoked), depending on the |
| current targets. For example, the Win32 <tt>detect.mk</tt> will |
| be able to detect a "<tt>visualc</tt>" or "<tt>lcc</tt>" target, |
| as described in section I. Similarly, the OS/2 <tt>detect.mk</tt> |
| can detect targets like "<tt>borlandc</tt>", "<tt>watcom</tt>" |
| or "<tt>visualage</tt>", etc.. |
| </ul> |
| |
| <p><hr><p> |
| |
| <h2>III. Building the library</h2> |
| <ul> |
| When the top-level <tt>Makefile</tt> is invoked and that it finds |
| a <tt>config.mk</tt> file in the current directory, it defines |
| the variable <tt>BUILD_FREETYPE</tt>, then includes and parses the |
| configuration sub-makefile. |
| <p> |
| The latter defines a number of important variables that describe |
| the compilation process to the build system. Among other things:<p> |
| <ul> |
| <li>the extension to be used for object files and library files |
| (i.e. <tt>.o</tt> and <tt>.a</tt> on Unix, <tt>.obj</tt> |
| and <tt>.lib</tt> on Dos-Windows-OS/2, etc..). |
| <p> |
| |
| <li>the directory where all object files will be stored |
| (usually <tt>freetype2/obj</tt>), as well as the one |
| containing the library file (usually the same as for |
| objects). |
| <p> |
| |
| <li>the command line compiler, and its compilation flags for |
| indicating a new include path (usually "<tt>-I</tt>"), |
| a new macro declaration (usually "<tt>-D</tt>") or |
| the target object file (usually "<tt>-o </tt>") |
| </ul> |
| <p> |
| Once these variable are defined, <tt>config.mk</tt> test for the |
| definition of the <tt>BUILD_FREETYPE</tt> variable. If it exists, |
| the makefile then includes "<tt>freetype2/config/freetype.mk</tt>" |
| which contains the rules required to compile the library. |
| <p> |
| Note that <tt>freetype.mk</tt> also scans the subdirectories of |
| "<tt>freetype2/src</tt>" for a file called "<tt>rules.mk</tt>". |
| Each <tt>rules.mk</tt> contains, as it names suggests, the rules |
| required to compile a given font driver or module. |
| <p> |
| Once all this parsing is done, the library can be compiled. Usually, |
| each font driver is compiled as a standalone object file (e.g. |
| <tt>sfnt.o</tt>, <tt>truetype.o</tt> and <tt>type1.o</tt>). |
| <p> |
| This process can be illustrated by the following graphics:<p> |
| <center> |
| <img src="library-compilation.png" border=0> |
| </center> |
| <p> |
| </ul> |
| |
| <p><hr><p> |
| |
| <h2>IIV. Managing the list of modules</h2> |
| <ul> |
| The makefile <tt>freetype.mk</tt> only determines how to compile |
| each one of the modules that are located in the sub-directories of |
| <tt>freetype2/src</tt>. |
| <p> |
| However, when the function <tt>FT_Init_FreeType</tt> is invoked at |
| the start of an application, it must create a new <tt>FT_Library</tt> |
| object, and registers all <em>known</em> font drivers to it by |
| repeatly calling <tt>FT_Add_Driver</tt>. |
| <p> |
| The list of <em>known</em> drivers is located in the file |
| "<tt>freetype2/config/<em>system</em>/ftmodule.h</tt>", and is used |
| exclusively by the internal function <tt>FT_Default_Drivers</tt>. The |
| list in <tt>ftmodule.h</tt> must be re-generated each time you add |
| or remove a module from <tt>freetype2/src</tt>. |
| <p> |
| This is normally performed by invoking the top-level <tt>Makefile</tt> |
| with the <tt>modules</tt> target, as in:<p> |
| <ul> |
| <tt>make modules</tt> |
| </ul> |
| <p> |
| This will trigger a special rule that will re-generate |
| <tt>ftmodule.h</tt>. To do so, the Makefile will parse all module |
| directories for a file called "<tt>module.mk</tt>". Each |
| <tt>module.mk</tt> is a tiny sub-Makefile used to add a single |
| module to the driver list. |
| <p> |
| This is illustrated by the following graphics:<p> |
| <center> |
| <img src="drivers-list.png" border=0> |
| </center> |
| <p> |
| Note that the new list of modules is displayed in a very human-friendly |
| way after a "<tt>make modules</tt>". Here's an example with the current |
| source tree (on 11 Jan 2000):<p> |
| <ul><pre> |
| Regenerating the font drivers list in ./config/unix/ftmodule.h |
| * driver: sfnt ( pseudo-driver for TrueType & OpenType formats ) |
| * driver: truetype ( Windows/Mac font files with extension *.ttf or *.ttc ) |
| * driver: type1 ( Postscript font files with extension *.pfa or *.pfb ) |
| -- done -- |
| </pre></ul> |
| |
| </ul> |
| |
| <p><hr><p> |
| |
| <h2>V. Building the demonstration programs</h2> |
| <ul> |
| Several demonstration programs are located in the |
| "<tt>freetype2/demos</tt>" directory hierarchy. This directory also |
| includes a tiny graphics sub-system that is able to blit glyphs to |
| a great variety of surfaces, as well as display these in various |
| graphics libraries or windowed environments. |
| <p> |
| This section describes how the demonstration programs are compiled, |
| using the configuration <tt>freetype2/config.mk</tt> and their own |
| <tt>freetype2/demos/Makefile</tt>. |
| <p> |
| To compile the demonstration programs, <em>after the library</em>, |
| simply go to <tt>freetype2/demos</tt> then invoke GNU make with no |
| arguments. |
| <p> |
| The top-level Makefile will detect the <tt>config.mk</tt> in the |
| <em>upper</em> directory and include it. Because it doesn't define |
| the <tt>BUILD_FREETYPE</tt> variable, this will not force the |
| inclusion of <tt>freetype2/config/freetype.mk</tt> as described in |
| the previous section. |
| <p> |
| the <tt>Makefile</tt> will then include the makefile called |
| "<tt>freetype2/demos/graph/rules.mk</tt>". The graphics <tt>rules.mk</tt> |
| defines the rules required to compile the graphics sub-system. |
| <p> |
| Because the graphics syb-system is also designed modularly, it is able |
| to use any number of "modules" to display surfaces on the screen. |
| The graphics modules are located in the subdirectories of |
| <tt>freetype2/demos/config</tt>. Each such directory contains a file |
| named <tt>rules.mk</tt> which is in charge of:<p> |
| <ul> |
| <li>detecting wether the corresponding graphics library is |
| available at the time of compilation. |
| <p> |
| <li>if it is, alter the compilation rules to include the graphics |
| module in the build of the <tt>graph</tt> library. |
| </ul> |
| <p> |
| When the <tt>graph</tt> library is built in <tt>demos/obj</tt>, the |
| demonstration programs executables are generated by the top-level |
| Makefile. |
| <p> |
| This is illustrated by the following graphics:<p> |
| <center> |
| <img src="demo-programs.png" border="0"> |
| </center> |
| </ul> |
| |
| <p><hr> |
| </td></tr></table></center> |
| </body> |
| </html> |
| |