cyclus/cyclus — pull request #1003 by scopatz (2014-09-10 16:24:47+00:00)
Title: Symbol diffing utility for releases

This PR adds a utility for computing, storing, and diffing the symbols present in libcyclus. This took me a couple of times to get right, but I think I *finally* have it without expending extraordinary effort. The bulk of this is a tool called `smbchk` in a new top-level `release` directory. From the help:

```bash
~/cyclus/release rel $ ./smbchk.py -h
usage: smbchk [-h] [--prefix PREFIX] [-f FILENAME] [--dump] [--update]
[--save] [--no-save] [-t TAG] [-c] [-d DIFF DIFF]

Collects & diffs public symobls in libcyclus.so. Used to ensure stability
between versions. Now with 100% fewer vowels!

The following tasks may be useful:

# update the database to the most recent release tag
$ ./smbchk.py --update -t 1.X.Y

# check that the existing database is stable
$ ./smbchk.py --check

# check if HEAD is stable, a diff will be printed if it is not
$ ./smbchk.py --update -t HEAD --no-save --check

optional arguments:
-h, --help show this help message and exit
--prefix PREFIX location of lib dir with libcyclus, default '../build'
-f FILENAME, --filename FILENAME
historical symbols database, default 'symbols.json'
--dump dumps existing symbols
--update updates the symbols with the current version
--save saves the database
--no-save does not save the database
-t TAG, --tag TAG version tag used when updating, eg 1.0.0-rc5
-c, --check checks that the API is stable
-d DIFF DIFF, --diff DIFF DIFF
takes the difference between two database indices
```

I have also done the honor and added the symbols from the 1.0.0 release. For various reasons, this is only suitable to run with GNU's version of the `nm` utility. Whatever one ships with mac does not work because Apple is not compatible with anything anymore. Since this is a release manager tool, I don't think that posix-only will be a limiting feature.

Additionally, this relies on the trailing underscore naming convention to indicate private for symbols which make it though to be extern'd. Frankly, I didn't think that was possible! But apparently if you have static private members, they are visible because they need to be allocated only once, or all instances need to be able to see them, or some such. (See [here](https://groups.google.com/d/topic/pyne-dev/uvdzwjCoRpU/discussion) for a more in-depth rant against access control.)

That said, I think this will be a boon to us going forward. Needed for v1.1 for sure.