Page History
...
There are a number of targets that will be created based on what is in the package. For example, suppose one has the following files split between two packages in a release:
Code Block |
---|
release/
release/packageA
release/packageA/src/A1.cpp
release/packageA/src/A2.cpp
release/packageA/src/pythonA.py
release/packageA/include/A.h
release/packageA/app/programA1.cpp
release/packageA/app/programA2.cpp
release/packageA/app/appA
release/packageB/src/B1.cpp
release/packageB/src/B2.cpp
release/packageB/include/B.h
release/packageB/src/pythonB1.py
release/packageB/src/pythonB2.py
|
...
Scripts need to start with the appropriate #! line for the language used. For python, you should start you script with
Code Block |
---|
#!@PYTHON@
|
to use the same version of python that the release uses.
When C and C++ code includes a header file, it needs to be qualified by the package name. To use functions in the packageA library, files in packageB (as well as packageA itself) would do
Code Block |
---|
#include "packageA/fileA.h"
|
The way to access python modules is simply
Code Block |
---|
import packageA.pythonA
import packageB.pythonB1
import packageB.pythonB2
|
...
After you run scons
on the above files, you will see three new directories:
Code Block |
---|
release/include
release/build
release/arch
|
These directories belong to the build system - you should never put anything in these directories. They will be rebuilt each time scons
runs if need be.
In release/include
you will find two links to the package include directories:
Code Block |
---|
release/include/packageA --> release/packageA/include
release/include/packageB --> release/packageB/include
|
...
The same mechanism used to share package header files is also done for package data
and web
directories. That is, if one had the files:
Code Block |
---|
release/packageA/data/data_fileA
release/packageB/web/introB.html
|
after running scons
, the following directories would be created:
Code Block |
---|
release/data
release/web
|
and within those directories, the following softlinks
Code Block |
---|
release/data/packageA -> release/packageA/data
release/web/packageB -> release/packageB/web
|
...
The top level SConstruct
file implements several features that may be useful. Running
Code Block |
---|
scons -h
|
from the release directory displays all the available options. A few notable things one might do with the switches:
...
When getting your code working it can be convenient to stop compiling after the first error - less it scroll away after all the subsequent errors. One can do
Code Block |
---|
scons CCFLAGS=-Wfatal-errors
|
...
A useful tool for checking python code is pylint
. scons
will run pylint
and report any errors it finds on your python code if you do
Code Block |
---|
scons pylint
|
from the release directory.
...
Most packages require no additional options beyond those in the default configuration. If a package requires additional build options, these can often be added by calling the standardSConscript()
function in the SConscript file in the package directory. For instance, suppose a psana user is developing a module in a package called MyPackage
which needs to use functions from the Gnu Scientific Library. They would add the following line:
Code Block |
---|
standardSConscript(LIBS='gsl gslcblas')
|
To the file MyPackage/SConscript
. Here is a complete list of options you can set with standardSConscipt()
:
Code Block | ||||
---|---|---|---|---|
| ||||
LIBS - list of additional libraries needed by this package
LIBPATH - list of directories for additional libraries
BINS - dictionary of executables and their corresponding source files
TESTS - dictionary of test applications and their corresponding source files
SCRIPTS - list of scripts in app/ directory
UTESTS - names of the unit tests to run, if not given then all tests are unit tests
PYEXTMOD - name of the Python extension module, package name used by default
CCFLAGS - additional flags passed to C/C++ compilers
NEED_QT - set to True to enable Qt support
|
...
Suppose you have the files:
Code Block |
---|
mycode/myheader.h
mycode/mysource.cpp
mycode/libmylib.so
|
That is you have a dynamic library built out of some source code. If you want to call functions in mylib from packageA, you could modify packageA/SConscript to have
Code Block |
---|
standardSConscript(CCFLAGS="-I/reg/neh/home/username/mycode", LIBPATH='/reg/neh/home/username/mycode', LIBS='mylib')
|
Then targets in packageA could do
Code Block |
---|
#include "myheader.h"
|
To find the header file (given the use of CCFLAGS above) and the library mylib will be added to the link line.Note (unfortunately
) that While targets in packageA that use mylib can now be built correctly, to run them you will need to make sure that the operating system can find the shared object library mylib. This is done by setting the environment variable LD_LIBRARY_PATH must be updated manually with the LIBPATH value above so psana can locate the shared library at runtime.to include the directory where mylib is located. This could be done in the shell initialization file (such as .bashrc, or .cshrc, depending on which shell you use).
Using a Library through the External Package Mechanism
...