Here is what you will do in the act of developing code.
To rebuild after hacking on the source just type:
When ready to install into the configured “prefix” installation area:
$ waf install
To force a full rebuild:
$ waf clean build
To limit building to just one submodule:
$ cd <subdir>/ $ waf
To build for debugging one needs to reconfigure waf with a
--build-debug=<flags> option and then the project must be cleaned and rebuilt. This can be done all at once like:
$ waf --prefix=/path/to/install --build-debug=-ggdb3 clean configure build install
You may also want to see what commands Waf is actually running to confirm this option is transmitted, just add a
-v to the command line:
$ waf -v
Finally, run GDB in your usual, preferred manner:
$ gdb --args /home/bviren/projects/wire-cell/top/build/nav/test_geomdatasource (gdb) run
New wire-cell packages can be added easily.
Wire Cell packages are organized to be easy to create. It's much better to create many small packages and maybe later merge them than it is to split apart ones which have grown too monolithic. When thinking about writing some code consider
- What other packages will I need?
- What future packages will need mine?
You may have an idea for a package but in reality it is better split up into others. Here are reasons to believe your ideas fit into multiple packages:
- When I describe my expected package functionality I use the word "and".
- Some other package should use part of my package but the other part is not needed.
If in doubt, make more, smaller packages.
Source Package Conventions
To make them easy to build and aggregate they must follow a layout convention.
First, each source package should be kept in it's own git repository. The recommended package naming convention is:
NAME is some short identifier of the package's primary purpose.
The contents of the source package must be organized following these sub-directory conventions
src/ # C++ source file for libraries with .cxx extensions or private headers inc/NAME/ # public/API C++ header files with .h extensions dict/LinkDef.h # ROOT linkdef header (for rootcling dictionaries) tests/ # Unit tests Python (nosetests) files like test_*.py or main C++ programs named like test_*.cxx. apps/ # main application(s), one appname.cxx file for each app named appname (todo: not yet supported) python/NAME # python modules (todo: not yet supported) wscript_build # a brief waf file
wscript_build file specifies a name for the binary package (in general similar but not identical to the source package name) and a list of any other packages part of the wire-cell system on which it depends. For example the
wire-cell-nav source package builds to a
WireCellNav binary package and it depends on the WireCellData package and so its
wscript_build file is:
This is Python and the
bld object is a Waf build context. It is provided automagically when waf interprets this file.
The above is about code packages. Code packages are built via a build package. This build package,
wire-cell is but one possible "view" into all the wire cell packages. Other build packages may be created which only build some sub-set of all wire cell packages.
To add a new code package to a build package (such as this one) one must do a little, annoying dance:
$ mkdir <name> $ cd <name>/ $ echo "bld.make_package('WireCell<Name>', use='WireCellNav WireCellData')" > wscript_build $ git init $ git commit -a -m "Start code package <name>"
<name> with your package name. And, of course, you may want to put more code than just the
wscript_build file. Also, that file should list what packages your package depends on.
Now, make a new repository by going to the BNLIF GitHub and clicking "New repository" button. Give it a name like
wire-cell-<name>. Copy-and-paste the two command it tells you to use:
$ git remote add origin email@example.com:BNLIF/wire-cell-<name>.git $ git push -u origin master
Finally, move aside the local repository and add it right back as a submodule:
$ cd .. # back to top $ mv <name> <name>.moved $ git submodule add -- firstname.lastname@example.org:BNLIF/wire-cell-<name>.git <name> $ git submodule update $ git commit -a -m "Added <name> to top-level build package." $ git push
The namespace WireCell is used for all "core" wire cell code. Code that is used to glue this core functionality into other systems may use another namespace but should not use WireCell. For example, the "simple simulation tree" uses
It can be tedious to type explicit namespace qualifiers all the time. You can use the using namespace WireCell; directive where in implementation files (*.cxx) but you should never use it in (top-scope) of header files as it will then leak the contents of the namespace into any unsuspecting file that #include’s it.
Dealing with git submodules
From the git book, do you updates like:
$ git submodule update --remote --rebase
$ git submodule update --remote --merge
--rebase: put our local commits on top of any new ones
--merge: merge our commits into new ones
The first leaves a more "linear" commit history while the second leaves
"diamonds" in the history whenever we have briefly diverged from the
remote repository. You can run "
gitk --all" in wire-cell or one of the
submodules to see what I mean. Either way is fine. Rebasing looks
cleaner in the history but merge captures the subtle fact of where our
line of development actually diverged.
In that link there are other interesting things to do:
Configure your repository so "
git status" in the top-level "wire-cell" gives us more info on the status of all submodules:
$ git config status.submodulesummary 1
Make it so "
git diff" in wire-cell will also show any diff's in the submodules:
$ git config diff.submodule log
To check that we will push in the right order (submodules first):
$ git push --recurse-submodules=check
To force submodules to push first
$ git push --recurse-submodules=on-demand
To run any command in all submodules
$ git submodule foreach 'the command'