= DSSS by Example = This document attempts to explain what DSSS is, and how it is useful, by example. Essentially, it will go through several, increasingly-complex examples, describing the process of accomplishing them with and without DSSS. Documentation on the actual format of dsss.conf files and their options is available in the DSSS distribution in README.software_engineers, and is not explored in depth here. = The Simple Binary = Imagine you've created a simple uncompressor for a hypothetical compression format, dzip. You are trying to decide how you should build your tool, dunzip. This can be done realistically with or without DSSS like so: === Using the Compiler === It is of course possible in this scenario to simply use the compiler, and neither a build tool nor DSSS. Just passing the file into the compiler is sufficient: {{{ $ [g]dmd dunzip.d -ofdunzip or $ gdc dunzip.d -o dunzip }}} === Using a Build Tool === Using a build tool with a one-file binary is basically exactly equivalent to just using the compiler: {{{ $ rebuild dunzip.d -ofdunzip or $ bud dunzip.d -Tdunzip }}} === Using DSSS === All tools using DSSS require a dsss.conf file. As such, using DSSS involves the extra step of creating this file. In this example, your dsss.conf file looks like this: {{{ name = dunzip [dunzip.d] target = dunzip }}} With this file, building is as simple as: {{{ $ dsss build }}} This added file may seem like it's not worth the effort, but keep in mind that the exact parameters to the build tool or compiler will need to be saved somewhere, so this isn't necessarily an overhead. Also, as will be expanded on further in this document, dsss.conf is far more flexible. = Less Simple: A Trivial Library = Imagine that dunzip has evolved, and people would like to use it as a library. As such, you divide the 'library' code and 'front-end' code into dunzip.d and main.d, respectively. You don't care to actually compile it into a library file (.a or .lib), so long as it's usable. === Using the Compiler === Installing the library code is as simple as copying the .d file into the include path of the compiler. Unfortunately, doing so is platform-specific. As such, the installation would essentially be manual. Building the binary itself is still fairly simple: {{{ $ [g]dmd main.d dunzip.d -ofdunzip or $ gdc main.d dunzip.d -o dunzip }}} === Using a Build Tool === Installing the library code is still platform-specific and needs to be done manually. However, building the binary is a bit easier, since the dependencies are traced: {{{ $ rebuild main.d -ofdunzip or $ bud main.d -Tdunzip }}} === Using DSSS === Here we see the first major advantage of DSSS: This installation process is simple and automated. All you need to do if you used DSSS for the basic binary is to add the library section to your dsss.conf file: {{{ name = dunzip [dunzip.d] type = sourcelibrary [main.d] target = dunzip }}} Building is still simple: {{{ $ dsss build }}} However, installing is no longer manual, but is also trivial: {{{ $ dsss install }}} = Proper Libraries = Let's say you've expanded your dunzip library to support both compressing and uncompressing, and expanded it to include a number of modules. Your tree now looks like this: {{{ main.d dzip/ dzip/algorithm.d dzip/block.d dzip/compress.d dzip/hash.d dzip/io.d dzip/levels.d dzip/stack.d dzip/trees.d dzip/uncompress.d }}} There are now a large number of modules. Furthermore, you have decided that you'd like to build this into a proper library file, that is a .a or .lib file. === Using the Compiler === At this point, using the compiler directly is ridiculous. Every .d file needs to be passed into the compiler, and maintaining that list as a Makefile or shell script is prone to errors, aside from being platform-specific. Furthermore, creating the library file is not platform-independent. Installing is, of course, even more difficult than before: Now we have to install a large number of .d files and a library file! === Using a Build Tool === To do this with a build tool, a file 'dzip/all.d' would need to be added. With the 'all.d' module, it would be fairly simple to build a library with a build tool: {{{ $ rebuild -lib dzip/all.d -oflibdzip.a or $ bud -lib dzip/all.d -Tlibdzip.a }}} And of course, compiling the binary is still simple: {{{ $ rebuild main.d -ofdzipper or $ bud main.d -Tdzipper }}} Ideally, building against this library would be as simple as importing the proper module. The standard means of accomplishing this is to create a .di (D import) file, and add a special directive to it which will cause the build tool to link in the proper library. You would therefore need to generate a number of .di files, and for every one, add a section something like this: {{{ version (build) { pragma(link, "dzip"); } }}} This can be done in a Makefile or shellscript, but not in a platform-independent way. Finally, installing is still very manual. === Using DSSS === Here again the advantage of using DSSS is quite clear. There is no need for an all.d file, and nothing is platform-specific. The dsss.conf file is now: {{{ name = dzip [dzip] [main.d] target = dzipper }}} Building is still simple: {{{ $ dsss build }}} And installing is also still simple: {{{ $ dsss install }}} = Using the Library = After you went through all the trouble of creating this library, presumably someone will want to use it. So, let's imagine you've written a new tool, dzipserver, which uses your dzip library. It contains only one file, dzipserver.d. As with the simple one-file binary, this '''can''' be accomplished with or without DSSS. === Using the Compiler === Linking against libraries is not consistent across platforms. As such, doing this with the compiler is not a very good option. On Posix: {{{ $ [g]dmd dzipserver.d -ofdzipserver -L-ldzip or $ gdc dzipserver.d -o dzipserver -ldzip }}} On Windows: {{{ $ dmd dzipserver.d -ofdzipserver -L+dzip.lib or $ gdmd dzipserver.d -ofdzipserver -L-ldzip }}} === Using a Build Tool === If .di files have been created and installed as described above (which is a manual and platform-specific process), building with a build tool is fairly simple: {{{ $ rebuild dzipserver.d -ofdzipserver or $ bud dzipserver.d -Tdzipserver }}} === Using DSSS === Because you're using DSSS, you know that the .di files and library have been installed properly. As such, '''all you need to do is import the proper modules'''. The dsss.conf will therefore look like this: {{{ name = dzipserver [dzipserver.d] target = dzipserver }}} As with every other step, building and installing is: {{{ $ dsss build $ dsss install }}} However, there's another advantage of DSSS here. Imagine that dzip has been set up in the DSSS networking system, but that it isn't installed on the system you're building dzipserver on. Not only is installing it simple, but the end user '''doesn't even need to know what it is or where it's from'''. Installing '''all''' the dependencies for a tool is as simple as: {{{ $ dsss net deps }}} = Documentation = As you've written dzip, hopefully you've been writing good ddocs. Now you'd like to generate documentation .html files from them. === Using the Compiler or a Build Tool === Simply adding the proper -D flag to the compiler or build tool's command line is usually sufficient, but has some significant lacks: 1. If you want to use candydoc, you need to set it up yourself. 2. If you have similarly-named modules, they will be given the same .html file name, so one will be missing. === Using DSSS === Making .html documentation from ddocs is trivial with DSSS. Just add --doc to the build line: {{{ $ dsss build --doc }}} Every module is given a fully qualified filename, so similarly-named modules do not cause a problem. Furthermore, candydoc is included automatically. = Conclusion = This document should have made clear the advantages of using DSSS: Primarily, it allows for much-improved interaction between D libraries, installation, and dependency acquisition. Even for simple tools, it provides the advantage of the simple format of dsss.conf as compared to a Makefile or shell script. This document has not gone into great detail on the range of features supported by DSSS, only the very most basic and useful ones. More complete documentation is provided with DSSS.