# Tutorial

## Hello, world

By far the simplest way to generate makefiles using Bakefile is to use so-called presets which are prepared skeletons of bakefiles that get you started quickly. Let's see how it works on an example of the famous Hello, world program written in C and implemented in the `hello.c` file:

    #include <stdio.h>

    int main()
    {
      printf("Hello, world!\n");
      return 0;
    }

The bakefile needed to compile it,`hello.bkl`, looks like this:

    <?xml version="1.0"?>
    <makefile>

      <include file="presets/simple.bkl"/>

      <exe id="hello" template="simple">
        <sources>hello.c</sources>
      </exe>

    </makefile>

Presets are included using the directive. The structure of the file name is always the same: `presets/NAME-OF-PRESET.bkl`. In general, you can combine several presets, but in practice you must be careful when doing so. It's always a good idea to read the code for the preset before using it. The "simple" preset we include here defines a `DEBUG` option and a template called `simple`. Generated makefiles will allow the user to build all targets that are based on this template as either debug or release build.

Let's generate some makefiles now. The `bakefile` command is used to do it. For example:

$ `bakefile -f msvc hello.bkl`

That's all. This will creates VC++ makefile `makefile.vc`. Of course, you can change the name of output file if you don't like the default:

$ `bakefile -f msvc -o makefile hello.bkl`

Bakefile will also generate the `Makefile.in` files used by Autoconf:

$ `bakefile -f autoconf hello.bkl`

These are templates for makefiles. Autoconf also requires a `configure.ac` script (previously, `configure.in`), but Bakefile will not generate this for you. This script checks for platform features necessary to build the program; see the autoconf manual for details.

When producing autoconf format output, Bakefile will also generate a file called `autoconf_inc.m4` which defines macros needed by the generated Makefile.in files. To use this, call the `AC_BAKEFILE` macro within your `configure.ac` script.

A minimal `configure.ac` script for our example program would look like this:

    AC_PREREQ(2.53)
    AC_INIT([hello], [1.0], [author@example.com])
    dnl pass some unique file file to AC_CONFIG_SRCDIR
    AC_CONFIG_SRCDIR([autoconf_inc.m4])
    AC_CANONICAL_HOST
    DEBUG=0
    AC_BAKEFILE([m4_include(autoconf_inc.m4)])
    AC_CONFIG_FILES([Makefile])
    AC_OUTPUT

Note the part that sets the `DEBUG` variable. Any options declared in your bakefile must be set to some default value before calling `AC_BAKEFILE`. The simple.bkl preset defines the `DEBUG` option, so we have to give it a default value here.

While the above code will work, there's a better way to handle the debug option:

    AC_PREREQ(2.53)
    AC_INIT([hello], [1.0], [author@example.com])
    dnl pass some unique file file to AC_CONFIG_SRCDIR
    AC_CONFIG_SRCDIR([autoconf_inc.m4])
    AC_CANONICAL_HOST

    AC_ARG_ENABLE(debug,
                  [  --enable-debug          Enable debugging information],
                  USE_DEBUG="$enableval", USE_DEBUG="no")

    if test $USE_DEBUG = yes ; then
      DEBUG=1
      dnl Bakefile doesn't touch {C,CPP,CXX,LD}FLAGS in autoconf format, we
      dnl have to do it ourselves. This will work with many compilers
      dnl (but not all, proper configure script would check if the compiler
      dnl supports it):
      CFLAGS="$CFLAGS -g"
    else
      DEBUG=0
    fi

    AC_BAKEFILE([m4_include(autoconf_inc.m4)])
    AC_CONFIG_FILES([Makefile])
    AC_OUTPUT

You are ready to generate Autoconf's `configure` script now:

$ `bakefilize --copy && aclocal && autoconf`