aboutsummaryrefslogtreecommitdiff
path: root/Configurations/README-design.md
diff options
context:
space:
mode:
Diffstat (limited to 'Configurations/README-design.md')
-rw-r--r--Configurations/README-design.md604
1 files changed, 604 insertions, 0 deletions
diff --git a/Configurations/README-design.md b/Configurations/README-design.md
new file mode 100644
index 000000000000..ef21a3ae2840
--- /dev/null
+++ b/Configurations/README-design.md
@@ -0,0 +1,604 @@
+Design document for the unified scheme data
+===========================================
+
+How are things connected?
+-------------------------
+
+The unified scheme takes all its data from the `build.info` files seen
+throughout the source tree. These files hold the minimum information
+needed to build end product files from diverse sources. See the
+section on `build.info` files below.
+
+From the information in `build.info` files, `Configure` builds up an
+information database as a hash table called `%unified_info`, which is
+stored in configdata.pm, found at the top of the build tree (which may
+or may not be the same as the source tree).
+
+[`Configurations/common.tmpl`](common.tmpl) uses the data from `%unified_info` to
+generate the rules for building end product files as well as
+intermediary files with the help of a few functions found in the
+build-file templates. See the section on build-file templates further
+down for more information.
+
+build.info files
+----------------
+
+As mentioned earlier, `build.info` files are meant to hold the minimum
+information needed to build output files, and therefore only (with a
+few possible exceptions [1]) have information about end products (such
+as scripts, library files and programs) and source files (such as C
+files, C header files, assembler files, etc). Intermediate files such
+as object files are rarely directly referred to in `build.info` files (and
+when they are, it's always with the file name extension `.o`), they are
+inferred by `Configure`. By the same rule of minimalism, end product
+file name extensions (such as `.so`, `.a`, `.exe`, etc) are never mentioned
+in `build.info`. Their file name extensions will be inferred by the
+build-file templates, adapted for the platform they are meant for (see
+sections on `%unified_info` and build-file templates further down).
+
+The variables `PROGRAMS`, `LIBS`, `MODULES` and `SCRIPTS` are used to declare
+end products. There are variants for them with `_NO_INST` as suffix
+(`PROGRAM_NO_INST` etc) to specify end products that shouldn't get installed.
+
+The variables `SOURCE`, `DEPEND`, `INCLUDE` and `DEFINE` are indexed by a
+produced file, and their values are the source used to produce that
+particular produced file, extra dependencies, include directories
+needed, or C macros to be defined.
+
+All their values in all the `build.info` throughout the source tree are
+collected together and form a set of programs, libraries, modules and
+scripts to be produced, source files, dependencies, etc etc etc.
+
+Let's have a pretend example, a very limited contraption of OpenSSL,
+composed of the program `apps/openssl`, the libraries `libssl` and
+`libcrypto`, an module `engines/ossltest` and their sources and
+dependencies.
+
+ # build.info
+ LIBS=libcrypto libssl
+ INCLUDE[libcrypto]=include
+ INCLUDE[libssl]=include
+ DEPEND[libssl]=libcrypto
+
+This is the top directory `build.info` file, and it tells us that two
+libraries are to be built, the include directory `include/` shall be
+used throughout when building anything that will end up in each
+library, and that the library `libssl` depend on the library
+`libcrypto` to function properly.
+
+ # apps/build.info
+ PROGRAMS=openssl
+ SOURCE[openssl]=openssl.c
+ INCLUDE[openssl]=.. ../include
+ DEPEND[openssl]=../libssl
+
+This is the `build.info` file in `apps/`, one may notice that all file
+paths mentioned are relative to the directory the `build.info` file is
+located in. This one tells us that there's a program to be built
+called `apps/openss` (the file name extension will depend on the
+platform and is therefore not mentioned in the `build.info` file). It's
+built from one source file, `apps/openssl.c`, and building it requires
+the use of `.` and `include/` include directories (both are declared
+from the point of view of the `apps/` directory), and that the program
+depends on the library `libssl` to function properly.
+
+ # crypto/build.info
+ LIBS=../libcrypto
+ SOURCE[../libcrypto]=aes.c evp.c cversion.c
+ DEPEND[cversion.o]=buildinf.h
+
+ GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(CFLAGS)" "$(PLATFORM)"
+ DEPEND[buildinf.h]=../Makefile
+ DEPEND[../util/mkbuildinf.pl]=../util/Foo.pm
+
+This is the `build.info` file in `crypto/`, and it tells us a little more
+about what's needed to produce `libcrypto`. LIBS is used again to
+declare that `libcrypto` is to be produced. This declaration is
+really unnecessary as it's already mentioned in the top `build.info`
+file, but can make the info file easier to understand. This is to
+show that duplicate information isn't an issue.
+
+This `build.info` file informs us that `libcrypto` is built from a few
+source files, `crypto/aes.c`, `crypto/evp.c` and `crypto/cversion.c`.
+It also shows us that building the object file inferred from
+`crypto/cversion.c` depends on `crypto/buildinf.h`. Finally, it
+also shows the possibility to declare how some files are generated
+using some script, in this case a perl script, and how such scripts
+can be declared to depend on other files, in this case a perl module.
+
+Two things are worth an extra note:
+
+`DEPEND[cversion.o]` mentions an object file. DEPEND indexes is the
+only location where it's valid to mention them
+
+ # ssl/build.info
+ LIBS=../libssl
+ SOURCE[../libssl]=tls.c
+
+This is the build.info file in `ssl/`, and it tells us that the
+library `libssl` is built from the source file `ssl/tls.c`.
+
+ # engines/build.info
+ MODULES=dasync
+ SOURCE[dasync]=e_dasync.c
+ DEPEND[dasync]=../libcrypto
+ INCLUDE[dasync]=../include
+
+ MODULES_NO_INST=ossltest
+ SOURCE[ossltest]=e_ossltest.c
+ DEPEND[ossltest]=../libcrypto.a
+ INCLUDE[ossltest]=../include
+
+This is the `build.info` file in `engines/`, telling us that two modules
+called `engines/dasync` and `engines/ossltest` shall be built, that
+`dasync`'s source is `engines/e_dasync.c` and `ossltest`'s source is
+`engines/e_ossltest.c` and that the include directory `include/` may
+be used when building anything that will be part of these modules.
+Also, both modules depend on the library `libcrypto` to function
+properly. `ossltest` is explicitly linked with the static variant of
+the library `libcrypto`. Finally, only `dasync` is being installed, as
+`ossltest` is only for internal testing.
+
+When `Configure` digests these `build.info` files, the accumulated
+information comes down to this:
+
+ LIBS=libcrypto libssl
+ SOURCE[libcrypto]=crypto/aes.c crypto/evp.c crypto/cversion.c
+ DEPEND[crypto/cversion.o]=crypto/buildinf.h
+ INCLUDE[libcrypto]=include
+ SOURCE[libssl]=ssl/tls.c
+ INCLUDE[libssl]=include
+ DEPEND[libssl]=libcrypto
+
+ PROGRAMS=apps/openssl
+ SOURCE[apps/openssl]=apps/openssl.c
+ INCLUDE[apps/openssl]=. include
+ DEPEND[apps/openssl]=libssl
+
+ MODULES=engines/dasync
+ SOURCE[engines/dasync]=engines/e_dasync.c
+ DEPEND[engines/dasync]=libcrypto
+ INCLUDE[engines/dasync]=include
+
+ MODULES_NO_INST=engines/ossltest
+ SOURCE[engines/ossltest]=engines/e_ossltest.c
+ DEPEND[engines/ossltest]=libcrypto.a
+ INCLUDE[engines/ossltest]=include
+
+ GENERATE[crypto/buildinf.h]=util/mkbuildinf.pl "$(CC) $(CFLAGS)" "$(PLATFORM)"
+ DEPEND[crypto/buildinf.h]=Makefile
+ DEPEND[util/mkbuildinf.pl]=util/Foo.pm
+
+A few notes worth mentioning:
+
+`LIBS` may be used to declare routine libraries only.
+
+`PROGRAMS` may be used to declare programs only.
+
+`MODULES` may be used to declare modules only.
+
+The indexes for `SOURCE` must only be end product files, such as
+libraries, programs or modules. The values of `SOURCE` variables must
+only be source files (possibly generated).
+
+`INCLUDE` and `DEPEND` shows a relationship between different files
+(usually produced files) or between files and directories, such as a
+program depending on a library, or between an object file and some
+extra source file.
+
+When `Configure` processes the `build.info` files, it will take it as
+truth without question, and will therefore perform very few checks.
+If the build tree is separate from the source tree, it will assume
+that all built files and up in the build directory and that all source
+files are to be found in the source tree, if they can be found there.
+`Configure` will assume that source files that can't be found in the
+source tree (such as `crypto/bildinf.h` in the example above) are
+generated and will be found in the build tree.
+
+The `%unified_info` database
+----------------------------
+
+The information in all the `build.info` get digested by `Configure` and
+collected into the `%unified_info` database, divided into the following
+indexes:
+
+ depends => a hash table containing 'file' => [ 'dependency' ... ]
+ pairs. These are directly inferred from the DEPEND
+ variables in build.info files.
+
+ modules => a list of modules. These are directly inferred from
+ the MODULES variable in build.info files.
+
+ generate => a hash table containing 'file' => [ 'generator' ... ]
+ pairs. These are directly inferred from the GENERATE
+ variables in build.info files.
+
+ includes => a hash table containing 'file' => [ 'include' ... ]
+ pairs. These are directly inferred from the INCLUDE
+ variables in build.info files.
+
+ install => a hash table containing 'type' => [ 'file' ... ] pairs.
+ The types are 'programs', 'libraries', 'modules' and
+ 'scripts', and the array of files list the files of
+ that type that should be installed.
+
+ libraries => a list of libraries. These are directly inferred from
+ the LIBS variable in build.info files.
+
+ programs => a list of programs. These are directly inferred from
+ the PROGRAMS variable in build.info files.
+
+ scripts => a list of scripts. There are directly inferred from
+ the SCRIPTS variable in build.info files.
+
+ sources => a hash table containing 'file' => [ 'sourcefile' ... ]
+ pairs. These are indirectly inferred from the SOURCE
+ variables in build.info files. Object files are
+ mentioned in this hash table, with source files from
+ SOURCE variables, and AS source files for programs and
+ libraries.
+
+ shared_sources =>
+ a hash table just like 'sources', but only as source
+ files (object files) for building shared libraries.
+
+As an example, here is how the `build.info` files example from the
+section above would be digested into a `%unified_info` table:
+
+ our %unified_info = (
+ "depends" =>
+ {
+ "apps/openssl" =>
+ [
+ "libssl",
+ ],
+ "crypto/buildinf.h" =>
+ [
+ "Makefile",
+ ],
+ "crypto/cversion.o" =>
+ [
+ "crypto/buildinf.h",
+ ],
+ "engines/dasync" =>
+ [
+ "libcrypto",
+ ],
+ "engines/ossltest" =>
+ [
+ "libcrypto.a",
+ ],
+ "libssl" =>
+ [
+ "libcrypto",
+ ],
+ "util/mkbuildinf.pl" =>
+ [
+ "util/Foo.pm",
+ ],
+ },
+ "modules" =>
+ [
+ "engines/dasync",
+ "engines/ossltest",
+ ],
+ "generate" =>
+ {
+ "crypto/buildinf.h" =>
+ [
+ "util/mkbuildinf.pl",
+ "\"\$(CC)",
+ "\$(CFLAGS)\"",
+ "\"$(PLATFORM)\"",
+ ],
+ },
+ "includes" =>
+ {
+ "apps/openssl" =>
+ [
+ ".",
+ "include",
+ ],
+ "engines/ossltest" =>
+ [
+ "include"
+ ],
+ "libcrypto" =>
+ [
+ "include",
+ ],
+ "libssl" =>
+ [
+ "include",
+ ],
+ "util/mkbuildinf.pl" =>
+ [
+ "util",
+ ],
+ }
+ "install" =>
+ {
+ "modules" =>
+ [
+ "engines/dasync",
+ ],
+ "libraries" =>
+ [
+ "libcrypto",
+ "libssl",
+ ],
+ "programs" =>
+ [
+ "apps/openssl",
+ ],
+ },
+ "libraries" =>
+ [
+ "libcrypto",
+ "libssl",
+ ],
+ "programs" =>
+ [
+ "apps/openssl",
+ ],
+ "sources" =>
+ {
+ "apps/openssl" =>
+ [
+ "apps/openssl.o",
+ ],
+ "apps/openssl.o" =>
+ [
+ "apps/openssl.c",
+ ],
+ "crypto/aes.o" =>
+ [
+ "crypto/aes.c",
+ ],
+ "crypto/cversion.o" =>
+ [
+ "crypto/cversion.c",
+ ],
+ "crypto/evp.o" =>
+ [
+ "crypto/evp.c",
+ ],
+ "engines/e_dasync.o" =>
+ [
+ "engines/e_dasync.c",
+ ],
+ "engines/dasync" =>
+ [
+ "engines/e_dasync.o",
+ ],
+ "engines/e_ossltest.o" =>
+ [
+ "engines/e_ossltest.c",
+ ],
+ "engines/ossltest" =>
+ [
+ "engines/e_ossltest.o",
+ ],
+ "libcrypto" =>
+ [
+ "crypto/aes.c",
+ "crypto/cversion.c",
+ "crypto/evp.c",
+ ],
+ "libssl" =>
+ [
+ "ssl/tls.c",
+ ],
+ "ssl/tls.o" =>
+ [
+ "ssl/tls.c",
+ ],
+ },
+ );
+
+As can be seen, everything in `%unified_info` is fairly simple suggest
+of information. Still, it tells us that to build all programs, we
+must build `apps/openssl`, and to build the latter, we will need to
+build all its sources (`apps/openssl.o` in this case) and all the
+other things it depends on (such as `libssl`). All those dependencies
+need to be built as well, using the same logic, so to build `libssl`,
+we need to build `ssl/tls.o` as well as `libcrypto`, and to build the
+latter...
+
+Build-file templates
+--------------------
+
+Build-file templates are essentially build-files (such as `Makefile` on
+Unix) with perl code fragments mixed in. Those perl code fragment
+will generate all the configuration dependent data, including all the
+rules needed to build end product files and intermediary files alike.
+At a minimum, there must be a perl code fragment that defines a set of
+functions that are used to generates specific build-file rules, to
+build static libraries from object files, to build shared libraries
+from static libraries, to programs from object files and libraries,
+etc.
+
+ generatesrc - function that produces build file lines to generate
+ a source file from some input.
+
+ It's called like this:
+
+ generatesrc(src => "PATH/TO/tobegenerated",
+ generator => [ "generatingfile", ... ]
+ generator_incs => [ "INCL/PATH", ... ]
+ generator_deps => [ "dep1", ... ]
+ incs => [ "INCL/PATH", ... ],
+ deps => [ "dep1", ... ],
+ intent => one of "libs", "dso", "bin" );
+
+ 'src' has the name of the file to be generated.
+ 'generator' is the command or part of command to
+ generate the file, of which the first item is
+ expected to be the file to generate from.
+ generatesrc() is expected to analyse and figure out
+ exactly how to apply that file and how to capture
+ the result. 'generator_incs' and 'generator_deps'
+ are include directories and files that the generator
+ file itself depends on. 'incs' and 'deps' are
+ include directories and files that are used if $(CC)
+ is used as an intermediary step when generating the
+ end product (the file indicated by 'src'). 'intent'
+ indicates what the generated file is going to be
+ used for.
+
+ src2obj - function that produces build file lines to build an
+ object file from source files and associated data.
+
+ It's called like this:
+
+ src2obj(obj => "PATH/TO/objectfile",
+ srcs => [ "PATH/TO/sourcefile", ... ],
+ deps => [ "dep1", ... ],
+ incs => [ "INCL/PATH", ... ]
+ intent => one of "lib", "dso", "bin" );
+
+ 'obj' has the intended object file with `.o`
+ extension, src2obj() is expected to change it to
+ something more suitable for the platform.
+ 'srcs' has the list of source files to build the
+ object file, with the first item being the source
+ file that directly corresponds to the object file.
+ 'deps' is a list of explicit dependencies. 'incs'
+ is a list of include file directories. Finally,
+ 'intent' indicates what this object file is going
+ to be used for.
+
+ obj2lib - function that produces build file lines to build a
+ static library file ("libfoo.a" in Unix terms) from
+ object files.
+
+ called like this:
+
+ obj2lib(lib => "PATH/TO/libfile",
+ objs => [ "PATH/TO/objectfile", ... ]);
+
+ 'lib' has the intended library file name *without*
+ extension, obj2lib is expected to add that. 'objs'
+ has the list of object files to build this library.
+
+ libobj2shlib - backward compatibility function that's used the
+ same way as obj2shlib (described next), and was
+ expected to build the shared library from the
+ corresponding static library when that was suitable.
+ NOTE: building a shared library from a static
+ library is now DEPRECATED, as they no longer share
+ object files. Attempting to do this will fail.
+
+ obj2shlib - function that produces build file lines to build a
+ shareable object library file ("libfoo.so" in Unix
+ terms) from the corresponding object files.
+
+ called like this:
+
+ obj2shlib(shlib => "PATH/TO/shlibfile",
+ lib => "PATH/TO/libfile",
+ objs => [ "PATH/TO/objectfile", ... ],
+ deps => [ "PATH/TO/otherlibfile", ... ]);
+
+ 'lib' has the base (static) library file name
+ *without* extension. This is useful in case
+ supporting files are needed (such as import
+ libraries on Windows).
+ 'shlib' has the corresponding shared library name
+ *without* extension. 'deps' has the list of other
+ libraries (also *without* extension) this library
+ needs to be linked with. 'objs' has the list of
+ object files to build this library.
+
+ obj2dso - function that produces build file lines to build a
+ dynamic shared object file from object files.
+
+ called like this:
+
+ obj2dso(lib => "PATH/TO/libfile",
+ objs => [ "PATH/TO/objectfile", ... ],
+ deps => [ "PATH/TO/otherlibfile",
+ ... ]);
+
+ This is almost the same as obj2shlib, but the
+ intent is to build a shareable library that can be
+ loaded in runtime (a "plugin"...).
+
+ obj2bin - function that produces build file lines to build an
+ executable file from object files.
+
+ called like this:
+
+ obj2bin(bin => "PATH/TO/binfile",
+ objs => [ "PATH/TO/objectfile", ... ],
+ deps => [ "PATH/TO/libfile", ... ]);
+
+ 'bin' has the intended executable file name
+ *without* extension, obj2bin is expected to add
+ that. 'objs' has the list of object files to build
+ this library. 'deps' has the list of library files
+ (also *without* extension) that the programs needs
+ to be linked with.
+
+ in2script - function that produces build file lines to build a
+ script file from some input.
+
+ called like this:
+
+ in2script(script => "PATH/TO/scriptfile",
+ sources => [ "PATH/TO/infile", ... ]);
+
+ 'script' has the intended script file name.
+ 'sources' has the list of source files to build the
+ resulting script from.
+
+Along with the build-file templates is the driving template
+[`Configurations/common.tmpl`](common.tmpl), which looks through all the
+information in `%unified_info` and generates all the rulesets to build libraries,
+programs and all intermediate files, using the rule generating
+functions defined in the build-file template.
+
+As an example with the smaller `build.info` set we've seen as an
+example, producing the rules to build `libcrypto` would result in the
+following calls:
+
+ # Note: obj2shlib will only be called if shared libraries are
+ # to be produced.
+ # Note 2: obj2shlib must convert the '.o' extension to whatever
+ # is suitable on the local platform.
+ obj2shlib(shlib => "libcrypto",
+ objs => [ "crypto/aes.o", "crypto/evp.o", "crypto/cversion.o" ],
+ deps => [ ]);
+
+ obj2lib(lib => "libcrypto"
+ objs => [ "crypto/aes.o", "crypto/evp.o", "crypto/cversion.o" ]);
+
+ src2obj(obj => "crypto/aes.o"
+ srcs => [ "crypto/aes.c" ],
+ deps => [ ],
+ incs => [ "include" ],
+ intent => "lib");
+
+ src2obj(obj => "crypto/evp.o"
+ srcs => [ "crypto/evp.c" ],
+ deps => [ ],
+ incs => [ "include" ],
+ intent => "lib");
+
+ src2obj(obj => "crypto/cversion.o"
+ srcs => [ "crypto/cversion.c" ],
+ deps => [ "crypto/buildinf.h" ],
+ incs => [ "include" ],
+ intent => "lib");
+
+ generatesrc(src => "crypto/buildinf.h",
+ generator => [ "util/mkbuildinf.pl", "\"$(CC)",
+ "$(CFLAGS)\"", "\"$(PLATFORM)\"" ],
+ generator_incs => [ "util" ],
+ generator_deps => [ "util/Foo.pm" ],
+ incs => [ ],
+ deps => [ ],
+ intent => "lib");
+
+The returned strings from all those calls are then concatenated
+together and written to the resulting build-file.