Hello!

I've started working on build system some time ago, my goal was to add
support for build variants that are not supported by current build
system. One of the major goals was to support build variant where smbd
binary is broken in serveral shared libraries + binary so other binaries
can share the same code.

Those who know how samba build system works in details can skip the
following paragraphs.

,----
| Today's samba build system defines four kinds of components: SUBSYSTEM, LIBRARY,
| BINARY and MODULE and relation between them that is called
| REQUIRED_SUBSYSTEMS.
| Components are allowed to have following properties:
| - REQUIRED_SUBSYSTEMS - defines the relation REQUIRED_SUBSYSTEMS
| between this component and others.
| - *OBJ_FILES - defines what object files are included in this
| component
| - LIBS - defines what linker flags should be used when LIBRARY
| BINARY or MODULE is compiled that is in relation REQUIRED_SUBSYSTEMS
| with this component.
| - ... other properties ...
|
| In practice, SUBSYSTEM is compiled in collection of object files that are
| in *OBJ_FILES. BINARY is compiled into binary file that includes one
| file with main function all SUBSYSTEMs with which it is in
| REQUIRED_SUBSYSTEMS relation and with all SUBSYSTEMs that these
| SUBSYSTEMs are in REQUIRED_SUBSYSTEMS relation and so on. LIBRARYs are
| the same as BINARYs, but they don't include that file that has main
| function in it. MODULE is pretty the same but it has a distinguishing
| property
| - SUBSYSTEM - property that is suitable only for MODULEs. It
| defines which SUBSYSTEM uses this MODULE. In practice this
| property is used by build system to make REQUIRED_SUBSYSTEMS
| relation between SUBSYSTEM describied in this property and
| MODULE if the module is built statically.
|
| This is almost complete description of current samba build system.
`----

Now I'll prove that this build system doesn't fit my needs. Let's
imagine situation where we want to build smbd broken into libraries.
Every object file should reside in one and only one of all the
libraries. Here we see that it's not possible to create such a build
if we are using semantics of the current build system because
REQUIRED_SUBSYSTEMS doesn't specify exclusive depends. Not only
exclusive depends have to be added, for each library we need to
specify ALL the subsystems that will be included in this
library. Making automatic guesses on what object files to include is
very dangerous, because of tracking library APIs. For example, if we
have two libraries that depend on one subsystem, resolvation of where
does the subsystem go cannot be done automatically.

After I've implemented exclusive depends I found that it is hard to
build samba the old way. For example, if we build smbd statically we
build all the libraries statically too. However, we might want to
build smbd in static way while wanting libldb to be built
dynamically. In this case we actually need to build two variants of
libldb, static and dynamic, smbd will link against the first one,
however this variant won't be distributed, latter one will be
distributed for other applications.

We can conclude that description of components in build system are
devided in two types. First type of descriptions have information about
component itself: for example, what object files does library include and what
libraries it is linked against, and what so version it has. Second
type of descriptions are build variants. Each latter description
contains information about how component will be built, how it will be
linked against other components and if the resulting object will be
distributed. It's important to admit, that we can have several build
variants for one component. It isn't needed to specify build variants
for all components, some of them can be determined automatically: for
example, if binary A is linked against library B dynamically we can predict
that B is needed to be built dynamically and it needs to be
distributed.

After creating trying to create collections of subsystems that would
fit into a libraries I found that in current .mk files there are
circular dependancies between subsystems and some dependancies are not
specified at all. I've created a small tool find_depends that
generates dependancy lists using nm.

Another change I've made is that I've got rid of object lists which
were common target for subsystems, all object files of each subsystem
are compiled in single .o file.

Code that is attached to this mail doesn't build samba to the end
because of the problems with sequence of files that are given to gcc
for linking (I'm not using -( and -) flags for portability), however
it is useful for understanding how makefile is generated.

I'd like to hear your suggestions about proposed changes.

Peter.