Migration to the g++-3.3 compiler

During the April 2007 shutdown, the NSCL will be migrating its default gnu compilers from version 2.95 to version 3.3. What this means is that the following compilation commands will be available: gcc # Runs gcc-3.3 g++ # Runs g++-3.3 gcc-2.95 # Runs gcc-2.95 g++-2.95 # Runs g++-2.95 gcc-3.3 # Runs gcc-3.3 g++-3.3 # Runs g++-3.3 Objects compiled with g++-3.3 cannot be intermixed with objects compiled under g++-2.95 as these two compilers use different name mangling schemes.

This document describes:

Non-standard Makefile

Makefiles that depend on gcc or g++ being the 2.95 compilers will need to explicitly select these compilers. We suggest that you centralize these changes. Suppose, for example, you have makefile lines that look like: thing.o: thing.cpp g++ -c thing.cpp We recommend you define towards the top of your Makefile: CXX=/usr/bin/g++-2.95 and then change lines like the compilation shown at the start of this section to: thing.o: thing.cpp $(CXX) -c thing.cpp This will allow you to switch compilers easily as you migrate your application to the g++-3.3 or later compilers.

Note that if you are using Makefiles based on those in the current Skel directories in nscldaq or SpecTcl, a similar technique is used.

Migrating from SpecTcl-2.x to SpecTcl 3.y

This section is an extract from http://groups.nscl.msu.edu/computer/webs/bin/view/Main/SpecTcl30ReleaseNotes

Source File changes

All C++ files that are built into tailored SpecTcl software must be modified at least slightly. Prior to the first include insert:

#include <config.h>
#ifdef HAVE_STD_NAMESPACE
using namespace std;
#endif

Note that as of SpecTcl 3.0, if you use an unpacked parameter (element of the CEvent array or a TreeParameter) on the right hand side of an expression before it is given a value, SpecTcl will throw an exception and you will get an error message at run-time that looks like:


Attempted getValue of unset ValidValue object

If you need to ensure that a Parameter (either CEvent element or TreeParameter) has been assigned a value you can call its isValid() member function. CEvent::isValid() and CTreeParameter::isValid() return true if the object has been assigned a value.

Suppose a, b, and c are CTreeParameter objects, or CEvent& elements: The following may be dangerous (depending on how well protected this code path is):


  a = b + c;

Safe is:

   if (b.isValid() && c.isValid()) {
     a = b + c;
   }

Tree parameter changes

The TreeParameter and TreeVariable subsystem written by Daniel Bazin has been incoporated into the supported part of SpecTcl. In doing so, parts of this package were re-written, and some operations you used to have to supply in MySpecTclApp.cpp are done for you transparently by SpecTcl.

Summarizing:

Wherever you see:

#include <../contrib/treeparam/TreeParameter.h>
#include <../contrig/treeparam/TreeVariable.h>

Replace these lines with:

#include <TreeParameter.h>

Note that you only need to include <TreeParameter.h> there is no <TreeVariable.h> header. Use <TreeParameter.h> where you would have used <TreeVariable.h> as well.

Locate:

CTreeParameter::BindParameters(rAnalyzer);

and remove it, SpecTcl now does this for you.

Locate:

CTreeVariable::BindVariables(rInterp);

and remove it, SpecTcl now does this for you.

Locate:

CTreeVariableCommand* m_treevariable;
m_treevariable = new CTreeVariableCommand(&rInterp);
m_treevariable->Register();
CTreeParameterCommand* m_treeparameter;
m_treeparameter = new CTreeParameterCommand(&rInterp);
m_treeparameter->Register();

And remove these lines. SpecTcl does this for you now.

Locate:

CTreeParameter::setEvent(rEvent);

and remove this line. SpecTcl will do this for you now.

In your SpecTclRC.tcl file, or files it sources... locate the line:

source $SpecTclHome/contrib/treeparam/SpecTclGui.tcl

and replace it with:

source $SpecTclHome/Script/SpecTclGui.tcl

Migrating from nscldaq-7.x to nscldaq-8.x

This section is extracted from http://groups.nscl.msu.edu/computer/webs/bin/view/Main/NsclDaq80ReleaseNotes

In order to allow Readout to compile under new gcc compilers (and to provide hooks for compilation under other compilers), some source file changes are necessary when migrating to 8.0. Usually these will be minor. If you have C++ or C source code that is not standard compliant, you may get additional compiler diagnostics that must be evaluated and fixed on a case by case basis, as the 3.x and later compilers become increasingly strict about enforcing the language standard.

At the top of each source file add the lines:

#include <config.h>
#ifdef HAVE_STD_NAMESPACE
using namespace std;
#endif

In your Makefile, locate the line that reads:

INSTDIR=/usr/opt/daq/7.4

and change it to read:

INSTDIR=/usr/opt/daq/8.0

If your makefiles date from prior to 7.4 (examine the skeleton makefiles to see if they do), you must change to the 8.0 form of the Makefile, available in the skeleton directories.

Note that this new Makefile form does not require you to specify how to build objects from your sources. default build rules are established that describe how to create .o files from .cpp files.

Migrating to the 'high performance' readout skeletons.

Peformance analysis of the Readout software revealed that one performance problem was the overhead associated with individually placing words in the Spectrodaq buffer. To help relieve this bottleneck, "high performance" versions of both Readout and the production readout software were added to nscldaq-8.0. If you migrate your code to these you can expect improvements in the dead-time of your readout software, in some cases, dramatic improvements.

The high performance versions of these programs require source code modifications to application code in addition to those described in the previous section. The high performance readouts read data into an ordinary memory buffer. When this buffer is full, it is block copied into a spectrodaq buffer and routed to DAQ clients. To migrate your software to these versions you will need to:

Due to differences in libraries and headers you should not attempt to change your current makefiles, but should use the skeleton makefiles for the high-performance software!!

High performance Classic Readout

The skeleton for the hich performance version of Readout classic is in /usr/opt/daq/8.0/Readout/hpskel

The only change you need to take into account is that the bufpt parameter of readevt is defined as UINT16* rather than a DAQWordBufferPtr&. If your software breaks up the readout into several modules, you will have to modify ensure that UINT16*'s are passed into subsidiary read functions in all other modules as well.

For example:

class aReadSegment {
 ...
public:
   ...

   int read(DAQWordBufferptr& buffer);   //<-----
};

The line indicated and the corresponding implementation becomes:

    int read(UINT16* buffer);

While it does not hurt to do so, it is no longer necessary to:

#include <spectrodaq.h>

High performance Production Readout

The skeleton for the high performance production readout software is in /usr/opt/daq/8.0/HPpReadoutSkeleton

The production readout software breaks up the readout into objects that are instances of classes derived from the CEventSegment. Each class of this type must implement a Read member function. For the standard production readout software, the signature of this function is:

   DAQWordBufferPtr& Read(DAQWordBufferptr& rBuffer)

You must modify your event segment classes to make the signature of the Read function:

    unsigned short* Read(unsigned short* rBuffer)