1<html> 2<head> 3 <title>How To Create a Project Using the Makefile Engine</title> 4</head> 5<body> 6<h1>How To Create a Project Using the Makefile Engine</h1> 7 8<p>Haiku helps developers with the build process of their projects by providing the so 9called makefile-engine. It's made of two files, that reside in 10<tt>/boot/system/develop/etc</tt> directory and are named 'Makefile' and 'makefile-engine'.<br /> 11Together, these two files provide you with a simple ready-to-be used build 12engine for your projects.</p> 13 14<p>This How-To describes the makefile-engine v2.6 and the 15Makefile template v2.6. Regardless of mentioning the 'makefiles' in this 16How-To, the same technique can be used for creating Jamfile-driven 17projects. Corresponding Jamfile and Jamfile-engine template files are provided 18with Haiku. We made both, the Makefile and Jamfile engines completely 19target-compatible for the user's convenience.</p> 20 21<h2>Contents</h2> 22<p> 23<ul> 24 <li><a href="#getting_started">Getting Started</a></li> 25 <li><a href="#config">Configuring a Project</a></li> 26 <li><a href="#localization">Using Localization</a></li> 27 <li><a href="#targets">Target Reference</a></li> 28</ul> 29</p> 30 31<div id="getting_started"><h2>Getting Started</h2></div> 32 33<p>To start a project, just copy Makefile from <tt>/boot/system/develop/etc</tt> directory, into 34your project directory. Write a few files that you want to add to your project. Add 35either relative or full paths to them into the SRCS variable definition in the 36Makefile and run <tt>make</tt>. Example files for a "Hello World" project:</p> 37 38<p><em>hello.cpp</em>:</p> 39 40<pre><code>#include <stdio.h> 41 42int main(void) 43{ 44 printf("Hello world!\n"); 45 return 0; 46} 47</code></pre> 48 49<p><em>Makefile</em>:</p> 50 51<pre><code>NAME = hello 52TYPE = APP 53SRCS = hello.cpp 54 55## Include the Makefile-Engine 56DEVEL_DIRECTORY := \ 57 $(shell findpaths -r "makefile_engine" B_FIND_PATH_DEVELOP_DIRECTORY) 58include $(DEVEL_DIRECTORY)/etc/makefile-engine 59</code></pre> 60 61<p>After creating both these files in same directory, just go there in Terminal, 62using the '<tt>cd</tt>' command and run '<tt>make</tt>'. This will create a new directory, 63named in the format: 'objects.x86-cc2-release' (the name depends on current compiler, 64that may be either "cc2" or "cc4", and defining DEBUG will force using 65"debug" instead of "release"), which will contain .o files (one 66for each source file), .d files with dependencies, generated automatically by 67the engine and a binary file, named 'hello' for the example case above.</p> 68 69<div id="config"><h2>Configuring a Project</h2></div> 70 71<p>In Makefile, there are many variables to configure builder helpers for your 72needs. Let's take a look at them:</p> 73 74<ul> 75<li><strong>NAME</strong> specifies the name of the project and the output binary filename</li> 76<li><strong>TYPE</strong> specifies the type of binary, can be one of the following: 77<ul> 78<li><strong>APP</strong> - Application</li> 79<li><strong>SHARED</strong> - Shared library or add-on</li> 80<li><strong>STATIC</strong> - Static library archive</li> 81<li><strong>DRIVER</strong> - Kernel driver</li> 82</ul></li> 83<li><strong>APP_MIME_SIG</strong> specifies the application's mime signature for 84localization features. Note that it should correspond to MIME type 85provided to the BApplication's constructor and the application MIME type 86defined in resource file. In case this parameter is not set, the 87default value '<tt>x-vnd.Haiku-$(NAME)</tt>' will be used.</li> 88<li><strong>SRCS</strong> specifies the source files to use. You may specify both, full 89paths and paths relative to the location of the Makefile. All objects, 90regardless of the location of their sources will be created in the 91common object directory. Please note, that this means, that the Makefile 92won't work correctly, if two source files with the same name 93(e.g. <tt>source.c</tt> and <tt>source.cpp</tt>) are included from different 94directories. Also note, that spaces in folder names do not work well 95with the engine.</li> 96<li><strong>RDEFS</strong> specifies the resource definition files to be used. You may 97specify both, relative and full paths to the files.</li> 98<li><strong>RSRCS</strong> specifies the binary file compiled from <em>RDEF</em>, or created 99separately by resource editors. Both <em>RDEFS</em> and <em>RSRCS</em> can be 100defined in the same Makefile.</li> 101<li><strong>LIBS</strong> specifies additional libraries, that the binary file should be 102linked against. There are two acceptable forms of library specifications: 103<ul> 104<li>if your library follows the naming pattern of <tt>libXXX.so</tt> or <tt>libXXX.a</tt>, 105you can simply specify XXX, e.g. for the library <tt>libbe.so</tt>, that would be: 106<tt>be</tt></li> 107<li>for version-independent linking of standard C++ libraries, please 108add <tt>$(STDCPPLIBS</tt> instead of raw "<tt>stdc++[.r4] [supc++]</tt>" library names</li> 109<li>for localization support add the following libraries: <tt>locale</tt> <tt>localestub</tt></li> 110<li>if your library doesn't follow the standard library naming 111scheme, you need to specify the path to the library and its name, e.g. 112for the library: <tt>my_lib.a</tt>, the entry would be either: <tt>my_lib.a</tt> or 113<tt>path/my_lib.a</tt></li> 114</ul></li> 115<li><strong>LIBPATHS</strong> specifies additional paths to directories following the 116standard <tt>libXXX.so</tt> or <tt>libXXX.a</tt> naming scheme. You can specify both, 117full paths or paths relative to the Makefile. The paths included may 118not be recursive, so include all the paths where libraries can be found. 119Directories where source files are found are automatically included.</li> 120<li><strong>SYSTEM_INCLUDE_PATHS</strong> specifies additional paths to look for system 121headers. These use the form: <tt>#include <header></tt>. Source file 122directories are <em>NOT</em> automatically included here.</li> 123<li><strong>LOCAL_INCLUDE_PATHS</strong> specifies additional paths to look for local 124headers. There use the form: <tt>#include "header"</tt>. Source file 125directories are automatically included.</li> 126<li><strong>OPTIMIZE</strong> specifies the level of optimization desired, can be one of 127following: <em>NONE</em>, <em>SOME</em>, <em>FULL</em>.</li> 128<li><strong>LOCALES</strong> specifies language codes, that are going to be supported 129by application. The default "en" one must be provided too. For more 130information about localization, see the corresponding section of this 131how-to.</li> 132<li><strong>DEFINES</strong> specifies any preprocessor symbols to be defined. The symbols 133will not have their values set automatically, you have to provide 134these values (if any). For example, setting <em>DEFINES</em> to "<tt>DEBUG=1</tt>" will 135cause the compiler option "<tt>-DDEBUG=1</tt>" to be used. However, setting 136<em>DEFINES</em> to "<tt>DEBUG</tt>" would pass "<tt>-DDEBUG</tt>" option.</li> 137<li><strong>WARNINGS</strong> specifies the level of warnings reported by compiler. If this 138option is unspecified, the default warnings will be used. It can be 139set to one of the following: 140<ul> 141<li>NONE - supress all warnings</li> 142<li>ALL - enable all warnings</li> 143</ul></li> 144<li><strong>SYMBOLS</strong> specifies, whether image symbols should be created, so the 145stack crawls in the debugger are meaningful. Setting it to <em>TRUE</em> 146enables the creation of symbols.</li> 147<li><strong>DEBUGGER</strong> specifies debugging settings. If set to <em>TRUE</em>, it allows 148the application to be run from a source-level debugger. Please note, 149that this will disable all optimization.</li> 150<li><strong>COMPILER_FLAGS</strong> specifies additional compiler flags for all files.</li> 151<li><strong>LINKER_FLAGS</strong> specifies additional linker flags.</li> 152<li><strong>APP_VERSION</strong> specifies the version of the particular item (e.g. -app 1533 4 0 d 0 -short 340 -long "340 "<code>echo -n -e '\302\251'</code>). 154"1999 GNU GPL"). This may also be specified in a resource.</li> 155<li><strong>DRIVER_PATH</strong> works only for <em>TYPE</em> == <em>DRIVER</em>. It specifies desired 156location of driver in the /dev hierarchy. It's user by the 157driverinstall rule. E.g. <em>DRIVER_PATH</em> = video/usb will instruct 158the driverinstall rule to place a symlink to your driver's binary into 159<tt>~/config/non-packaged/add-ons/kernel/drivers/dev/video/usb</tt>, so that your driver will 160appear in <tt>/dev/video/usb</tt> when loaded. Default is "misc".</li> 161<li><strong>INSTALL_DIR</strong> specifies the installation directory of application.</li> 162</ul> 163 164<p>Please also note, that if you're building your own Makefile, that will use this 165engine, last lines must contain:</p> 166 167<pre><code>DEVEL_DIRECTORY := \ 168 $(shell findpaths -r "makefile_engine" B_FIND_PATH_DEVELOP_DIRECTORY) 169include $(DEVEL_DIRECTORY)/etc/makefile-engine 170</code></pre> 171 172<div id="localization"><h2>Using Localization</h2></div> 173 174<p>Localization in Haiku programs is achieved simply, as following example shows.</p> 175 176<p><em>localized_hello.cpp</em>:</p> 177 178<pre><code>#include <stdio.h> 179#include <Catalog.h> 180 181#undef B_TRANSLATION_CONTEXT 182#define B_TRANSLATION_CONTEXT "hello" 183 184int main(void) 185{ 186 printf(B_TRANSLATE("Hello, world!\n")); 187 return 0; 188} 189</code></pre> 190 191<p>This file uses header file <tt>Catalog.h</tt>, that belongs to locale library. So to 192actually be able to use localization in your programs, you have to adjust few 193settings in your Makefile.</p> 194 195<ol> 196<li><p>Adjust a value to your project's <strong>APP_MIME_SIG</strong> variable. 197Application's mime signature should also be set in the following 198format: <tt>x.vnd-<author>-<project_name></tt></p></li> 199<li><p>Add following two libraries into your <strong>LIBS</strong> variable: <tt>locale</tt> 200<tt>localestub</tt></p></li> 201<li><p>Add every language, that you want to support, into <strong>LOCALES</strong> variable, 202e.g. '<tt>LOCALES = en de fr</tt>' for English, German and French locale 203support.</p></li> 204<li><p>Add the resource definition script (also specified in the <em>RDEF</em> 205variable) containing the following entries to project:</p> 206 207<pre>resource app_signature "application/x-vnd.<author>-<project_name>"; 208resource app_name_catalog_entry "<author>-<project_name>:System name:Terminal";</pre></li> 209<li><p>Run '<tt>make</tt>' to build the binary file.</p></li> 210<li><p>Run '<tt>make catkeys</tt>' to get the <tt>locales/en.catkeys</tt> file.</p></li> 211<li><p>Copy this file to <tt>locales/<language_code>.catkeys</tt> and translate it, 212as needed.</p></li> 213<li><p>When you've prepared all needed .catkeys files, run '<tt>make catalogs</tt>' to create 214catalog files from them.</p></li> 215<li><p>Run either '<tt>make catalogsinstall</tt>' or '<tt>make bindcatalogs</tt>' to make the catalogs 216available for the application. For more information about differences 217between these two commands, please see the next section.</p></li> 218</ol> 219 220<p>Here is an example Makefile for the <tt>localized_hello.cpp</tt> above:</p> 221 222<p><em>Makefile</em>:</p> 223 224<pre><code>NAME = hello 225TYPE = APP 226APP_MIME_SIG = x-vnd.example-hello 227SRCS = localized_hello.cpp 228LIBS = locale localestub 229LOCALES = en de fr 230 231## Include the Makefile-Engine 232DEVEL_DIRECTORY := \ 233 $(shell findpaths -r "makefile_engine" B_FIND_PATH_DEVELOP_DIRECTORY) 234include $(DEVEL_DIRECTORY)/etc/makefile-engine 235</code></pre> 236 237<div id="targets"><h2>Target Reference</h2></div> 238 239<p>This is supposed to be the list of all non-file related targets.</p> 240 241<ul> 242<li><strong>default</strong> is the same as running <tt>make</tt> without arguments, it builds theoutput 243file</li> 244<li><strong>catkeys</strong> creates the <tt>locales/en.catkeys</tt> file, containing all strings from 245the sources, ready to be localized.</li> 246<li><strong>catalogs</strong> compiles all .catkeys files into corresponding .catalog files</li> 247<li><strong>clean</strong> cleans the project directory of building leftovers, removes 248everything in the objects folder.</li> 249<li><strong>rmapp</strong> removes only the executable application file from the objects folder</li> 250<li><strong>driverinstall</strong> installs the driver in the system.</li> 251<li><strong>install</strong> installs the program into the directory specified by the <em>INSTALL_DIR</em> 252variable.</li> 253<li><strong>catalogsinstall</strong> installs localization resource catalogs into 254<tt>/boot/home/config/non-packaged/data/locale/catalogs/<APP_MIME_SIG></tt> 255for testing purposes. Note that for the distribution of a release version, catalogs should be stored in 256<tt>/boot/system/non-packaged/data/locale/catalogs/<APP_MIME_SIG></tt> instead of 257home. Even better, create a proper HPKG and don't install in any non-packaged folder at all.</li> 258<li><strong>bindcatalogs</strong> binds localization resource catalogs into the executable 259file's resources (it's an alternative way of storing localization 260catalogs that doesn't require to distribute separate catalog files).</li> 261</ul> 262 263<table border="0" width="100%"> 264<tr> 265<td align="left">This How-To was originally created on November 28, 2011 by Peter 266Poláčik</td> 267<td align="right">Copyright © 2017 Haiku Inc.</td> 268</tr> 269</table> 270</body> 271</html> 272