= DSSS Documentation for Software Engineers =

DSSS, the D Shared Software System, is a tool to:

* Build D software.
* Install D software.
* Configure D software dependencies and libraries.
* Maintain a repository of DSSS-compatible D sources to be easily installable
  via the Internet.

This document explains the use of DSSS by software engineers wishing to use
DSSS as a project management solution.


== OVERVIEW ==

Software utilizing DSSS is configured with a file named "dsss.conf". This file
describes the components of the complete software package and how each component
should be built.

dsss.conf files are plain text files, in a format similar to Windows INI files.
They are intentionally minimalistic, and require very little maintenance to keep
working.

Because dsss.conf files are minimalistic, most software packages can be
configured for use by DSSS with very simple dsss.conf files. For example, most
software packages containing one binary can have a dsss.conf file like the
following:
[example.d]
target = example_binary

This is all you need for a simple application. DSSS will parse your imports, so
you only need to list the file with the entry function (main). In most cases,
DSSS is very easy to use. Simple instructions on basic dsss.conf files is
available at http://www.dsource.org/projects/dsss/wiki/DSSSByExample


== THE BASICS ==

dsss.conf files are divided into a number of sections. Most sections describes a
single binary or library to be built.

A section is started with the file name of the source module or package in
brackets. File names should always be specified with '/' for the path
separator. '\' will work on Windows, but is not portable. '/' works on all
platforms.

In general, sections which are named for modules produce binaries, and sections
which are named for packages produce libraries. Each section may have any
number of settings, which customize how that section is built.

When running `dsss build`, sections are built in the order that they appear in
the dsss.conf file, with the exception that binaries are always built last.

= SETTINGS =

Settings are simple name-value pairs which customize the building of sections.
The format is simple:
<name>=<value>

For example,
target=example_binary

It is also possible to add to a setting:
<name>+=<value>

e.g.:
a=Hello
a+=World

The setting 'a' is now 'Hello World'. This is most useful with versioning,
described later.

Some settings do not require values. In this case, the setting name alone is
sufficient, such as:
shared

Settings may include references to environment variables:
a=$PREFIX

DSSS provides several environment variables for this purpose:
PREFIX: The prefix to which the software is being installed.
BIN_PREFIX: The prefix for binaries.
LIB_PREFIX: The prefix for libraries.
INCLUDE_PREFIX: The base prefix for .di files.
DOC_PREFIX: The prefix for documentation.
ETC_PREFIX: The prefix for configuration files.
EXE_EXT: The extension for executable files. Empty on POSIX, ".exe" on Windows.
DSSS: The full path to the DSSS binary itself.
DSSS_BUILD: The full path to the build tool being used by DSSS (usually
            rebuild).

= FLAGS =

Any section may have a 'buildflags' setting, which specifies the flags to be
used while building that section. For example,
buildflags=-O

Flags for use with release and debug builds (when using --debug) can be
specified separately in 'releaseflags' and 'debugflags', respectively.
'debugflags' defaults to '-debug -gc'.

= SECTION TYPES =

Although section types are usually determined automatically from the section
name, they may also be overridden with the 'type' setting:
[oneFileLib.d]
type=library

The valid values for 'type' (all described in later sections) are:
binary
library
sourcelibrary
special
subdir

= BINARIES =

Sections which are named for D modules (.d files) produce executable binaries
when built with DSSS. The target binary file name will be deduced from the name
of the .d file, or can be set explicitly with a 'target' line, such as:
[example.d]
target=example_binary

A single source file can be used to build multiple binaries, but they must be
given different section names. To allow this, section names may have a '+'
character, then any descriptive name appended. For example:
[example.d+withfeature]
target=example_binary_withfeature
buildflags=-version=withfeature

Windows users: Be careful not to set the target of a binary build to the name of
a directory. This will work on Windows because it gains the .exe suffix, but
will fail on other operating systems.

= LIBRARIES =

Sections which are named for D packages (directories) produce libraries when
built with DSSS. The name of the library file is derived from the name of the
package and the platform. There is no reason to remember this name, however,
because DSSS will detect library dependencies and link them in automatically.
This name can partially be overridden if desired, in the same way as binaries:
[mydpackage]
target=dlibrary

However, the platform will always affect the output library name. On POSIX
systems, the above library will be named libSdlibrary.a and libdlibrary.so. On
Windows, the above library will be named Sdlibrary.lib.

By default, all of the .d files within the directory and any subdirectory will
be included in the library. Files may be excluded with the 'exclude' setting:
[mydpackage]
exclude=mydpackage/broken.d

Entire directories may also be excluded:
[mydpackage]
exclude=mydpackage/brokenpackage

The 'exclude' setting is useful in concert with versioning, described in a later
section.

You may also explicitly include files in a library with the 'include' setting:
[mydpackage]
include=mydpackage/all.d

Note that, if 'include' is found, only those files listed in 'include' and
their dependencies will be included. Please note that the 'include' setting is
being tested and may be changed dramatically.

When using GDC on POSIX, it is also possible to build shared libraries (.so
files). To specify that a shared library should be built, set the 'shared'
option in the library's section:
[mydpackage]
shared

You can set the .so file's version extension (the 1.2.3 in .so.1.2.3) with the
soversion setting:
[mydpackage]
shared
soversion=3.2.1

= SOURCE LIBRARIES =

Source libraries are libraries which are not compiled until they are used in a
binary. They are installed in their source form. Otherwise, they act identically
to normal libraries. A source library may be specified by setting the 'type'
setting to 'sourcelibrary':
[mydpackage]
type=sourcelibrary

= SPECIAL SECTIONS =

It is also possible to create sections which are not associated with compiling
a binary or library. These sections are given names starting with a '+', such
as:
[+generate]

The utility of these sections will be seen below, in the section on hooks.


== INSTALLATION ==

DSSS is capable of installing binaries and libraries to a predetermined
directory, usually the prefix in which it is installed. When libraries are
installed in this way, they will be usable by DSSS without being explicitly
specified.

If a section should be built but not installed, set the 'noinstall' setting:
[test.d]
noinstall


== DEPENDENCIES ==

The primary reason that DSSS exists is to make handling dependencies easier. To
this end, is is never necessary to explicitly specify a dependency upon a
library which is itself set up to use DSSS. Because DSSS traces D imports and
keeps an Internet-accessible repository of package information, installing the
dependencies which are supported by DSSS is as easy as typing:
$ dsss net deps

However, dependencies on non-DSSS D libraries or C libraries can be more
complicated.

= INCLUDE PATHS =

It is possible to specify include paths in the 'buildflags' settings. Import
paths are specified with the -I flag:
buildflags=-I../prerequisite/import

= PREREQUISITE LIBRARIES =

Library search paths are specified with the -S flag:
buildflags=-S../prerequisite/lib

Libraries can be explicitly linked in with the -ll flag. -ll works similarly to
-l in most compilers. On POSIX and similar platforms, a flag such as
-ll<library>
will link in a library named
lib<library>.a (or lib<library>.so)

On Windows (except GDC), the same flag will link a library named
<library>.lib

Libraries linked in with the -ll flag are searched for in the search paths
specified by the -S flag.

The -ll flag is only useful for explicitly linking libraries into binaries. If
the DSSS-implemented library depends on a non-DSSS library, the dependency must
be specified in a .d file which is part of the DSSS-implemented library. This
is done with the 'link' pragma, which must always be specified within
version(build):
version (build) {
    pragma(link, "example");
}

The above example will cause any binary linked against the DSSS-implemented
library to link against the library named libexample.a (or example.lib on
Windows).


== HOOKS ==

DSSS can run arbitrary commands while building software. There are a number of
points at which commands can be run: before and after building, before and after
installing, and before and after cleaning up. These commands are added to
'prebuild', 'postbuild', 'preinstall', 'postinstall', 'preclean' and 'postclean'
lines, respectively.

Hook commands can be anything which can be run on the shell of the host system,
such as:
prebuild = echo Hello

Any number of hook commands may be strung together between semicolons:
prebuild = echo Hello ; echo World

And may span multiple lines by ending each line with a backslash:
prebuild = echo \
    Hello ; \
    echo World



There are also a number of special, builtin commands available.

= warn and error =

A warning or error condition can be specified by the hook commands 'warn' and
'error'.

An example of 'error':
version (!Posix) {
    prebuild=error Only POSIX is supported.
}

An example of 'warn':
version (Posix) {
    prebuild=warn POSIX support is untested.
}

When an error hook command is run, building of course halts.

= install =

The 'install' command installs a file to the specified directory. If the
directory does not exist, it is created. For example:
postinstall = install docs/README $DOC_PREFIX

Files installed in this way are recorded, so that they may be uninstalled
easily.

= installdir =

'installdir' is similar to 'install', with the exception that it can install
entire directories (and all of their subdirectories). The /content/ of the
first directory will be installed into the second directory.

= cd =

The 'cd' command changes the current directory. It works exactly as on POSIX
and Windows shells:
prebuild = cd c_source ; make

It is unnecessary to return to the original directory after 'cd'ing. The
directory will be restored after the hook commands have finished.

= .d files =

Any .d file may be used as a command. It will be compiled and run on-the-fly:
prebuild = generateBindings.d

= set =

The 'set' command sets a dsss.conf file setting while DSSS is actually running.
The parameters are:
set <section>:<setting> <value>

It is also possible to omit the section from the command to set in the current
section:
set <setting> <value>

The special section '*' may be used to set a setting in all sections:
set *:<setting> <value>

For example,
set example.d:postbuild echo Hello

'set' is most useful in concert with the 'eval' command (described below), as
it can then be used to set dsss.conf file settings programatically. It is
also usable independently of 'eval', but is no better than merely specifying
the setting.

= add =

The 'add' command is identical to the 'set' command, except that it appends to
the current value instead of replacing it.

For example,
add example.d:postbuild World

= eval =

The 'eval' command runs a specified command, captures its output, and then runs
its output as a command. This allows for very general processes to be
encapsulated into binaries, rather than the dsss.conf file itself.

For example, imagine the scenario that some system specifics need to be detected
and utilized in the building of a section. There can be a program, analyze.d,
which does the analysis and outputs commands such as
add *:postbuild echo Hello

This program could be run and used with the hook command:
prebuild=eval analyze.d


== VERSIONING ==

dsss.conf files support version statements with a similar syntax to D's own
version statements:

version (Windows) {
    postbuild=setupWindows.d
} else version (Posix) {
    postbuild=setupPosix.d
}

Unlike D, dsss.conf files support negative versions:

version (!Windows) {
    postbuild=giveUserCandy.d
}

dsss.conf's version statements can be used at any point in the dsss.conf file.
They can even conditionally include different sections:
version (Windows) {
    [winlib]
} else version (Posix) {
    [posixlib]
}
type = library


== GLOBAL SETTINGS ==

There are several settings that DSSS supports which are global. That is, they
are specified for the software package as a whole, rather than any section.
These are included at the top of the dsss.conf file. Common settings are 'name'
(the name of the software package) and 'version'.

There is also a global setting available to specify which sections should be
built normally, 'defaulttargets'. Without it, all sections will be built by
default. The section list is simply separated by spaces:
defaulttargets=xlib xbin

It is also possible to specify global settings later in the dsss.conf file by
adding an empty section header:
[]
name=exampleSoft


== DEFAULT SETTINGS ==

It is possible to create default settings with a special "*" section. This is
most useful for settings such as 'buildflags':

[*]
buildflags=-O

Note that any settings in a named section will override those in "*" sections.
For example, in this situation:

[*]
buildflags=-O

[mydlib]
buildflags+=-release

mydlib's buildflags are only "-release".


== ADVANCED FEATURES ==

There are several advanced features of DSSS which do not need any modification
to the dsss.conf file to use.

The flag '--test', when passed to `dsss build`:
$ dsss build --test
will cause all of the unit tests to be run.

The flag '--doc', when passed to `dsss build`:
$ dsss build --doc
will cause API documentation for every library to be generated with CandyDoc,
which beautifies and organizes the documentation.

The flag '--debug', when passed to `dsss build`:
$ dsss build --debug
will cause libraries to be built in both a debug- and non-debug mode.


== SUBDIRECTORIES ==

It is possible to contain an entire DSSS-enabled software package inside of
another. This is useful for keeping libraries from different sources separated,
and occasionally for adapting non-DSSS-aware packages to use DSSS. Essentially,
a section named for the directory of the sub-package has its type set to subdir:
[dziplib]
type=subdir

Note that you must manully add buildflags such as -Idziplib if you want to
import sources from the subdirectory into sources in the parent directory.


To be written:
== NET INSTALLATION ==
