diff --git a/setup.py b/setup.py index ec03a373a1b7ddbe5e7758009b30cb7daa09b3e6..677ea0210521376ff6bcd06e65580ec8fe406a20 100644 --- a/setup.py +++ b/setup.py @@ -7,6 +7,8 @@ bob_packages = ['bob.core'] from setuptools import setup, find_packages, dist dist.Distribution(dict(setup_requires=['bob.extension', 'bob.blitz'] + bob_packages)) +from bob.extension.utils import egrep, find_header, find_library +from bob.extension.pkgconfig import pkgconfig from bob.blitz.extension import Extension, Library, build_ext from bob.extension.utils import load_requirements @@ -15,9 +17,131 @@ build_requires = load_requirements() # Define package version version = open("version.txt").read().rstrip() -packages = ['boost', 'hdf5'] +packages = ['boost'] boost_modules = ['system', 'filesystem'] +import os +def libhdf5_version(header): + + vv = egrep(header, r"#\s*define\s+H5_VERSION\s+\"([\d\.]+)\"") + if not len(vv): return None + return vv[0].group(1) + +class hdf5: + + def __init__ (self, requirement='', only_static=False): + """ + Searches for libhdf5 in stock locations. Allows user to override. + + If the user sets the environment variable BOB_PREFIX_PATH, that prefixes + the standard path locations. + + Parameters: + + requirement, str + A string, indicating a version requirement for this library. For example, + ``'>= 8.2'``. + + only_static, boolean + A flag, that indicates if we intend to link against the static library + only. This will trigger our library search to disconsider shared + libraries when searching. + """ + import os + + self.name = 'hdf5' + + # try to use pkg_config first + try: + pkg = pkgconfig('hdf5') + self.include_directories = pkg.include_directories() + version_header = os.path.join(self.include_directories[0], 'H5pubconf.h') + self.version = libhdf5_version(version_header) + self.libraries = pkg.libraries() + self.library_directories = pkg.library_directories() + except RuntimeError: + + # locate pkg-config on our own + header = 'hdf5.h' + + candidates = find_header(header) + + if not candidates: + raise RuntimeError("could not find %s's `%s' - have you installed %s on this machine?" % (self.name, header, self.name)) + + found = False + + if not requirement: + self.include_directories = [os.path.dirname(candidates[0])] + directory = os.path.dirname(candidates[0]) + version_header = os.path.join(directory, 'H5pubconf.h') + self.version = libhdf5_version(version_header) + found = True + + else: + + # requirement is 'operator' 'version' + operator, required = [k.strip() for k in requirement.split(' ', 1)] + + # now check for user requirements + for candidate in candidates: + directory = os.path.dirname(candidate) + version_header = os.path.join(directory, 'H5pubconf.h') + vv = libhdf5_version(version_header) + available = LooseVersion(vv) + if (operator == '<' and available < required) or \ + (operator == '<=' and available <= required) or \ + (operator == '>' and available > required) or \ + (operator == '>=' and available >= required) or \ + (operator == '==' and available == required): + self.include_directories = [os.path.dirname(candidate)] + self.version = vv + found = True + break + + if not found: + raise RuntimeError("could not find the required (%s) version of %s on the file system (looked at: %s)" % (requirement, self.name, ', '.join(candidates))) + + # normalize + self.include_directories = [os.path.normpath(self.include_directory)] + + # find library + prefix = os.path.dirname(os.path.dirname(self.include_directory)) + module = 'hdf5' + candidates = find_library(module, version=self.version, prefixes=[prefix], only_static=only_static) + + if not candidates: + raise RuntimeError("cannot find required %s binary module `%s' - make sure libhdf5 is installed on `%s'" % (self.name, module, prefix)) + + # libraries + self.libraries = [] + name, ext = os.path.splitext(os.path.basename(candidates[0])) + if ext in ['.so', '.a', '.dylib', '.dll']: + self.libraries.append(name[3:]) #strip 'lib' from the name + else: #link against the whole thing + self.libraries.append(':' + os.path.basename(candidates[0])) + + # library path + self.library_directories = [os.path.dirname(candidates[0])] + + def macros(self): + return [ + ('HAVE_%s' % self.name.upper(), '1'), + ('%s_VERSION' % self.name.upper(), '"%s"' % self.version), + ] + + +hdf5_pkg = hdf5() + +system_include_dirs = hdf5_pkg.include_directories + +library_dirs = hdf5_pkg.library_directories + +libraries = hdf5_pkg.libraries + +define_macros = hdf5_pkg.macros() + + setup( name='bob.io.base', @@ -47,6 +171,8 @@ setup( [ "bob/io/base/version.cpp", ], + define_macros = define_macros, + system_include_dirs = system_include_dirs, version = version, bob_packages = bob_packages, packages = packages, @@ -75,6 +201,10 @@ setup( "bob/io/base/cpp/array_type.cpp", "bob/io/base/cpp/blitz_array.cpp", ], + libraries = libraries, + library_dirs = library_dirs, + system_include_dirs = system_include_dirs, + define_macros = define_macros, version = version, bob_packages = bob_packages, packages = packages, @@ -89,6 +219,10 @@ setup( "bob/io/base/hdf5.cpp", "bob/io/base/main.cpp", ], + library_dirs = library_dirs, + libraries = libraries, + define_macros = define_macros, + system_include_dirs = system_include_dirs, version = version, bob_packages = bob_packages, packages = packages,