= DSSS Documentation for Software Engineers = ''Revision 862: /trunk/docs'' [[TOC(inline)]] 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 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: = For example, target=example_binary It is also possible to add to a setting: += 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 will link in a library named lib.a (or lib.so) On Windows (except GDC), the same flag will link a library named .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, built-in 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
: }}} It is also possible to omit the section from the command to set in the current section: {{{ set }}} The special section '*' may be used to set a setting in all sections: {{{ set *: }}} 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. == 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 manually 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