haiku/docs/develop/makefile-engine.html

255 lines
12 KiB
HTML

<h1>How To Create a Project Using Makefile Engine</h1>
<p>Haiku helps developers in build process of their projects by providing so
called Makefile engine. It's made of two files, that reside in
/boot/develop/etc directory and are named 'makefile' and 'makefile-engine'.
Together, these two files provide you with simple ready-to-be used build
engine for your projects. This How To describes makefile-engine v2.5.1 and
makefile template v2.5. Regardless of mentioning the 'makefiles' in this
How To, the same technique can be used for creating Jamfile-driven
projects. Corresponding Jamfile and Jamfile-engine template files are provided
with Haiku. We made both, the makefile and Jamfile engines completely
target-compatible for user's convenience.</p>
<h2>Contents</h2>
<p>
<ul>
<li><a href="#getting_started">Getting Started</a></li>
<li><a href="#config">Configuring a Project</a></li>
<li><a href="#localization">Using Localization</a></li>
<li><a href="#targets">Target Reference</a></li>
</ul>
</p>
<div id="getting_started"><h2>Getting Started</h2></div>
<p>To start a project, just copy makefile from /boot/develop/etc directory, into
your project directory. Write few files, you want to add into project. Add
either relative or full paths to them, into SRCS variable definition in
makefile and run make. Example files for Hello World project:</p>
<p><em>hello.cpp</em>:</p>
<pre><code>#include &lt;stdio.h&gt;
int main(void)
{
printf("Hello world!\n");
return 0;
}
</code></pre>
<p><em>makefile</em>:</p>
<pre><code>NAME = hello
TYPE = APP
SRCS = hello.cpp
include $(BUILDHOME)/etc/makefile-engine
</code></pre>
<p>After adding both these files into same directory, just go there in Terminal,
using 'cd' command and run 'make'. This will create a new directory, named in
similar format: 'objects.x86-gcc2-release' (name depends on current compiler,
that may be either "gcc2" or "gcc4", and defining DEBUG will force using
"debug" instead of "release"), which will contain .o files (one
for each source file), .d files with dependencies, generated automatically by
the engine and a binary file, named 'hello' for the example case above.</p>
<div id="config"><h2>Configuring a Project</h2></div>
<p>In makefile, there are many variables, to configure builder helpers for your
needs. Let's take a look at them:</p>
<ul>
<li><strong>NAME</strong> specifies the name of the project and the output binary filename</li>
<li><strong>TYPE</strong> specifies the type of binary, can be one of the following:
<ul>
<li><strong>APP</strong> - Application</li>
<li><strong>SHARED</strong> - Shared library or add-on</li>
<li><strong>STATIC</strong> - Static library archive</li>
<li><strong>DRIVER</strong> - Kernel Driver</li>
</ul></li>
<li><strong>APP_MIME_SIG</strong> specifies application's mime signature for
localization features. Note that it should correspond to MIME type
provided to BApplication's constructor and the application MIME type
defined in resource file. In case this parameter is not set, the
default value x-vnd.Haiku-$(NAME) will be used.</li>
<li><strong>SRCS</strong> specifies the source files to use. You may specify both, full
paths and paths relative to the position of makefile, all objects,
regardless of the position of their sources will be created in the
common object directory. Please note, that this means, that makefile
won't work correctly, if two source files with the same name
(e.g. source.c and source.cpp) are included from different
directories. Also note, that spaces in folder names do not work well
with the engine.</li>
<li><strong>RDEFS</strong> specifies the resource definition files to be used. You may
specify both, relative and full paths to the files.</li>
<li><strong>RSRCS</strong> specifies the binary file compiled from <em>RDEF</em>, or created
separately by Resource Editors, both <em>RDEFS</em> and <em>RSRCS</em> can be
defined in the same makefile.</li>
<li><strong>LIBS</strong> specifies additional libraries, that binary file should be
linked against. There are two acceptable forms of library
specifications:
<ul>
<li>if your library follows the naming pattern of libXXX.so or libXXX.a,
you can simply specify XXX, e.g. for library libbe.so, that would be:
be</li>
<li>for version-independent linking of standard C++ libraries, please
add $(STDCPPLIBS instead of raw "stdc++[.r4] [supc++]" library names</li>
<li>for localization support add following libraries: locale localestub</li>
<li>if your library doesn't follow the standard library naming
scheme, you need to specify the path to the library and its name, e.g.
for library: my_lib.a, the entry would be either: my_lib.a or
path/my_lib.a</li>
</ul></li>
<li><strong>LIBPATHS</strong> specifies additional paths to directories following the
standard libXXX.so or libXXX.a naming scheme. You can specify both,
full paths or paths relative to the makefile. The paths included may
not be recursive, so include all paths, where libraries can be found.
Directories where source files are found are automatically included.</li>
<li><strong>SYSTEM_INCLUDE_PATHS</strong> specifies additional paths to look for system
headers. These use the form: #include &lt;header&gt;. Source file
directories are <em>NOT</em> automatically included here.</li>
<li><strong>LOCAL_INCLUDE_PATHS</strong> specifies additional paths to look for local
headers. There use the form: #include "header". Source file
directories are automatically included.</li>
<li><strong>OPTIMIZE</strong> specifies the level of optimization desired, can be one of
following: <em>NONE</em>, <em>SOME</em>, <em>FULL</em>.</li>
<li><strong>LOCALES</strong> specifies language codes, that are going to be supported
by application. The default "en" one must be provided too. For more
information about localization, see the corresponding section of this
how-to.</li>
<li><strong>DEFINES</strong> specifies any preprocessor symbols to be defined. The symbols
will not have their values set automatically, you have to provide
these values (if any). For example, setting <em>DEFINES</em> to "DEBUG=1" will
cause the compiler option "-DDEBUG=1" to be used. However, setting
<em>DEFINES</em> to "DEBUG" would pass "-DDEBUG" option.</li>
<li><strong>WARNINGS</strong> specifies the level of warnings reported by compiler. If this
option is unspecified, the default warnings will be used. It can be
set to one of the following:
<ul>
<li>NONE - supress all warnings</li>
<li>ALL - enable all warnings</li>
</ul></li>
<li><strong>SYMBOLS</strong> specifies, whether image symbols should be created, so the
stack crawls in the debugger are meaningful. Setting it to <em>TRUE</em>
enables the creation of symbols.</li>
<li><strong>DEBUGGER</strong> specifies debugging settings. If set to <em>TRUE</em>, it allows
the application to be run from a source-level debugger. Please note,
that this will disable all optimization.</li>
<li><strong>COMPILER_FLAGS</strong> specifies additional compiler flags for all files.</li>
<li><strong>LINKER_FLAGS</strong> specifies additional linker flags.</li>
<li><strong>APP_VERSION</strong> specifies the version of the particular item (e.g. -app
3 4 0 d 0 -short 340 -long "340 "<code>echo -n -e '\302\251'</code>).
"1999 GNU GPL"). This may also be specified in a resource.</li>
<li><strong>DRIVER_PATH</strong> works only for <em>TYPE</em> == <em>DRIVER</em>. It specifies desired
location of driver in the /dev hierarchy. It's user by the
driverinstall rule. E.g. <em>DRIVER_PATH</em> = video/usb will instruct
the driverinstall rule to place a symlink to your driver's binary into
~/add-ons/kernel/drivers/dev/video/usb, so that your driver will
appear in /dev/video/usb when loaded. Default is "misc".</li>
<li><strong>INSTALL_DIR</strong> specifies the installation directory of application.</li>
</ul>
<p>Please also note, that if you're building your own makefile, that will use this
engine, last line must contain:</p>
<pre><code>include $(BUILDHOME)/etc/makefile-engine
</code></pre>
<div id="localization"><h2>Using Localization</h2></div>
<p>Localization in Haiku programs is achieved simply, as following example shows.</p>
<p><em>localized_hello.cpp</em>:</p>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;Catalog.h&gt;
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "hello"
int main(void)
{
printf(B_TRANSLATE("Hello, world!\n"));
return 0;
}
</code></pre>
<p>This file uses header file Catalog.h, that belongs to locale library. So to
actually be able to use localization in your programs, you have to adjust few
settings in your makefile.</p>
<ol>
<li>Adjust a value to your project's <strong>APP_MIME_SIG</strong> variable.
Application's mime signature should also be set in the following
format: x.vnd-&lt;author&gt;-&lt;project_name&gt;</li>
<li>Add following two libraries into your <strong>LIBS</strong> variable: locale localestub</li>
<li>Add every language, that you want to support, into <strong>LOCALES</strong> variable,
e.g. 'LOCALES = en de fr' for English, German and French locale
support.</li>
<li><p>Add the Resource Definition script (also please specify it in <em>RDEF</em>
variable) containing the following entries into project:</p>
<p>resource app_signature "application/x-vnd.<author>-<project_name>";</p>
<p>resource app<em>name</em>catalog_entry "<author>-<project_name>:System name:Terminal";</p></li>
<li><p>Run 'make' to build binary file.</p></li>
<li>Run either: 'make catkeys' to get locales/en.catkeys file.</li>
<li>Copy this file to locales/&lt;language_code&gt;.catkeys and translate it,
as needed.</li>
<li>When you prepared all needed .catkeys files, run 'make catalogs' to create
catalogs files from them.</li>
<li>Run either 'make catalogsinstall' or 'make bindcatalogs' to make catalogs
available for application. For more information about differences
between these two commands, please see the next section.</li>
</ol>
<p>Here is also example makefile for the localized_hello.cpp above:</p>
<p><em>makefile</em>:</p>
<pre><code>NAME = hello
TYPE = APP
APP_MIME_SIG = x.vnd-example-hello
SRCS = localized_hello.cpp
LIBS = locale localestub
LOCALES = en de fr
include $(BUILDHOME)/etc/makefile-engine
</code></pre>
<div id="targets"><h2>Target Reference</h2></div>
<p>This is supposed to be the list of all non-file related targets.</p>
<ul>
<li><strong>default</strong> is the same as running make without arguments, it builds output
file</li>
<li><strong>catkeys</strong> creates locales/en.catkeys file, containing all strings from
sources, ready to be localized.</li>
<li><strong>catalogs</strong> compiles all .catkeys files into corresponding .catalog files</li>
<li><strong>clean</strong> cleans project directory of building leftovers, removes
everything in the objects folder.</li>
<li><strong>rmapp</strong> removes only the executable application file from objects folder</li>
<li><strong>driverinstall</strong> installs driver into system.</li>
<li><strong>install</strong> installs program into directory, specified by <em>INSTALL_DIR</em>
variable.</li>
<li><strong>catalogsinstall</strong> installs localization resources catalogs into
/boot/home/config/data/locale/catalogs/&lt;APP_MIME_SIG&gt;
directory for testing purposes. Note that for the distribution of
release version catalogs should be stored in
/boot/common/data/locale/catalogs/&lt;APP_MIME_SIG&gt; instead of
home.</li>
<li><strong>bindcatalogs</strong> binds localization resources catalogs into executable
file's resources (it's alternative way of storing localization
catalogs that doesn't require to distribute separate catalog files).</li>
</ul>
<table border="0" width="100%">
<tr>
<td align="left">This How To was created on November 28, 2011 by Peter
Poláčik</td>
<td align="right">Copyright &copy; 2011 Haiku Inc.</td>
</tr>
</table>