# Version 3.04/01 release notes

    The ROOT Team is pleased to announce the release of ROOT version 3.04/01.

    Compared to the previous production release (v3.03/09) this new,
    backward compatible, version has major enhancements described in the
    attachement.

    Binaries for all supported platforms are available at:

          http://root.cern.ch/root/Version304.html

    Versions for AFS have also been updated. See the list of supported platforms:

          http://root.cern.ch/root/AFS.html

    Both links are reachable via the download page. Note that with this release,
    we are supporting binaries for more platforms/compilers.

     For more information, see:

          http://root.cern.ch

    Rene Brun, Philippe Canal, Olivier Couet, Masaharu Goto, Fons Rademakers

    CINT
    ====

    Latest version of CINT. For the main new features see the CINT
    release notes: http://root.cern.ch/root/Cint.phtml?relnote

    TSystem
    =======

    One can now create dictionaries for existing libraries.
    So now the following is possible:

    	  root [] .L path/lib/veryImportant3rdPartyLib.so
    	  root [] .include path/include
    	  root [] .L importantClass.h+

    By default the library is build in the directory of the header file
    but that can be changed by doing:

    	   root [] TString cmd = gSystem->GetMakeSharedLib();
    	   root [] cmd.ReplaceAll("$BuildDir","whereIwantTheLib/lib");
    	   root [] gSystem->SetMakeSharedLib(cmd);

    One can now select the optimization level used when compiling with ACLiC
    	   root [] .L Macro.C++g
    compiles the macro with debug symbols.
    	   root [] .L Macro.C++O
    compiles the macro with optimization.
    	   root [] .L Macro.C++
    using the default optimization level.  The initial default is to compile
    with the same level of optimization as the root executable itself.  The
    default can be changed using:
               root[] gSystem->SetAclicMode (TSystem::kDebug);
               root[] gSystem->SetAclicMode (TSystem::kOpt);

    The commands:
    	   root [] .L Macro.C+g
    	   root [] .L Macro.C+O
    respectively compiles the macro with debug and optimization if the library
    does not exist yet.  If the library exists, it is loaded unchanged.

    rootcint/lindef files
    =====================

    The default behavior of rootcint is now to not link in (i.e. generate the
    dictionary for) any of the symbols.  In particular this means that the lines

      #pragma link off all globals;
      #pragma link off all classes;
      #pragma link off all functions;

    are now, in the general case, unnecessary.  This also means that linking the
    instantiation of a class template:

      #pragma link C++ class mytemplate<int>;

    ONLY links this specific class.  In previous versions of ROOT, depending on
    many factors, this might also have included the linking of many other
    instantiation of class template used directly or indirectly by 'mytemplate'.
    A typical case would have been to rely on

      #pragma link C++ class vector<MyClass>;

    to also induce the generation of the iterators.  You now needs to explicitly
    request them.

    Another advantage of the change is that now, if you omit the
    'pragma link off' line from your linkdef file, you can actually springle
    the 'pragma link C++ class' across as many of you header as file as you need.

    TH1
    ===

    Add new option "M" in TH1::KolmogorovTest()
        "X" Run the pseudo experiments post-processor with the following
            procedure: make pseudoexperiments based on random values from
            the parent distribution and compare the KS distance of the
            pseudoexperiment to the parent distribution. Bin the KS
            distances in a histogram, and then take the integral of all
            the KS values above the value obtained from the original data
            to Monte Carlo distribution. The number of pseudo-experiments
            NEXPT is currently fixed at 1000. The function returns the
            integral. Thanks to Ben Kilminster to submit this procedure.
            Note that this option "X" is much slower.

    Make all DrawCopy() functions const.

    Add new function:
    TH1 *TH1::DrawNormalized(Option_t *option, Double_t norm) const
         Draw a normalized copy of this histogram.
         A clone of this histogram is normalized to norm and drawn with
         option. A pointer to the normalized histogram is returned.
         The contents of the histogram copy are scaled such that the new
         sum of weights (excluding under and overflow) is equal to norm.
         Note that the returned normalized histogram is not added to the
         list of histograms in the current directory in memory.
         It is the user's responsability to delete this histogram.
         The kCanDelete bit is set for the returned object. If a pad
         containing this copy is cleared, the histogram will be automatically
         deleted. See Draw for the list of options

    THistPainter
    ============

    Allow logarithmic axes (x, y and z) when using the CONT drawing options.

    Fix in PaintLego and PaintSurface in the new algorithm computing the scale.
    Fix a problem in PaintColorLevels when a maximum has been set.

    TPad
    ====

    Add a new feature in TPad::WaitPrimitive().
    When this function is called with no arguments, it will wait
    until a double-click is executed in the canvas or any key pressed.
    A call to gSystem->Sleep(10) has been added in the loop to avoid
    consuming all the CPU.
    This new option is convenient when executing a macro. By adding
    statements like
         canvas->WaitPrimitive();
    one can monitor the progress of a running macro, stop at convenient
    places with the possibility to interact with the canvas and resume
    the execution with a double click or a key press.

    TView
    =====

    Perspective view introduced (default for new geometry). Can be selected
    via the context menu.

    TTree
    =====

    The new version allows TTree objects to properly treat TTreeFriends
    which are actually TChain objects.

    Modify TTree::ChangeFile() to remove several limitations.
    In particular, it is now possible to have more than one Tree
    in the file. All trees are correctly closed, written to the
    file and reset before switching to the new file.

    TBranchElement
    ==============

    Several changes in TBranchElement::SetAddress() to simplify the logic
    and add support for a Tree with missing classes.

    Add special icons for TBranchElements that are folders as opposed to
    leaves. This is done by overriding TObject::GetIconName() which returns
    a different name for a branch folder than for a branch leave. In the
    mime types file this icon name is specified with the corresponding icons.

    In Unroll function, remove the limitation that a TClonesArray cannot be split
    when the pointer is in a base class. However, there are still changes
    required in the browse functions to get this feature operational.

    One change from Dave Morrison to escape the slash character.

    One fix in case of nested inheritance with the same class used
    in the base class and by composition.

    Fix a problem in TBranchElement::SetAddress() in case of an object
    with a level of inheritance greater than 3 and when data members
    are simple types following classes at the same level (thanks Susan
    Kasahara for reporting an example).

    The new function has been simplified, taking advantage of the work
    already done by TClass::BuildRealData().

    TTreePlayer
    ===========

    Make sure that a scalar weight is used for all the elements
    of an array which is drawn. The scalar weight was only applied to
    the first element of the array.

    TChain
    ======

    Fix a problem in TChain::LoadTree() in case one file has a Tree
    with no entries.

    TPostScript
    ===========

    Fix when printing patterns. The line width must be set to 1.

    TStyle
    ======

    Add new member
      Int_t fNumberContours;
    and the corresponding Getter()/Setter() GetNumberContours(),
    SetNumberContour()s. The default number of contours is 20.

    Add new options in TStyle::SetOptDate() to support several date formats.
       void TStyle::SetOptDate(Int_t optdate)
    if optdate is non null, the current date/time will be printed in the canvas.
    The position of the date string can be controlled by:
       optdate = 10*format + mode
       mode = 1   (default) date is printed in the bottom/left corner.
       mode = 2   date is printed in the bottom/right corner.
       mode = 3   date is printed in the top/right corner.
       format = 0 (default) date has the format like: "Wed Sep 25 17:10:35 2002"
       format = 1 date has the format like: "2002-09-25"
       format = 2 date has the format like: "2002-09-25 17:10:35"

    Examples:
       optdate = 1  date like "Wed Sep 25 17:10:35 2002" in the bottom/left corner.
       optdate = 13 date like "2002-09-25" in the top/right corner.

    New class TPaletteAxis
    ======================

    A TPaletteAxis object is used to display the color palette when
    drawing 2-d histograms. The object is automatically created when drawing a
    2-D histogram when the option "z" is specified.
    The object is added to the histogram list of functions and can be retrieved
    and its attributes changed with:
     TPaletteAxis *palette = (TPaletteAxis*)h->FindObject("palette");

    The palette can be interactively moved and resized. The context menu
    can be used to set the axis attributes.

    It is possible to select a range on the axis to set the min/max in z

    TBrowser
    ========

    Several improvements: bug fixes, new functions and faster. Removed
    limitation on number of items in the tree view in the left pane.

    TRandom classes
    ===============

    Modify the Rndm() function in the generator classes such that they never
    return 0.

    TProfile
    ========

    Modify TProfile::GetBinError() to disable the optimisation when the number
    of bins is greater than 1000. The time of the old algorithm was proportional
    to the number of bins, generating a N^2 problem when projecting a TProfile
    with a large number of bins (eg 100000).

    TGraph
    ======

    Changes in TGraph::SetMinimum,SetMaximum to use GetHistogram() instead of
    fHistogram. GetHistogram guarantees that fHistogram is computed.

    Fix a problem in TGraph::PaintGrapHist in low resolution mode with empty bins.

    In the fit functions, the test on Foption.Errors was not correct.
    As a result, the parabolic error was returned in case the maximum
    precision error had been requested and vice-versa.

    Rewrite TGraph::GetHistogram() to create the histogram without
    painting the graph.

    TGraphAsymmErrors
    =================

    Modify the algorithm computing the errors in X and Y in case of asymmetric
    errors. Instead of:
       return TMath::Sqrt(elow*elow + ehigh*ehigh);
    the new algorithm returns
       return TMath::Sqrt(0.5*(elow*elow + ehigh*ehigh));

    In the Paint() functions, optimize the distance between the error bar
    and the marker.

    THbookFile
    ==========

    Fix from Andrei Gaponenko:
    "For the lack of THbookChain, I tried to do an explicit loop over
    ntuples.  After processing about 50 files, the program started to
    complain about "too many hbook files open".  According to the code
    logic, no more than one hbook file should have been opened at a time.
    (TFile was an automatic object in a loop of a compiled program.)

    I have fixed this by changing the THbookFile(const char*, int)
    constructor, so that HROPEN() and HREND() are now called with the
    same CHTOP parameter.

    TGaxis
    ======

    Add a new option in TAxis and TGaxis to center the bin labels
    on the center of the bin instead of the tick marks.
    This option makes sense only when the number of bins is equal
    to the number of tick marks.
    The new function TAxis::CenterLabels sets the bit kCenterLabels.
    CenterLabels is visible in the TAxis context menu.

    TMinuit
    =======

    Add new data members
       Bool_t   fGraphicsMode;
       TObject *fPlot;

    By default fGraphicsMode is true.
    When calling the Minuit functions such as mncont, mnscan, or any Minuit
    command invoking mnplot, TMinuit::mnplot() produces a TGraph object
    pointed by fPlot. One can retrieve this object with TMinuit::GetPlot().
    For example, one can do:
       h->Fit("gaus");
       gMinuit->Command("SCAn 1");
       TGraph *gr = (TGraph*)gMinuit->GetPlot();
       gr->setMarkerStyle(21);
       gr->Draw("alp");

    To set Minuit in no graphics mode, call gMinuit->SetGraphicsMode(kFALSE).

    TMatrix
    =======

    Several improvements and bug fixes by Eddy Offermann:

    The operator*(const TMatrix &source1,const TMatrix &source2);
    was not correctely defined: it would multply matrix of transposed shapes:
      a(m,n) * b(n,m)

    Do not calculate /correct the matrix determinant if the user does
    not requests its value. Reason is that after rescaling by the
    diagonal it might be too large or too small.

    If rank(matrix) <= 3 determinant and matrix inversion
    formulas are hard-coded in order to improve speed,
    as requested by Nicolas Produit
        (http://root.cern.ch/root/roottalk/roottalk02/1136.html)
    Eddy has implemented a class called TMatrixFlat that lets
    you access the matrix elements as a flat array. Functionalities
    are identical to TMatrixRow, TMatrixColumn and TMatrixDiag.

    Added some constructors to TVector:
      TVector(const TMatrixRow &mr);
      TVector(const TMatrixColumn &mc);
      TVector(const TMatrixDiag &md);

    Operations like TMatrix(a,2) *= TMatrix(b,3) are now supported
    Elements in TVector/TMatrix/TMatrixRow ... can now be accessed
    with operator() and [].

    Code cleanup:
      - made functions static in TMatrix
      - enforced better "const"-ness
    in particular the Apply methods in TVector/TMatrix now
    have a "const" argument allowing constructs like (Nicolas Produit) in
       http://root.cern.ch/cgi-bin/print_hit_bold.pl/root/roottalk/roottalk02/0827.html

    Removed the MakeHilbert() function from TMatrix class.
    no reason to give this matrix type a special status.

    IsSymmetric was incorrect for non-square matrices: should fail
    if matrix is not square
    Added THilbertMatrix class just like the THaarrMatrix,
    both inheriting from TLazyMatrix. THaarMatrix and THilbertMatrix can now be
    accessed in the interpreter

    The InvertPosDef matrix complained when a matrix was not positive definite
    but nevertheless continued its calculation and returnd of course the wrong
    result. Now, an error message appears and the inversion is continued with
    the Gaus-Jordan algorithm.

    Geometry classes
    ================

    Once a geometry is sucessfully built, one can save it in a root file calling:
      TGeoManager::Export(const char *filename, const char *keyname="",
                          Option_t *option="v")
    where :
      filename -  name of the file to be written (mandatory)
      keyname  - name of the key in the file (default "")
      option   - "v" = export voxelization (default), otherwise
                       voxelization is recomputed after loading the geometry

    Loading a geometry from file can be done via the static member function:
      TGeoManager::Import(const char *filename, const char *keyname="",
                          Option_t *option="")
    Example:
      ... geometry definition
      root[0] gGeoManager->CloseGeometry();  // geometry ready
      ...
      root[1] gGeoManager->Export("MyGeom.root"); // file MyGeom.root produced

      root[0] TGeoManager::Import("MyGeom.root"); // geometry ready

    Boolean composite shapes (class TGeoCompositeShape) can be produced
    out of any shape known by the modeler, by using boolean operators:
    union (+), intersection (*) and subtraction (-) associated with shape
    names. Composite shapes are deriving from the abstract TGeoShape class
    so they can be used also to define other composite shapes. Local
    transformation matrices can apply to composite shape components. A full
    component identifier looks like: shape_name:matrix_name
    A composite shape is built using a boolean expression of component
    identifiers:

       cs = new TGeoCompositeShape("cs_name", "(A:m1+B:m2)-C");

    where: A,B,C are names of shapes previously defined, while m1, m2 are
    names of transformations that should apply to shapes in the composition.
    Any valid boolean expression is accepted. Missing transformation
    identifiers are interpreted as identity matrix. Transformations cannot
    be applied globally to such a boolean expression (e.g. "(A+B):m1" is not
    valid, while "(A+B):m1-C" is)

    Composite shapes cannot be visualized in the current version, but
    they are "visible" by the tracking methods FindNode() and
    FindNextBoundary() of the manager class.

    Several improvements in shape classes making the tracking algorithms
    much more reliable. Lego plots of radiation length can be globally
    computed for a given volume in the geometry (see TGeoVolume::LegoPlot()).
    Voxelization can be computed optimally in cylindrical coordinates in
    addition to cartesian ones. For the time being this option is not fully
    stable, so it is disabled, but in future it will be used in some cases
    in order to improve tracking performance in geometries having this type
    of symmetry.

    Visualization of geometry in the pad is using perspective view
    instead of parralel view. The view is now scaled w.r.t the absolute
    proportions of the drawing objects. Double-clicking volume vertices in
    the pad produces an animation so that the cliched volume grabs the focus
    of the view. Navigation can be performed using the same keys as in x3d
    view (see TViewerX3D::gHelpX3DViewer).

    TFile
    =====

    New function ReOpen():
       Reopen a file with a different access mode, like from READ to
       UPDATE or from NEW, CREATE, RECREATE, UPDATE to READ. Thus the
       mode argument can be either "READ" or "UPDATE". The method returns
       0 in case the mode was successfully modified, 1 in case the mode
       did not change (was already as requested or wrong input arguments)
       and -1 in case of failure, in which case the file cannot be used
       anymore.

    Several changes in the logic for file recovery. With this patch:
       - the case of a file currently being created by another process
         and connected by the current process is supported again.
       - The StreamerInfo record was not correctly read back. This fix
         is important in case one connects to a file without the shared lib.

    Add entry kRecovered in TFile enum.
    The bit kRecovered is set when Recover has been called on the file.
    A user can test if the file has been recovered with:
        file->TestBit(TFile::kRecovered);

    TROOT
    =====

    Extend TROOT::FindObjectAny() to also scan the memory list of all files
    in case no object is found in the folder structure.

    Correctly handle trailing +(+) in Macro() and LoadMacro(). Before we failed
    on path names containing ++, like .../g++/macro.C.

    TRef
    ====

    In TRef::GetObject() protect against the case where fPID points to
    a deleted processID using the new function TProcessID::IsValid.

    TString
    =======

    New method
       Int_t TString::CountChar(Int_t c) const
    returns the number of times character c appears in the TString.

    TUrl
    ====

    Add support for username and passwd embedded in url according to W3C specs.

    TBuffer + TKey + Meta Classes
    =============================

    Added the ability to save objects of classes using multiple
    inheritance (directly or indirectly) as part of other objects.
    Previously multiple inheritance was only supported for top level objects.

       TBuffer::WriteObject(const void *actualObjStart, TClass *actualClass);

    has been made protected. It is replaced by:

       TBuffer::WriteObjectAny(const void *obj, TClass *ptrClass);

    which has a slightly different semantic (for multiple inheriting classes).
    The value of 'obj' in expected to be a value that can be legally stored
    in a pointer to an object of the type described by 'ptrClass'.  I.e:
        MyClass *ptr;
        ....
        b.WriteObjectAny(ptr,gROOT->GetClass(typeid(MyClass)));

    We introduced:

       void    *ReadObjectAny(const TClass* cast);

    which returns a value suitable to be stored in a pointer to an object of
    the type described by the TClass object 'cast'.  I.e, a typical usage is:
       MyClass *ptr = (MyClass*)b.ReadObjectAny(MyClass::Class());

    The existing function:

        TObject *TBuffer::ReadObject(const TClass *clReq)

    now ignores its parameter and returns the address where the object read
    actually start.  It should be noted that if the object is of a class
    which derives from TObject but not as a first inheritance, this value is
    NOT a valid TObject*.  We recommend using ReadObjectAny() instead.

    In TGenericInfo.h, TGenericInfo.cxx, rootcint.cxx and TClass.cxx, we moved
    to always use an IsA() wrapper function instead of using the interpreter for
    TObjects.

    TClass.cxx has been modified to optimize a few functions now called many
    times.

    TStreamerInfo.cxx and TStreamerElement.cxx has been modified to use the
    new TBuffer function and to properly read/write multiple inheriting objects.

    The semantic of TKey::ReadObj has also been changed.  It now always returns
    a proper TObject pointer (which sometimes is NOT the address of the actual
    start of the object).  In particular, code that looks like:

       MyClass *obj = (MyClass*)((void*)key->ReadObj());

    should be changed to

      MyClass *obj = dynamic_cast<MyClass*>(key->ReadObj());

    TStreamerInfo
    =============

    In TStreamerInfo::BuildOld() add support for members moved to base classes
    even when the base class did not exist in the old version of the class.

    Changes by Victor for the STL support.

    Added support for I/O of the following types of data members:
    	MyClass  myArr[3];
    	MyClass *myArrFix[3];

    The following is NOT supported yet:
    	MyClass **myArrVar; //[index]
    This is already supported for TObject classes via a streamer generated by rootcint.

    TThread
    =======

    Several improvements by Mathieu de Naurois making the code safer and faster.

    THtml
    =====

    Many improvements by Axel Naumann:
    The USER_Index does not contain ROOT classes anymore, and THtml does not try
    to access files that are not there anymore. In addition:

     - check if file exists before creating .cxx.html
     - removed postscript created prompt, as TCanvas already says: Created
       file TWhatever_Tree.ps
     - Looks at impl file name, if that has format: base/src/TSomething.cxx,
       assume it comes from the BASE package. If impl file name is not set,
       look at decl file name and get package name the same way.

    New tutorials
    =============

    -tutorials/jets.C:
     illustrating the use of a Tree using the JetEvent class.
     The JetEvent class has several collections (TClonesArray)
     and other collections (TRefArray) referencing objects in the TClonesArrays.
     The JetEvent class is in $ROOTSYS/test/JetEvent.h,cxx
     to execute the script, do
       .x jets.C

    -JetEvent.cxx, JetEvent.h:
     a JetEvent emulates 2 detectors A and B producing each a TClonesArray
     of Hit objects. A TClonesArray  of Track objects is built with Hits objects
     of detectors A and B. Eack Track object has a TRefArray of hits.
     A TClonesArray of Jets is made with a subset of the Track objects
     also stored in a TRefArray.
     See $ROOTSYS/tutorials/jets.C for an example creating a Tree with JetEvents.

    -tutorials/tree2a.C:
     Same functionality than tree2.C but using a class instead of a C-struct.

    -tutorials/copytree3.C:
     illustrating how to
      - open a file
      - loop over the entries of a Tree
      - under certain conditions, copy selected entries into another Tree

    -tutorials/quarks.C:
     showing divided pads and TLatex.

    -tutorials/LDAPExample.C:
     showing usage of LDAP interface. Needs some tunings since
     currently it accesses too much data.

    New classes TLDAPServer, TLDAPAttribute, TLDAPResult
    ====================================================

    OpenLDAP interface by Evgenia Smirnova and Oleksandr Grebenyuk of GSI.

    PROOF
    =====

    Many improvements and new features. Almost deployment ready:
    - dynamic feedback objects that can be displayed while the query is running.
    - better packet size algorithm
    - signal to connect a progress meter to

    rootd
    =====

    Applied rootd patch by Ulrik Egede and Tim Adye from BaBar. New features:

    1) New option, -P FILE, to specify an alternate SRP password file. As an
       example

       rootd -P $HOME/.srootdpass2

       will start rootd using the files $HOME/.srootdpass2.conf and
       $HOME/.srootdpass2 for SRP authentication.

    2) Modified option, -p port1-port2, will search for the first available
       port in the range. You can also specify -p 0-N for search relative to the
       service port specified in /etc/services (this was sort of accidental, but
       not a bad feature :-). If a single port is specified as before, then no
       search is made.

    3) Unless started by inetd (rootd -i), it prints something like

        ROOTD_PORT=5151
        ROOTD_PID=14433

       before spawning the daemon so the user knows what was used (eval `rootd`
       will set these as variables in Bourne-shells).

    4) rootd now shows an error message (as well as the syslog message it
       always sent) if there is any problem binding the port or forking the
       daemon.

    RFIO access
    ===========

    Add capability to read directory structures via RFIO. This works via
    the TRFIOSystem helper class (which derives from TSystem) that is loaded
    by the plugin manager whenever one tries to access a rfio directory or file.
    This helper class is used in the actual system class (TUnixSystem,
    TWinNTSystem).

    rootcint
    ========

    Rootcint now properly detects that an operator new hides (for C++)
    any operator new with placement previously declared in the class hierarchy.

    Additions to support C-structs in the generated code for I/O.

    Add support for const data members.  Disable support for data members which
    are references.

    Stack Trace
    ===========

    Added stack trace code for Linux glibc based systems and AIX (via
    stack walker function xl__trbk()). Code borrowed from Lassi Tuura's
    ClassLib but improved by taking care of C++ symbol demangling and
    file and line number information (if compiled in debug mode). Later
    code will come for Solaris, Irix and True64. The stack trace can be
    disabled via the system.rootrc key "Root.Stacktrace". Default is on.

    GUI
    ===

    New method TGGroupFrame::SetTitlePos() allowing the positioning of the
    title of the group frame.

    Fix in TGButtonGroup::ButtonRelease(). Radiobuttons were not toggled
    correctly.

    TGListTree is now be able to handle very large tree's (not limited
    anymore by the bitmap size). Added key navigation options to TGListTree
    and some new signals.

    ACLIC
    =====

    Generalization of ACliC argument parsing. New method
    TSystem::SplitAclicMode(). Change in GetLibraries() to also
    allow for non regexp search (solves problem with pathnames containing
    regexp characters, like ++).

    Windows version
    ===============

    Fixed the problems on Window 98, XP, 2000 where ROOT
    was mysteriously, randomly crashing or giving error messages like 'this
    "text file name" is a binary file' or other weird behaviors.

    Window win32gdk version
    =======================

    A new version developed by Bertrand Bellenot. This new version supports
    the command mode in the MSDOS shell. The win32gdk version is fully
    compatible with the Unix version (GUI support in particular).
    The canvas graphics in this version is still slower than the native
    win32 version. We hope to improve the speed in the next release.
    Feedback is welcome.

    macosx
    ======

    Ported to Fink and custom installed (as per Keisuke Fujii's web page)
    X11 tools. Support Mac OS X 10.2.

    configure script
    ================

    allow also --enable-rpath when doing a ROOTSYS driven build. However,
    when using this option the build product is not relocatable anymore
    (i.e. the build directory cannot change location afterwards).