| 1 | ----------------------------------------------------------------------- |
| 2 | Creating a Cross-Platform Build System Using Bakefile |
| 3 | The 10-minute, do-it-yourself wx project baking guide (with free sample recipes!) |
| 4 | |
| 5 | Status: DRAFT |
| 6 | Author: Kevin Ollivier |
| 7 | Date: 2/13/04 |
| 8 | License: wxWidgets License |
| 9 | ----------------------------------------------------------------------- |
| 10 | |
| 11 | Supporting many different platforms can be a difficult challenge. The |
| 12 | challenge for wxWidgets is especially great, because it supports a variety of |
| 13 | different compilers and development environments, including MSVC, Borland C++, |
| 14 | MinGW, DevCPP, GNU make/automake, among others. Maintaining such a large |
| 15 | number of different project files and formats can quickly become overwhelming. |
| 16 | To simplify the maintenance of these formats, one of the wxWidgets developers, |
| 17 | Vaclav Slavik, created Bakefile, a XML-based makefile wrapper that generates |
| 18 | all the native project files for wxWidgets. So now, even though wxWidgets |
| 19 | supports all these formats, wxWidgets developers need only update one file - |
| 20 | the Bakefile, and it handles the rest. But Bakefile isn't specific to |
| 21 | wxWidgets in any way - you can use Bakefile for your own projects, too. This |
| 22 | brief tutorial will take a look at how to do that. |
| 23 | |
| 24 | Note that this tutorial assumes that you are familiar with how to build |
| 25 | software using one of the supported Bakefile makefile systems, that you have |
| 26 | some basic familiarity with how makefiles work, and that you are capable of |
| 27 | setting environment variables on your platform. Also note that the terms Unix |
| 28 | and Unix-based refers to all operating systems that share a Unix heritage, |
| 29 | including FreeBSD, Linux, Mac OS X, and various other operating systems. |
| 30 | |
| 31 | -- Getting Started -- |
| 32 | |
| 33 | First, you'll need to install Bakefile. You can always find the latest version |
| 34 | for download online at http://www.bakefile.org. A binary installer is provided |
| 35 | for Windows users, while users of Unix-based operating systems (OS) will need |
| 36 | to unpack the tarball and run configure && make && make install. (binary |
| 37 | packages for some Linux distributions are also available, check |
| 38 | http://www.bakefile.org/download.html for details). |
| 39 | |
| 40 | -- Setting Up Your wx Build Environment -- |
| 41 | |
| 42 | Before you can build wxWidgets software using Bakefile or any other build |
| 43 | system, you need to make sure that wxWidgets is built and that wxWidgets |
| 44 | projects can find the wxWidgets includes and library files. wxWidgets build |
| 45 | instructions can be found by going to the docs subfolder, then looking for the |
| 46 | subfolder that corresponds to your platform (i.e. msw, gtk, mac) and reading |
| 47 | "install.txt" there. Once you've done that, here are some extra steps you |
| 48 | should take to make sure your Bakefile projects work with wxWidgets: |
| 49 | |
| 50 | On Windows |
| 51 | ---------- |
| 52 | Once you've built wxWidgets, you should create an environment variable named |
| 53 | WXWIN and set it to the home folder of your wxWidgets source tree. (If you use |
| 54 | the command line to build, you can also set or override WXWIN at build time by |
| 55 | passing it in as an option to your makefile.) |
| 56 | |
| 57 | On Unix |
| 58 | ------- |
| 59 | In a standard install, you need not do anything so long as wx-config is on |
| 60 | your PATH. wx-config is all you need. (See the section of the book on using |
| 61 | wx-config for more information.) |
| 62 | |
| 63 | -- A Sample wx Project Bakefile -- |
| 64 | |
| 65 | Now that everything is setup, it's time to take Bakefile for a test run. I |
| 66 | recommend that you use the wx sample Bakefile to get you started. It can be |
| 67 | found in the 'build/bakefiles/wxpresets/sample' directory in the wxWidgets |
| 68 | source tree. Here is the minimal.bkl Bakefile used in the sample: |
| 69 | |
| 70 | minimal.bkl |
| 71 | ------------------------------------------------------------- |
| 72 | <?xml version="1.0" ?> |
| 73 | <!-- $Id$ --> |
| 74 | |
| 75 | <makefile> |
| 76 | |
| 77 | <include file="presets/wx.bkl"/> |
| 78 | |
| 79 | <exe id="minimal" template="wxgui"> |
| 80 | <debug-info>on</debug-info> |
| 81 | <runtime-libs>dynamic</runtime-libs> |
| 82 | |
| 83 | <sources>minimal.cpp</sources> |
| 84 | |
| 85 | <wx-lib>core</wx-lib> |
| 86 | <wx-lib>base</wx-lib> |
| 87 | </exe> |
| 88 | |
| 89 | </makefile> |
| 90 | --------------------------------------------------------------- |
| 91 | |
| 92 | It's a complete sample ready to be baked, so go into the directory mentioned |
| 93 | above and run the following command: |
| 94 | |
| 95 | On Windows: |
| 96 | bakefile -f msvc -I.. minimal.bkl |
| 97 | |
| 98 | On Unix: |
| 99 | bakefile -f gnu -I.. minimal.bkl |
| 100 | |
| 101 | It should generate a makefile (makefile.vc or GNUmakefile, respectively) which |
| 102 | you can use to build the software. Just build the software using the command |
| 103 | "nmake -f makefile.vc" or "make -f GNUmakefile" respectively. Now let's take a |
| 104 | look at some of the basic Bakefile concepts that you'll need to know to move |
| 105 | on from here. |
| 106 | |
| 107 | -- Project Types -- |
| 108 | |
| 109 | As mentioned earlier, Bakefile builds makefiles for many different |
| 110 | development environments. The -f option accepts a list of formats that you |
| 111 | would like to build, separated by commas. Valid values are: |
| 112 | |
| 113 | autoconf GNU autoconf Makefile.in files |
| 114 | borland Borland C/C++ makefiles |
| 115 | dmars Digital Mars makefiles |
| 116 | dmars_smake Digital Mars makefiles for SMAKE |
| 117 | gnu GNU toolchain makefiles (Unix) |
| 118 | mingw MinGW makefiles (mingw32-make) |
| 119 | msevc4prj MS eMbedded Visual C++ 4 project files |
| 120 | msvc MS Visual C++ nmake makefiles |
| 121 | msvc6prj MS Visual C++ 6.0 project files |
| 122 | watcom OpenWatcom makefiles |
| 123 | |
| 124 | TIP: autoconf Project Type |
| 125 | --------------------------- |
| 126 | You may notice that in the sample folder, there is also a file called |
| 127 | configure.in. That file is the input for autoconf, which creates the configure |
| 128 | scripts that you often see when you build software from source on Unix-based |
| 129 | platforms. People use configure scripts because they make your Unix makefiles |
| 130 | more portable by automatically detecting the right libraries and commands to |
| 131 | use on the user's machine and OS. This is necessary because there are many |
| 132 | Unix-based operating systems and they all are slightly different in various |
| 133 | small ways. |
| 134 | |
| 135 | Bakefile does not generate a configure or configure.in script, so if you want |
| 136 | to use configure scripts with your Unix-based software, you will need to learn |
| 137 | how to use autoconf. Unfortunately, this topic deserves a book all its own and |
| 138 | is beyond the scope of this tutorial, but a book on the subject can be found |
| 139 | online at: http://sources.redhat.com/autobook/. Note that you do not need to |
| 140 | use automake when you are using Bakefile, just autoconf, as Bakefile |
| 141 | essentially does the same thing as automake. |
| 142 | ---------------------------- |
| 143 | |
| 144 | -- Targets -- |
| 145 | |
| 146 | Every project needs to have a target or targets, specifying what is to be |
| 147 | built. In Bakefile, you specify the target by creating a tag named with the |
| 148 | target type. The possible names for targets are: |
| 149 | |
| 150 | exe create an executable file |
| 151 | dll create a shared library |
| 152 | lib create a static library |
| 153 | module create a library that is loaded at runtime (i.e. a plugin) |
| 154 | |
| 155 | Note the sample above is an "exe" target. Once you create the target, all the |
| 156 | build settings, including flags and linker options, should be placed inside |
| 157 | the target tag, as they are in the sample above. |
| 158 | |
| 159 | -- Adding Sources and Includes -- |
| 160 | |
| 161 | Obviously, you need to be able to add source and include files to your |
| 162 | project. You add sources using the "<sources>" tag (as shown above), and add |
| 163 | include directories using the "<include>" tag. You can add multiple <sources> |
| 164 | and <include> tags to add multiple source files, or you can also add multiple |
| 165 | sources and includes into one tag by separating them with a space, like so: |
| 166 | |
| 167 | <sources>minimal.cpp minimal2.cpp minimal3.cpp</sources> |
| 168 | |
| 169 | If your sources are in a subfolder of your Bakefile, you use the slash "/" |
| 170 | character to denote directories, even on Windows. (i.e. src/minimal.cpp) For |
| 171 | more options and flags, please consult the Bakefile documentation in the 'doc' |
| 172 | subfolder of Bakefile, or you can also find it on the Bakefile web site. |
| 173 | |
| 174 | -- Build Options -- |
| 175 | |
| 176 | What if you want to offer a DEBUG and a RELEASE build? Or a UNICODE/ANSI |
| 177 | build? You can do this in Bakefile by creating options. To create an option, |
| 178 | use the "<option>" tag. A typical option has three important parts: a name, a |
| 179 | default value, and a comma-separated list of values. For example, here is how |
| 180 | to create a DEBUG option which builds debug by default: |
| 181 | |
| 182 | <option name="DEBUG"> |
| 183 | <default-value>1</default-value> |
| 184 | <values>0 1</values> |
| 185 | </option> |
| 186 | |
| 187 | You can then test the value of this option and conditionally set build |
| 188 | settings, flags, etc. For more information on both options and conditional |
| 189 | statements, please refer to the Bakefile documentation. |
| 190 | |
| 191 | -- Bakefile Presets/Templates and Includes -- |
| 192 | |
| 193 | It is common that most projects will reuse certain settings, or options, in |
| 194 | their makefiles. (i.e. DEBUG or static/dynamic library options) Also, it is |
| 195 | common to have to use settings from another project; for example, any project |
| 196 | that uses wxWidgets will need to build using the same flags and options that |
| 197 | wxWidgets was built with. Bakefile makes these things easier by allowing users |
| 198 | to create Bakefile templates, where you can store common settings. |
| 199 | |
| 200 | Bakefile ships with a couple of templates, found in the 'presets' subfolder of |
| 201 | your Bakefile installation. The "simple.bkl" template adds a DEBUG option to |
| 202 | makefiles so you can build in release or debug mode. To add this template to |
| 203 | your project, simply add the tag "<include file="presets/simple.bkl"/>" to the |
| 204 | top of your Bakefile. Then, when creating your target, add the |
| 205 | "template="simple"" attribute to it. Now, once you build the makefile, your |
| 206 | users can write commands like: |
| 207 | |
| 208 | nmake -f makefile.vc DEBUG=1 |
| 209 | |
| 210 | or |
| 211 | |
| 212 | make -f GNUmakefile DEBUG=1 |
| 213 | |
| 214 | In order to build the software in debug mode. |
| 215 | |
| 216 | To simplify the building of wxWidgets-based projects, wxWidgets contains a |
| 217 | set of Bakefiles that automatically configure your build system to be |
| 218 | compatible with wxWidgets. As you'll notice in the sample above, the sample |
| 219 | project uses the "wxgui" template. Once you've included the template, your software |
| 220 | will now build as a GUI application with wxWidgets support. |
| 221 | |
| 222 | There's also "wxconsole" template for building console-based wxWidgets applications |
| 223 | and "wx" template that doesn't specify application type (GUI or console) and can be |
| 224 | used e.g. for building libraries that use wxWidgets. |
| 225 | |
| 226 | But since the wx presets don't exist in the Bakefile presets subfolder, |
| 227 | Bakefile needs to know where to find these presets. The "-I" command adds the |
| 228 | wxpresets folder to Bakefile's search path. |
| 229 | |
| 230 | If you regularly include Bakefile presets in places other than the Bakefile |
| 231 | presets folder, then you can set the BAKEFILE_PATHS environment variable so |
| 232 | that Bakefile can find these Bakefiles and include them in your project. This |
| 233 | way you no longer need to specify the -I flag each time you build. |
| 234 | |
| 235 | Lastly, it's important to note that the Win 32 wx project Bakefiles come with |
| 236 | some common build options that users can use when building the software. These |
| 237 | options are: |
| 238 | |
| 239 | Option Values Description |
| 240 | ------ ------ ------------- |
| 241 | WX_MONOLITHIC 0(default),1 Set this to 1 if you built wx |
| 242 | as a monolithic library |
| 243 | WX_SHARED 0(default),1 Specify static or dynamic wx libs |
| 244 | WX_UNICODE 0(default),1 Use ANSI or UNICODE wx libs |
| 245 | WX_DEBUG 0,1(default) Use release or debug wx libs |
| 246 | *WX_VERSION 25,26(default) Specify version of wx libs |
| 247 | |
| 248 | *Note: Any version of wx past 2.5 will be allowed here, so 25/26 is not a |
| 249 | complete list of values. |
| 250 | |
| 251 | These options are not needed under Unix as wx-config can be used to specify |
| 252 | these options. |
| 253 | |
| 254 | -- bakefile_gen - Automated Bakefile Scripts -- |
| 255 | |
| 256 | If you have a large project, you can imagine that the calls to Bakefile would |
| 257 | get more and more complex and unwieldy to manage. For this reason, a script |
| 258 | called bakefile_gen was created, which reads in a .bkgen file that provides |
| 259 | all the commands needed to build all the makefiles your project supports. A |
| 260 | discussion of how to use bakefile_gen is beyond the scope of this tutorial, |
| 261 | but it deserves mention because it can be invaluable to large projects. |
| 262 | Documentation on bakefile_gen can be found in the Bakefile documentation. |
| 263 | |
| 264 | -- Conclusion -- |
| 265 | |
| 266 | This concludes our basic tutorial of the cross-platform Bakefile build system |
| 267 | management tool. From here, please be sure to take a good look at the Bakefile |
| 268 | documentation to see what else it is capable of. Please post questions to the |
| 269 | bakefile-devel@lists.sourceforge.net list, or if you have questions specific |
| 270 | to the wx template Bakefile, send an email to wx-users@lists.wxwidgets.org. |
| 271 | |
| 272 | Enjoy using Bakefile! |