On 10 December 2016 at 13:33, Geert Janssens <geert.gnuc...@kobaltwit.be> wrote: > ... > I agree the complete details of autogen/configure/make are fairly complex. I > don't even understand all of it myself. The complexity stems from the design > idea to create a build system that's generic enough to build all kinds of > objects (applications, libraries, documentation, websites, whatever) on as > many different platforms as possible. Luckily we don't need all of this > complexity for our purposes. > > Let me try to explain this top to bottom. The command we're ultimately > interested in is 'make'. This command follows recipes to convert some source > files into some end object(s). For gnucash this is a bunch of c and guile > sources which are transformed into the gnucash application (which itself is > composed of an executable and lots of libraries). There are lots of details > I'm glossing over here, focusing mostly on the principles. > > For our docs plain make (without explicit target that is) does nothing, > because the xml files are both the source and the target which yelp needs to > display the docs. > > However aside from the main target one can also define alternative targets. A > few spring to mind for the docs: html, pdf, mobi, epub, install. So one could > run > make pdf > and make will search a recipe to build one or more pdf files, depending on > which directory you execute the command in. > > 'install' is a special recipe that is intended to put whatever make built as > primary target (the xml files in case of the docs, which are the same as the > source xml files) in a special location where a typical unix system expects > these files. For example, executables typically should be installed in > /usr/bin on linux. This location can be overridden. I'll get back to this > later. > > Where does make find all these recipes ? > make looks for a file called Makefile in the current directory. Makefile holds > the recipes and other configuration items. Unfortunately this file is very > complex in itself because - as I said earlier - the build system is designed > to work in very different environments. > For example the location of all the tools needed to create targets from the > source files (like xsltproc) may be installed in different locations on > different platforms, or even have a different name (like xsltproc.exe in a > Windows environment). Or some commandline options for certain tools may not > be available on all platforms or versions of the tool. Manually coping with > all these variations will quickly result in a mess. > > So to cope with this a configuration step was added to the build process. This > step runs a very complicated script called "configure" that will analyze your > system and actually creates the Makefile files I described above. configure > will lookup installation location for all tools used and can enable or disable > certain recipes in the Makefiles based on its findings. "configure" can also > take extra commandline options that can alter what it will include in the > Makefiles. You can see these options by running configure --help. Most of them > are not relevant for us, except for the few we invented ourselves like > --with-mobi. > > "configure" doesn't take Makefile's as input. Instead it will read files > called Makefile.in, which is a pseudo Makefile with lots or variables that > still need final setting. > > Still, writing a configure script and Makefile.in files remains very > cumbersome and lots of information in both files comes back all the time in > different projects. So yet another step was added before in the build system. > This step is meant to generate the configure script and the Makefile.in files > based on another set of files: configure.ac and Makefile.am files. > These files encode the essence of configure and the final Makefiles, but with > everything removed that can be detected by a smart configuration script. Only > the details that matter and are unique for each project are retained in these > files. > Generating configure and the various Makefile.in files involve a few steps, > but they are always the same, regardless of the platform you run them on. For > this reason they are combined together in a small script called autogen.sh. > This script itself is the platform independent and is used to initiate the > whole build system for a given project. > > And that's the general idea behind the autotools based build system. Again I > glossed over a lot of details. > > As a rule of thumb, autogen.sh should be called the first time you want to > initialize the build system and sometimes when changes are made in > configure.ac or the Makefile.am files. Frequently those changes are > autodetected though. Calling autogen.sh when it's not necessary doesn't doe > harm either way. The only side effect is that the first next build may take > longer. > > The same goes for "configure". It should generally be called right after > autogen.sh for the same reasons. And same here, calling it while not really > required has no negative side-effect other than that the first next build may > take longer because more objects will be rebuilt. > > Lastly, make is the command you'll want to call after each change in the > sources you want reflected in the targets. > > > Now on to directories. In a build system there are three important > directories: > - the source directory > - the build directory > - the installation directory (which can also be more than one directory all > under a special directory called the prefix-directory) > > The source directory should be clear - it's where your source files are. > gnucash-docs (the clone of our github repository) with all its subdirectories > on your system for documentation. If you want to make changes to the > documentaiton, you do this in the source directory. > > The build directory is a directory used by the build system to store all > files/objects that are generated by the build system.*make is always executed > in the build directory*. Each make recipe results in at least one such file or > object. > Without any extra steps, the build directory will be the same as the source > directory. So if you build the html files for the English guide for example, > these files will be put next to the xml files for that guide in the source > directory (although the recipe will put them in a subdirectory as a > convenience). > If you don't want this (and it's generally recommended *not* to build in the > source directory directly for various reasons), you can also choose to work > with a separate build directory. The way to do this is a bit unusual but very > simple once you understand it: configure will use the directory from which > it's called as the build directory. An example will help here: > Assume you have cloned the gnucash-docs repository here: > /home/user/gnucash/gnucash-docs > and want to use > /home/user/gnucash/gnucash-docs/build > as build directory > > Then first run autogen.sh in /home/user/gnucash/gnucash-docs as follows > cd /home/user/gnucash/gnucash-docs > ./autogen.sh > This ensures the configure script is generated. Now create the directory you > want to use as build directory > mkdir /home/user/gnucash/gnucash-docs/build > Note that "build" is purely arbitrary. It can be whatever suits you, and even > wherever it suits you. Some people create it as a subdirectory to the source > directory. I tend to have it in a completely different location to have all > builds together under one directory. That is a matter of preference. > Now to "call configure from the build directory", you first have to be *in* > the build directory: > cd /home/user/gnucash/gnucash-docs/build > And then invoke configure. Configure is still in the source directory, so in > order to call it you need to use the full (absolute or relative) path to it: > /home/user/gnucash/gnucash-docs/configure > or > ../configure > Both are equivalent. The former uses the absolute path, the latter uses a > relative path. > With this, configure will use /home/user/gnucash/gnucash-docs/build as the > build directory. The Makefile files and target objects will all be stored in > there (and its subdirectories). > > And finally there is the installation location, which is the location where > the generated objects should finally end up to be used sensibly in the system. > Without any special configuration this will be /usr/local/... on linux based > systems. This is however not a good location to keep as default during > development (or documentation changing), because this would interfere with > your stable, running system and that's generally not what you want on a modern > system where installed software is usually done via a package manager. > So for development purposes we need to tell the build system to use another > final location. This is done during the run to configure, by setting the > --prefix option. You can find a reference to this in the wiki page as well in > the section about testing on linux. Again whatever you choose as base > directory for the --prefix option is really a matter of preference. The only > conditions are: > - it should be a writable location for the user that runs make install > - it should not be in the default paths /usr or /usr/local > For the example started above, one could use say > /home/user/gnucash/gnucash-docs/install > Or the full configure command (using relative paths here): > ../configure --prefix=/home/user/gnucash/gnucash-docs/install > > And this is as far as I can tell all there is to know. You may need to install > a few packages at the beginning. xsltproc is one, the build system also > requires autoconf, automake and libtoolize. I believe most distributions > provide generic packages to install all that is needed to have a suitable > development environment. These should take care of most of the dependencies. > I'm a bit vague here as it's been quite a while since I had to start from > scratch like this. Sorry about that. >
That's a great description of how build systems work. You should put it on a blog somewhere. Colin _______________________________________________ gnucash-devel mailing list gnucash-devel@gnucash.org https://lists.gnucash.org/mailman/listinfo/gnucash-devel