(c) Copyright Rosetta Commons Member Institutions.
(c) This file is part of the Rosetta software suite and is made available under license.
(c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
(c) For more information, see http://www.rosettacommons.org. Questions about this can be
(c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.

Rosetta 3 build system, first major revision.

Basic Requirements
------------------

scons >= 0.96.1
python >= 2.2

The system is built around SCons:

    http://www.scons.org

You will need at least version 0.96.1 installed

    http://www.scons.org/download.php

You probably want to at least be aware of the SCons User's Guide and manual
page:

    http://www.scons.org/doc/HTML/scons-user/book1.html
    http://www.scons.org/doc/HTML/scons-man.html

SCons depends on Python, version 1.5 or later.  The build sources depend on
features present only in Python 2.2 or later, so you need at least 2.2.

Platform requirements
---------------------

One of the supported platforms as listed in the Rosetta Commons wiki at:

  https://wiki.rosettacommons.org/index.php/Supported_Platforms

Currently this means:
  Compilers:
    - G++, 3.3 or greater
    - Intel C++, 8.0 or greater
    - MSVC 7.0 or greater -- but this is not yet tested
  OS:
    - Linux, 2.6 or greater (possibly 2.4), on Intel or AMD processors
    - MacOS, 10.4 or greater, on PowerPC processors
    - Windows, 2000 or greater -- but this is not yet tested


What it can do
--------------

- Build sources, build tests based on sources, and build documentation using
  Doxygen.
- Target particular build types: combinations of compilers, os, and architectures,
  as well as debug and release modes.  Not all combinations are legal, but from
  those that are you can mix and match.

Setting it up
-------------

To specify default options for the build:

   - Copy SConstruct.template to <project>/SConstruct
   - Copy SConscript.template to <project>/SConscript
   - Copy SConscript.src.template to <project>/src/SConscript
   - Copy SConscript.test.template to <project>/test/SConscript
   - Copy SConscript.doc.template to <project>/doc/SConscript
   - Copy site.settings.template to site.settings
   - Copy user.settings.template to user.settings
   - Copy settings.template to <project>/src/<project>.src.settings
     Copy settings.template to <project>/test/<project>.test.settings
     Copy settings.template to <project>/doc/<project>.doc.settings

The SConstruct is the main build file and SCons scans for it.
The SConscripts contain specific rules for building particular directories.
You should not need to edit either the SConstruct or the SConscripts when
things are working as intended.  Any changes to be made to either file should
be made in the templates and then copied back out.  This ensures that changes
are shared with other users and more immediately prevents the need to keep
all the SConscripts in sync to prevent them from becoming subtly incompatible.

All user changes, including package specific decisions should be done in
the .settings files:
   - site.settings specifies build options and environment for the host
     or network you are on.  It should include the paths to all compilers
     you want to use, and the paths to all headers and libraries that are
     external to the system.  It can also specify an appropriate default
     build type. as noted below.
   - user.settings specifiy the build options and environment for an
     individual user, allowing you to customize your defaults on an as
     needed basis.
   - The various project/target .settings files contain the actual details
     needed by your specific build: the sources, header, and libraries that
     are part of the dependencies.  Provisions can be made for other parameters
     such as #defines as well.  In theory .settings files are designed to be
     be independent from SCons's own internal options, and are used to set
     them appropriately in the SConscripts.

How to use it
-------------

For most of the following commands you need to be in the project's
directory.  You can be below that directory (inside the project) if
you use the -D flag, which will scan up the directory tree for a
SConstruct.  But you can't be further up than the project.

Targets
-------

To get a list of scons options (do this at least once):

    scons -H

To build everything in a project

    scons

To clean everything in a project

    scons -c

There are four general targets: 'all' (the default), 'src' (the sources),
'test' (the tests), and 'doc' (the documentation).
To build only the sources, the tests, or the documentation, respectively:

    scons src
    scons test
    scons doc

(Note that these can be combined: e.g. 'scons src test' skips the documentation.)

To clean only a specific target:

    scons -c src
    scons -c test
    scons -c doc

You can build particular individual libraries or object files, but you need to
specify the full build location of the file, which includes the build type:

    scons build/src/debug/linux/x86/gcc/3.4.0/utility/libutility.a
    scons build/src/debug/linux/x86/gcc/3.4.0/utility/file/file_sys_util.o
    scons build/src/release/macos/ppc/gcc/4.0/utility/libutility.a

The tediousness of this is a known issue.


Options
-------

There are several options you can set, which control the compiler, the os,
the machine architecture and the debug mode.  The combination of these is
called the 'build type' and is used to select which options are finally passed
to the compiler.  This looks like:

    scons compiler=<compiler> compiler_version=<X.x> os=<os> arch=<architecture>
          mode=<debug mode>

You can pass these in any order and in any combination, but only some of the
combinations will build.  Which combinations work is defined in settings.py.
Which options are allowed is defined in options.py.

Currently supported options:
  - compiler: one of 'gcc', 'icc'.  (To be added: 'msvc').
  - compiler_version: one of '3.3', '3.4', '4.0' (for gcc) and '8.0', '8.1'
      or '9.0' for 'icc'.  However unless you really need a specific
      compiler version it is better to use the default, which is '*': i.e.
      pick whatever compiler is the default on your system.
  - os: one of 'linux', 'windows', or 'macos'.  32-bit and 64-bit versions
      of these systems exist, and the options should be specified appropriately
      as the system evolves.  Right now 64-bit systems are not properly supported.
      As with compiler_version the default is '*': which means use the system
      as automatically determined by the build system.  In theory picking an os
      different than the default will result in a cross-compile, but we aren't
      really ready to support that.
  - arch: one of "x86', 'x64', 'ia64', 'amd32', 'amd64', 'ppc32', 'ppc64'.
      There should be a "*" option for architecture as well, but it's not yet
      clear how to guarantee it's correct.
  - mode: one of 'debug', 'release', 'release_debug', 'profile' or
      'coverage'.  The default is debug.  This is the option you are
      most likely to specify on a regular basis.
  - extras: currently one of 'boinc', 'fastdocs', 'graphics',
      'sqlite3', 'mpi', runtimecheck', 'valgrind', 'static', 'gprof',
      'gcov', 'rosetta_float', 'boost' or ''.  Extra features to be
      added to the build for specific extra functionality.  Not all
      features mean anything to all projects. 'boinc' sets up Rosetta
      to be built for Rosetta @ home.

  < For up to date information see tools/build/options.settings.py >


General layout
--------------

Each project has master build file (SConstruct), a project build file
(SConscript), and SConscript files for sources, tests, and documentation.
The SConscripts describe how a general build works, and should not need
to be altered directly: if you need to make changes, modify the templates
and recopy as noted above.  In other words the builds should be similar
for every project.  Customization is done in the .settings files.

Each project also has a .settings file for source, for tests, and for
docs, which specifies what files you actually build.  A normal user of
the build system, for whom the existing setup is satisfactory, should
be able to never need change (or indeed look at) anything but the
.settings files.

The overall build system is contained in rosetta3/build.  (This is confusingly
named the same as rosetta3/<project>/build, but they are quite different.)
This contains the python source which sets up the build.  The two main sets of
files to be aware of:
  - settings.py creates sets of SCons options and build flags, which are combined
    to fit the build target.  For example a GCC debug build on Linux will combine
    options for GCC, Linux, and debug builds to pass to SCons.
  - basic.settings, site.settings, and user.settings establish respectively:
    the default options and environment variables, site specific options and
    environment, and user specific options and environment.  You should never
    need to modify the basic settings, modify the site's once per host, and make
    individual changes in the user settings.  In fact the site and user settings
    are both templates which should be copied into the rosetta3/build directory,
    and editted without the .template extension.  These non-templates should
    not be checked in.

The overarcing design is intend to make each project independent.  There is no
master build file for all projects (though it might be possible to add it as a
convenience).

Known issues
------------
  - You can build individual .o files but you need to specify the full build
    path (e.g. build/src/debug/linux/x86/gcc/3.4.0/numeric/constants.o).  This
    is tedious but SCons steadfastly resists any attempt to make a shorter alias.
  - Shared libraries can be built, but they don't link.  This is some compiler
    option issue that hasn't been debugged yet.
  - Not enough tests to know if the test builds really work.
  - This hasn't been tested on Windows.

Todo
----
  - Add some kind of target which lists what targets are possible.
    SCons might do this already.
  - Add a target which lists what build types are possible.
  - The configuration settings should probably live in some location within
    each project, and be installed from templates.
    - site.settings and user.settings need to have some location.  It goes
      counter to the point of the file if each user has their own site.settings.
      user.settings could stay in the build directory.
  - Break out most of SConstruct into a build/SConscript.  Make the SConstruct
    as simple as possible.
  - Allow for a toplevel SConstruct that builds all the projects.  It would
    probably just invoke the project SConscripts of every project.  To do this
    requires simplifying the current project SConstructs as noted in the previous
    item.
  - Properly handle platform specific files.  This is not a big step in the
    SConscripts.  The issue is deciding if platform source should be toplevel
    (as it is now) or made project specific (in keeping with the goal of
    self-contained projects.)
  - Properly handle external dependencies (in ext/).  This will involve
    detecting the presence of external libraries and headers, and then either
    making them available in the environment, or either symlinking or actively
    installing them into ext/.  The goal is that even if the user doesn't have
    access to the machine's shared directories and are missing an external
    dependency they can still build.
  - Improve the documentation build:
    - Move the builder for Doxyfiles out of the SConscript.
    - Include handwritten HTML (e.g. such as is present in ObjexxFCL).
    - Doxygen output is too verbose.
    - Allow specification of varied Doxygen options from the .settings.
    - Allow both terse and full (i.e. with full dependency diagrams) doc
      builds.  Make sure to recognize if 'dot' is absent.
  - Model the Doxyfile and Doxygen builders to be more like the design
    described in:

        http://www.atd.ucar.edu/rsf/eldora/software/apidocs/config-page.html

    This design makes the builders more like existing ones, and uses the
    environment usefully.
  - Improve default options, so you can't specify an invalid compiler +
    version combination (e.g. gcc 8.0).
  - Extras mechanism needs to be thought out further.  What does 'boinc' mean
    outside of Rosetta?  What does 'fulldocs' mean when 'doc' is not the target?
    I.e. what do extras mean for irrelevant targets.  Also how should they be mixed:
    the current system only recognizes one extra at a time.
