diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..dbda8d61e28b3344c0f9920ac1975ccd2f1fe47c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,29 @@ +# After changing this file, run it through http://lint.travis-ci.org/ +# Generates 4 builds, the ones for python3 will install external wheels +language: python +python: + - 2.6 + - 2.7 +matrix: + include: + - python: 3.2 + env: + - NUMPYSPEC===1.7.1 + - python: 3.3 + env: + - NUMPYSPEC===1.8.0 +before_install: + - sudo add-apt-repository -y ppa:biometrics/bob + - sudo apt-get update -qq + - sudo apt-get install -qq bob-dev + - if [ -n "${NUMPYSPEC}" ]; then sudo apt-get install -qq libatlas-dev libatlas-base-dev liblapack-dev gfortran; fi + - if [ -n "${NUMPYSPEC}" ]; then pip install --upgrade pip setuptools; fi + - if [ -n "${NUMPYSPEC}" ]; then pip install --find-links http://wheels.astropy.org/ --find-links http://wheels2.astropy.org/ --use-wheel numpy$NUMPYSPEC sphinx nose; fi +install: + - "python bootstrap.py" + - "./bin/buildout" +script: + - "./bin/python -c 'from xbob.learn.activation import get_config; print(get_config())'" + - "./bin/nosetests -sv" + - "./bin/sphinx-build -b doctest doc sphinx" + - "./bin/sphinx-build -b html doc sphinx" diff --git a/buildout.cfg b/buildout.cfg index aef0b05b9be6c6b1717c8f9e7557285a206e7abc..dcaf2d3ade3578d713cdd0bbc74183587b15b7f5 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -17,12 +17,12 @@ develop = src/xbob.extension debug = true verbose = true prefixes = /idiap/group/torch5spro/nightlies/last/bob/linux-x86_64-release - /Users/andre/work/bob/b/dbg/ + /Users/andre/work/bob/b/dbgx/ [sources] -xbob.extension = git git@github.com:bioidiap/xbob.extension branch=prototype -xbob.blitz = git git@github.com:bioidiap/xbob.blitz -xbob.io = git git@github.com:bioidiap/xbob.io +xbob.extension = git https://github.com/bioidiap/xbob.extension branch=prototype +xbob.blitz = git https://github.com/bioidiap/xbob.blitz +xbob.io = git https://github.com/bioidiap/xbob.io [scripts] recipe = xbob.buildout:scripts diff --git a/setup.py b/setup.py index b07399d31066f3be85cc7ccaf69999dbb95af1ef..2c538080b7a3193c8d8eea5c8110e8144dbfdc2c 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ package_dir = os.path.dirname(os.path.realpath(__file__)) package_dir = os.path.join(package_dir, 'xbob', 'learn', 'activation', 'include') include_dirs = [package_dir, xbob.io.get_include()] -packages = ['bob-machine >= 1.3'] +packages = ['bob-machine >= 1.2.2'] version = '2.0.0a0' setup( @@ -43,6 +43,14 @@ setup( ], ext_modules = [ + Extension("xbob.learn.activation.version", + [ + "xbob/learn/activation/version.cpp", + ], + packages = packages, + include_dirs = include_dirs, + version = version, + ), Extension("xbob.learn.activation._library", [ "xbob/learn/activation/activation.cpp", diff --git a/xbob/learn/activation/__init__.py b/xbob/learn/activation/__init__.py index 05534bd471f8685d1f9abd3e4b1ed2e1f0bcc9a9..82a60a698dd6bdb3ce58788bf9c65efa03b60fef 100644 --- a/xbob/learn/activation/__init__.py +++ b/xbob/learn/activation/__init__.py @@ -1,10 +1,32 @@ from ._library import * -from ._library import __version__, __api_version__ +from . import version +from .version import module as __version__ +from .version import api as __api_version__ def get_include(): """Returns the directory containing the C/C++ API include directives""" return __import__('pkg_resources').resource_filename(__name__, 'include') +def get_config(): + """Returns a string containing the configuration information. + """ + + import pkg_resources + from .version import externals + + packages = pkg_resources.require(__name__) + this = packages[0] + deps = packages[1:] + + retval = "%s: %s [api=0x%04x] (%s)\n" % (this.key, this.version, + version.api, this.location) + retval += " - c/c++ dependencies:\n" + for k in sorted(externals): retval += " - %s: %s\n" % (k, externals[k]) + retval += " - python dependencies:\n" + for d in deps: retval += " - %s: %s (%s)\n" % (d.key, d.version, d.location) + + return retval.strip() + # gets sphinx autodoc done right - don't remove it __all__ = [_ for _ in dir() if not _.startswith('_')] diff --git a/xbob/learn/activation/version.cpp b/xbob/learn/activation/version.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ea3606a97566ddeff32f74aff4b1055b4d8a3439 --- /dev/null +++ b/xbob/learn/activation/version.cpp @@ -0,0 +1,185 @@ +/** + * @author Andre Anjos <andre.anjos@idiap.ch> + * @date Thu 7 Nov 13:50:16 2013 + * + * @brief Binds configuration information available from bob + */ + +#include <Python.h> + +#include <xbob.learn.activation/config.h> +#include <xbob.io/api.h> + +#include <bob/config.h> + +#include <string> +#include <cstdlib> +#include <blitz/blitz.h> +#include <boost/preprocessor/stringize.hpp> +#include <boost/version.hpp> +#include <boost/format.hpp> + +#ifdef NO_IMPORT_ARRAY +#undef NO_IMPORT_ARRAY +#endif +#include <xbob.blitz/capi.h> +#include <xbob.blitz/cleanup.h> + +static int dict_set(PyObject* d, const char* key, const char* value) { + PyObject* v = Py_BuildValue("s", value); + if (!v) return 0; + int retval = PyDict_SetItemString(d, key, v); + Py_DECREF(v); + if (retval == 0) return 1; //all good + return 0; //a problem occurred +} + +static int dict_steal(PyObject* d, const char* key, PyObject* value) { + if (!value) return 0; + int retval = PyDict_SetItemString(d, key, value); + Py_DECREF(value); + if (retval == 0) return 1; //all good + return 0; //a problem occurred +} + +/** + * Describes the version of Boost libraries installed + */ +static PyObject* boost_version() { + boost::format f("%d.%d.%d"); + f % (BOOST_VERSION / 100000); + f % (BOOST_VERSION / 100 % 1000); + f % (BOOST_VERSION % 100); + return Py_BuildValue("s", f.str().c_str()); +} + +/** + * Describes the compiler version + */ +static PyObject* compiler_version() { +# if defined(__GNUC__) && !defined(__llvm__) + boost::format f("%s.%s.%s"); + f % BOOST_PP_STRINGIZE(__GNUC__); + f % BOOST_PP_STRINGIZE(__GNUC_MINOR__); + f % BOOST_PP_STRINGIZE(__GNUC_PATCHLEVEL__); + return Py_BuildValue("ss", "gcc", f.str().c_str()); +# elif defined(__llvm__) && !defined(__clang__) + return Py_BuildValue("ss", "llvm-gcc", __VERSION__); +# elif defined(__clang__) + return Py_BuildValue("ss", "clang", __clang_version__); +# else + return Py_BuildValue("s", "unsupported"); +# endif +} + +/** + * Python version with which we compiled the extensions + */ +static PyObject* python_version() { + boost::format f("%s.%s.%s"); + f % BOOST_PP_STRINGIZE(PY_MAJOR_VERSION); + f % BOOST_PP_STRINGIZE(PY_MINOR_VERSION); + f % BOOST_PP_STRINGIZE(PY_MICRO_VERSION); + return Py_BuildValue("s", f.str().c_str()); +} + +/** + * Bob version, API version and platform + */ +static PyObject* bob_version() { + return Py_BuildValue("sis", BOB_VERSION, BOB_API_VERSION, BOB_PLATFORM); +} + +/** + * Numpy version + */ +static PyObject* numpy_version() { + return Py_BuildValue("{ssss}", "abi", BOOST_PP_STRINGIZE(NPY_VERSION), + "api", BOOST_PP_STRINGIZE(NPY_API_VERSION)); +} + +/** + * xbob.blitz c/c++ api version + */ +static PyObject* xbob_blitz_version() { + return Py_BuildValue("{ss}", "api", BOOST_PP_STRINGIZE(XBOB_BLITZ_API_VERSION)); +} + +/** + * xbob.io c/c++ api version + */ +static PyObject* xbob_io_version() { + return Py_BuildValue("{ss}", "api", BOOST_PP_STRINGIZE(XBOB_IO_API_VERSION)); +} + +static PyObject* build_version_dictionary() { + + PyObject* retval = PyDict_New(); + if (!retval) return 0; + auto retval_ = make_safe(retval); + + if (!dict_set(retval, "Blitz++", BZ_VERSION)) return 0; + if (!dict_steal(retval, "Boost", boost_version())) return 0; + if (!dict_steal(retval, "Compiler", compiler_version())) return 0; + if (!dict_steal(retval, "Python", python_version())) return 0; + if (!dict_steal(retval, "NumPy", numpy_version())) return 0; + if (!dict_steal(retval, "xbob.blitz", xbob_blitz_version())) return 0; + if (!dict_steal(retval, "xbob.io", xbob_io_version())) return 0; + if (!dict_steal(retval, "Bob", bob_version())) return 0; + + Py_INCREF(retval); + return retval; +} + +static PyMethodDef module_methods[] = { + {0} /* Sentinel */ +}; + +PyDoc_STRVAR(module_docstr, +"Information about software used to compile the C++ Bob API" +); + +#if PY_VERSION_HEX >= 0x03000000 +static PyModuleDef module_definition = { + PyModuleDef_HEAD_INIT, + XBOB_EXT_MODULE_NAME, + module_docstr, + -1, + module_methods, + 0, 0, 0, 0 +}; +#endif + +static PyObject* create_module (void) { + +# if PY_VERSION_HEX >= 0x03000000 + PyObject* m = PyModule_Create(&module_definition); +# else + PyObject* m = Py_InitModule3(XBOB_EXT_MODULE_NAME, module_methods, module_docstr); +# endif + if (!m) return 0; + auto m_ = make_safe(m); ///< protects against early returns + + /* register version numbers and constants */ + if (PyModule_AddIntConstant(m, "api", XBOB_LEARN_ACTIVATION_API_VERSION) < 0) + return 0; + if (PyModule_AddStringConstant(m, "module", XBOB_EXT_MODULE_VERSION) < 0) + return 0; + + PyObject* externals = build_version_dictionary(); + if (!externals) return 0; + if (PyModule_AddObject(m, "externals", externals) < 0) return 0; + + if (import_xbob_blitz() < 0) return 0; + + Py_INCREF(m); + return m; + +} + +PyMODINIT_FUNC XBOB_EXT_ENTRY_NAME (void) { +# if PY_VERSION_HEX >= 0x03000000 + return +# endif + create_module(); +}