For this purpose, I created the sinfil utility. It reads definitions and lists of source files, executes #include directives which relate to the source code being packaged, and produces a combined source code.
I have used this on freetype2 and I want to tackle AGG next. Let's review the tool and then get to the results.
The command line to the utility consists of variable definitions and names of specification files. A variable definition takes the form NAME=VALUE. Typically, you want the root directory of the software package to be a variable defined in this way. Rest of the arguments name the specification files. These are read in sequence and processed as if you had concatenated them and provided as a single argument.
Specification files are line based text files with the leading word being a command and the rest of the line its argument. # characters start a comment when they are at the beginning of a line. They are processed as normal characters elsewhere.
The first sequence of characters which are not space or control characters on a line form the command name. Following the command, there shall be one or more space characters and after that, we have the arguments.
If there is more than one argument for a command, these are separated by space characters. All arguments are trimmed such that no space or control characters appear at the beginning or the end of the argument. There is no way to include such things in an argument meant to be used as a word. This can be a problem with file names, but space-separated file names are so rare, I don't think this will be a big problem. Let's start with the easy commands.
So, which headers are incorporated into the final source code? The ones sinfil knows about. One way of informing it is the bpref command. This command will inform sinfil about headers that are under a specific directory.
#include <freetype/ftlist.h>You can inform the position of the whole
bpref freetype $TOP/includeNow, the above include directive will resolve to
$TOP/include/freetype/ftlist.hsinfil by default won't try to execute bracketed #include directives which don't fit into a pattern like the above. Therefore, it will not incorporate things like <stdio.h> However, you may override this behaviour using the braw command.
braw ft2build.h $TOP/include/ft2build.hThis is because many files include this file using:
#include <ft2build.h>Let's now discuss #include directives that use quotes instead of brackets. sinfil looks for the included file in the directory of the file doing the inclusion first. If it doesn't find it there, the directories given using the following command is used.
Sometimes the argument to #include is not a bracketed or quoted file name, but a macro to be expanded. freetype2 uses this a lot for modularization. When that is the case, you may define the relevant macro for the inclusion to proceed.
In the freetype2 example, I have the following in my specs:
defmac FT_CONFIG_CONFIG_H $CFG/ftconfig.hUsing this, the tool is able to execute directives such as
#include FT_CONFIG_CONFIG_HThe last command affecting file search is replace.
cp replacement filebefore running the tool. This is handy when you want to patch some file but don't want to modify the distribution tree.
The last command is the most important one.
Here is a single-file packaging of the library. I enabled only the truetype driver, along with builtin zlib and "smooth" rasterizer.
The source file is independent of the header file. In fact, if you append all your freetype related code at the end of the source file, you don't need the header file at all.
Here is a package with sinfil, specs files and a test program. If you run 'make', the test program will be built twice, once compiled and linked with the system freetype2 library and once with ft2.h/ft2.c.
The library package contains agg.cc and agg.h. These have all the functionality except for platform and control code. The excluded code is used for running demos. They contain a basic display connection and some widgets to control things within demos.
The full package contains agg-demolib.cc and agg-demolib.h. These include the platform and widgets.
The generator is here. It contains some extra files to run the demos.