<html><head><title>How To Create a Project Using the Makefile Engine</title></head><body><h1>How To Create a Project Using the Makefile Engine</h1><p>Haiku helps developers with the build process of their projects by providing the socalled makefile-engine. It's made of two files, that reside in<tt>/boot/system/develop/etc</tt> directory and are named 'Makefile' and 'makefile-engine'.<br />Together, these two files provide you with a simple ready-to-be used buildengine for your projects.</p><p>This How-To describes the makefile-engine v2.6 and theMakefile template v2.6. Regardless of mentioning the 'makefiles' in thisHow-To, the same technique can be used for creating Jamfile-drivenprojects. Corresponding Jamfile and Jamfile-engine template files are providedwith Haiku. We made both, the Makefile and Jamfile engines completelytarget-compatible for the 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 <tt>/boot/system/develop/etc</tt> directory, intoyour project directory. Write a few files that you want to add to your project. Addeither relative or full paths to them into the SRCS variable definition in theMakefile and run <tt>make</tt>. Example files for a "Hello World" project:</p><p><em>hello.cpp</em>:</p><pre><code>#include <stdio.h>int main(void){printf("Hello world!\n");return 0;}</code></pre><p><em>Makefile</em>:</p><pre><code>NAME = helloTYPE = APPSRCS = hello.cpp## Include the Makefile-EngineDEVEL_DIRECTORY := \$(shell findpaths -r "makefile_engine" B_FIND_PATH_DEVELOP_DIRECTORY)include $(DEVEL_DIRECTORY)/etc/makefile-engine</code></pre><p>After creating both these files in same directory, just go there in Terminal,using the '<tt>cd</tt>' command and run '<tt>make</tt>'. This will create a new directory,named in the format: 'objects.x86-cc2-release' (the name depends on current compiler,that may be either "cc2" or "cc4", and defining DEBUG will force using"debug" instead of "release"), which will contain .o files (onefor each source file), .d files with dependencies, generated automatically bythe 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 yourneeds. 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 the application's mime signature forlocalization features. Note that it should correspond to MIME typeprovided to the BApplication's constructor and the application MIME typedefined in resource file. In case this parameter is not set, thedefault value '<tt>x-vnd.Haiku-$(NAME)</tt>' will be used.</li><li><strong>SRCS</strong> specifies the source files to use. You may specify both, fullpaths and paths relative to the location of the Makefile. All objects,regardless of the location of their sources will be created in thecommon object directory. Please note, that this means, that the Makefilewon't work correctly, if two source files with the same name(e.g. <tt>source.c</tt> and <tt>source.cpp</tt>) are included from differentdirectories. Also note, that spaces in folder names do not work wellwith the engine.</li><li><strong>RDEFS</strong> specifies the resource definition files to be used. You mayspecify both, relative and full paths to the files.</li><li><strong>RSRCS</strong> specifies the binary file compiled from <em>RDEF</em>, or createdseparately by resource editors. Both <em>RDEFS</em> and <em>RSRCS</em> can bedefined in the same Makefile.</li><li><strong>LIBS</strong> specifies additional libraries, that the binary file should belinked against. There are two acceptable forms of library specifications:<ul><li>if your library follows the naming pattern of <tt>libXXX.so</tt> or <tt>libXXX.a</tt>,you can simply specify XXX, e.g. for the library <tt>libbe.so</tt>, that would be:<tt>be</tt></li><li>for version-independent linking of standard C++ libraries, pleaseadd <tt>$(STDCPPLIBS</tt> instead of raw "<tt>stdc++[.r4] [supc++]</tt>" library names</li><li>for localization support add the following libraries: <tt>locale</tt> <tt>localestub</tt></li><li>if your library doesn't follow the standard library namingscheme, you need to specify the path to the library and its name, e.g.for the library: <tt>my_lib.a</tt>, the entry would be either: <tt>my_lib.a</tt> or<tt>path/my_lib.a</tt></li></ul></li><li><strong>LIBPATHS</strong> specifies additional paths to directories following thestandard <tt>libXXX.so</tt> or <tt>libXXX.a</tt> naming scheme. You can specify both,full paths or paths relative to the Makefile. The paths included maynot be recursive, so include all the 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 systemheaders. These use the form: <tt>#include <header></tt>. Source filedirectories are <em>NOT</em> automatically included here.</li><li><strong>LOCAL_INCLUDE_PATHS</strong> specifies additional paths to look for localheaders. There use the form: <tt>#include "header"</tt>. Source filedirectories are automatically included.</li><li><strong>OPTIMIZE</strong> specifies the level of optimization desired, can be one offollowing: <em>NONE</em>, <em>SOME</em>, <em>FULL</em>.</li><li><strong>LOCALES</strong> specifies language codes, that are going to be supportedby application. The default "en" one must be provided too. For moreinformation about localization, see the corresponding section of thishow-to.</li><li><strong>DEFINES</strong> specifies any preprocessor symbols to be defined. The symbolswill not have their values set automatically, you have to providethese values (if any). For example, setting <em>DEFINES</em> to "<tt>DEBUG=1</tt>" willcause the compiler option "<tt>-DDEBUG=1</tt>" to be used. However, setting<em>DEFINES</em> to "<tt>DEBUG</tt>" would pass "<tt>-DDEBUG</tt>" option.</li><li><strong>WARNINGS</strong> specifies the level of warnings reported by compiler. If thisoption is unspecified, the default warnings will be used. It can beset 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 thestack 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 allowsthe 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. -app3 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 desiredlocation of driver in the /dev hierarchy. It's user by thedriverinstall rule. E.g. <em>DRIVER_PATH</em> = video/usb will instructthe driverinstall rule to place a symlink to your driver's binary into<tt>~/config/non-packaged/add-ons/kernel/drivers/dev/video/usb</tt>, so that your driver willappear in <tt>/dev/video/usb</tt> 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 thisengine, last lines must contain:</p><pre><code>DEVEL_DIRECTORY := \$(shell findpaths -r "makefile_engine" B_FIND_PATH_DEVELOP_DIRECTORY)include $(DEVEL_DIRECTORY)/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 <stdio.h>#include <Catalog.h>#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 <tt>Catalog.h</tt>, that belongs to locale library. So toactually be able to use localization in your programs, you have to adjust fewsettings in your Makefile.</p><ol><li><p>Adjust a value to your project's <strong>APP_MIME_SIG</strong> variable.Application's mime signature should also be set in the followingformat: <tt>x.vnd-<author>-<project_name></tt></p></li><li><p>Add following two libraries into your <strong>LIBS</strong> variable: <tt>locale</tt><tt>localestub</tt></p></li><li><p>Add every language, that you want to support, into <strong>LOCALES</strong> variable,e.g. '<tt>LOCALES = en de fr</tt>' for English, German and French localesupport.</p></li><li><p>Add the resource definition script (also specified in the <em>RDEF</em>variable) containing the following entries to project:</p><pre>resource app_signature "application/x-vnd.<author>-<project_name>";resource app_name_catalog_entry "<author>-<project_name>:System name:Terminal";</pre></li><li><p>Run '<tt>make</tt>' to build the binary file.</p></li><li><p>Run '<tt>make catkeys</tt>' to get the <tt>locales/en.catkeys</tt> file.</p></li><li><p>Copy this file to <tt>locales/<language_code>.catkeys</tt> and translate it,as needed.</p></li><li><p>When you've prepared all needed .catkeys files, run '<tt>make catalogs</tt>' to createcatalog files from them.</p></li><li><p>Run either '<tt>make catalogsinstall</tt>' or '<tt>make bindcatalogs</tt>' to make the catalogsavailable for the application. For more information about differencesbetween these two commands, please see the next section.</p></li></ol><p>Here is an example Makefile for the <tt>localized_hello.cpp</tt> above:</p><p><em>Makefile</em>:</p><pre><code>NAME = helloTYPE = APPAPP_MIME_SIG = x-vnd.example-helloSRCS = localized_hello.cppLIBS = locale localestubLOCALES = en de fr## Include the Makefile-EngineDEVEL_DIRECTORY := \$(shell findpaths -r "makefile_engine" B_FIND_PATH_DEVELOP_DIRECTORY)include $(DEVEL_DIRECTORY)/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 <tt>make</tt> without arguments, it builds theoutputfile</li><li><strong>catkeys</strong> creates the <tt>locales/en.catkeys</tt> file, containing all strings fromthe sources, ready to be localized.</li><li><strong>catalogs</strong> compiles all .catkeys files into corresponding .catalog files</li><li><strong>clean</strong> cleans the project directory of building leftovers, removeseverything in the objects folder.</li><li><strong>rmapp</strong> removes only the executable application file from the objects folder</li><li><strong>driverinstall</strong> installs the driver in the system.</li><li><strong>install</strong> installs the program into the directory specified by the <em>INSTALL_DIR</em>variable.</li><li><strong>catalogsinstall</strong> installs localization resource catalogs into<tt>/boot/home/config/non-packaged/data/locale/catalogs/<APP_MIME_SIG></tt>for testing purposes. Note that for the distribution of a release version, catalogs should be stored in<tt>/boot/system/non-packaged/data/locale/catalogs/<APP_MIME_SIG></tt> instead ofhome. Even better, create a proper HPKG and don't install in any non-packaged folder at all.</li><li><strong>bindcatalogs</strong> binds localization resource catalogs into the executablefile's resources (it's an alternative way of storing localizationcatalogs that doesn't require to distribute separate catalog files).</li></ul><table border="0" width="100%"><tr><td align="left">This How-To was originally created on November 28, 2011 by PeterPolรกฤik</td><td align="right">Copyright © 2017 Haiku Inc.</td></tr></table></body></html>