Skip to content
Snippets Groups Projects
Commit bd98b574 authored by André Anjos's avatar André Anjos :speech_balloon:
Browse files

Merge branch 'conda-prefix' into 'master'

Add CONDA_PREFIX to the search path

See merge request !62
parents 2353a3cc c0b6cfca
Branches
No related tags found
1 merge request!62Add CONDA_PREFIX to the search path
Pipeline #
...@@ -16,9 +16,17 @@ import distutils.sysconfig ...@@ -16,9 +16,17 @@ import distutils.sysconfig
from pkg_resources import resource_filename from pkg_resources import resource_filename
DEFAULT_PREFIXES = [
"/opt/local",
"/usr/local",
"/usr",
]
"""The list common places to search for library-related files."""
from .pkgconfig import pkgconfig from .pkgconfig import pkgconfig
from .boost import boost from .boost import boost
from .utils import uniq, uniq_paths, find_executable, find_library from .utils import uniq, uniq_paths, find_executable, find_library, construct_search_paths
from .cmake import CMakeListsGenerator from .cmake import CMakeListsGenerator
from .rc_config import _loadrc from .rc_config import _loadrc
......
...@@ -7,12 +7,35 @@ import os ...@@ -7,12 +7,35 @@ import os
import sys import sys
import subprocess import subprocess
import logging import logging
from .utils import uniq, uniq_paths, find_executable from .utils import uniq, uniq_paths, find_executable, construct_search_paths
def call_pkgconfig(cmd, paths=None):
"""Runs a command as a subprocess and raises if that does not work
Returns the exit status, stdout and stderr. def call_pkgconfig(cmd, paths=None):
"""Calls pkg-config with a constructed PKG_CONFIG_PATH environment variable.
The PKG_CONFIG_PATH variable is constructed using
:any:`construct_search_paths`.
Parameters
----------
cmd : [str]
A list of commands to be given to pkg-config.
paths : [str]
A list of paths to be added to PKG_CONFIG_PATH.
Returns
-------
returncode : int
The exit status of pkg-config.
stdout : str
The stdout output of pkg-config.
stderr : str
The stderr output of pkg-config.
Raises
------
OSError
If the `pkg-config' executable is not found.
""" """
# locates the pkg-config program # locates the pkg-config program
...@@ -20,27 +43,8 @@ def call_pkgconfig(cmd, paths=None): ...@@ -20,27 +43,8 @@ def call_pkgconfig(cmd, paths=None):
if not pkg_config: if not pkg_config:
raise OSError("Cannot find `pkg-config' - did you install it?") raise OSError("Cannot find `pkg-config' - did you install it?")
# sets the PKG_CONFIG_PATH taking into consideration: pkg_path = construct_search_paths(
# 1. BOB_PREFIX_PATH, if set prefixes=paths, suffix=os.sep + 'lib' + os.sep + 'pkgconfig')
# 2. the paths set by the user
# 3. the current python executable prefix
# 1. BOB_PREFIX_PATH
bob_prefix = os.environ.get('BOB_PREFIX_PATH', False)
if bob_prefix:
bob_prefix = bob_prefix.split(os.pathsep)
pkg_path = [os.path.join(k, 'lib', 'pkgconfig') for k in bob_prefix]
else:
pkg_path = []
# 2. user path
if paths: pkg_path += paths
# 3. adds the current python executable prefix
pkg_path.append(os.path.join(os.path.dirname(os.path.dirname(sys.executable)), 'lib', 'pkgconfig'))
# Make unique to avoid searching twice
pkg_path = uniq_paths(pkg_path)
env = os.environ.copy() env = os.environ.copy()
var = os.pathsep.join(pkg_path) var = os.pathsep.join(pkg_path)
...@@ -83,6 +87,7 @@ def version(): ...@@ -83,6 +87,7 @@ def version():
return stdout.strip() return stdout.strip()
class pkgconfig: class pkgconfig:
"""A class for capturing configuration information from pkg-config """A class for capturing configuration information from pkg-config
......
...@@ -11,59 +11,62 @@ import sys ...@@ -11,59 +11,62 @@ import sys
import glob import glob
import platform import platform
import pkg_resources import pkg_resources
from . import DEFAULT_PREFIXES
DEFAULT_PREFIXES = [
"/opt/local",
"/usr/local", def construct_search_paths(prefixes=None, subpaths=None, suffix=None):
"/usr", """Constructs a list of candidate paths to search for.
]
The list of paths is constructed using the following order of priority:
def find_file(name, subpaths=None, prefixes=None):
"""Finds a generic file on the file system. Returns all candidates. 1. ``BOB_PREFIX_PATH`` environment variable, if set. ``BOB_PREFIX_PATH`` can
contain several paths divided by :any:`os.pathsep`.
This method will find all occurrences of a given name on the file system and 2. The paths provided with the ``prefixes`` parameter.
will return them to the user. 3. The current python executable prefix.
4. The ``CONDA_PREFIX`` environment variable, if set.
If the environment variable ``BOB_PREFIX_PATH`` is set, then it is 5. :any:`DEFAULT_PREFIXES`.
considered a unix path list that is prepended to the list of prefixes to
search for. The environment variable has the highest priority on the search Parameters
order. The order on the variable for each path is respected. ----------
prefixes : [:obj:`str`], optional
Parameters: The list of paths to be added to the results.
subpaths : [:obj:`str`], optional
name, str A list of subpaths to be appended to each path at the end. For
The name of the file to be found, including extension example, if you specify ``['foo', 'bar']`` for this parameter, then
``os.path.join(paths[0], 'foo')``,
subpaths, str list ``os.path.join(paths[0], 'bar')``, and so on are added to the returned
A list of subpaths to be appended to each prefix for the search. For paths. Globs are accepted in this list and resolved using the function
example, if you specificy ``['foo', 'bar']`` for this parameter, then :py:func:`glob.glob`.
search on ``os.path.join(prefixes[0], 'foo')``, ``os.path.join(prefixes[0], suffix : :obj:`str`, optional
'bar')``, and so on. Globs are accepted in this list and resolved using ``suffix`` will be appended to all paths except ``prefixes``.
the function :py:func:`glob.glob`.
Returns
prefixes, str list -------
A list of prefixes that will be searched prioritarily to the paths : [str]
``DEFAULT_PREFIXES`` defined in this module. A list of unique and existing paths to be used in your search.
Returns a list of filenames that exist on the filesystem, matching your
description.
""" """
search = [] search = []
suffix = suffix or ''
# Priority 1: the environment # Priority 1: the environment
if 'BOB_PREFIX_PATH' in os.environ: if 'BOB_PREFIX_PATH' in os.environ:
search += os.environ['BOB_PREFIX_PATH'].split(os.pathsep) paths = os.environ['BOB_PREFIX_PATH'].split(os.pathsep)
search += [p + suffix for p in paths]
# Priority 2: user passed paths # Priority 2: user passed paths
if prefixes: if prefixes:
search += prefixes search += prefixes
# Priority 3: the current system executable # Priority 3: the current system executable
search.append(os.path.dirname(os.path.dirname(sys.executable))) search.append(os.path.dirname(os.path.dirname(sys.executable)) + suffix)
# Priority 4: the conda prefix
conda_prefix = os.environ.get('CONDA_PREFIX')
if conda_prefix:
search.append(conda_prefix + suffix)
# Priority 4: the default search prefixes # Priority 5: the default search prefixes
search += DEFAULT_PREFIXES search += [p + suffix for p in DEFAULT_PREFIXES]
# Make unique to avoid searching twice # Make unique to avoid searching twice
search = uniq_paths(search) search = uniq_paths(search)
...@@ -77,48 +80,71 @@ def find_file(name, subpaths=None, prefixes=None): ...@@ -77,48 +80,71 @@ def find_file(name, subpaths=None, prefixes=None):
subsearch.append(s) subsearch.append(s)
search = subsearch search = subsearch
# Before we do a filesystem check, filter out the unexisting paths # Before we do a file-system check, filter out the un-existing paths
tmp = [] tmp = []
for k in search: tmp += glob.glob(k) for k in search:
tmp += glob.glob(k)
search = tmp search = tmp
retval = [] return search
candidates = []
for path in search:
candidate = os.path.join(path, name)
candidates.append(candidate)
if os.path.exists(candidate): retval.append(candidate)
return retval
def find_header(name, subpaths=None, prefixes=None): def find_file(name, subpaths=None, prefixes=None):
"""Finds a header file on the file system. Returns all candidates. """Finds a generic file on the file system. Returns all occurrences.
This method will find all occurrences of a given name on the file system and This method will find all occurrences of a given name on the file system and
will return them to the user. will return them to the user. It uses :any:`construct_search_paths` to
construct the candidate folders that file may exist in.
Parameters
----------
name : str
The name of the file. For example, ``gcc``.
subpaths : [:obj:`str`], optional
See :any:`construct_search_paths`
subpaths : :obj:`str`, optional
See :any:`construct_search_paths`
Returns
-------
[str]
A list of filenames that exist on the filesystem, matching your
description.
"""
If the environment variable ``BOB_PREFIX_PATH`` is set, then it is search = construct_search_paths(prefixes=prefixes, subpaths=subpaths)
considered a unix path list that is prepended to the list of prefixes to
search for. The environment variable has the highest priority on the search
order. The order on the variable for each path is respected.
Parameters: retval = []
for path in search:
candidate = os.path.join(path, name)
if os.path.exists(candidate):
retval.append(candidate)
name, str return retval
The name of the file to be found, including extension
subpaths, str list
A list of subpaths to be appended to each prefix for the search. For
example, if you specificy ``['foo', 'bar']`` for this parameter, then
search on ``os.path.join(prefixes[0], 'foo')``, ``os.path.join(prefixes[0],
'bar')``, and so on.
prefixes, str list def find_header(name, subpaths=None, prefixes=None):
A list of prefixes that will be searched prioritarily to the """Finds a header file on the file system. Returns all candidates.
``DEFAULT_PREFIXES`` defined in this module.
Returns a list of filenames that exist on the filesystem, matching your This method will find all occurrences of a given name on the file system and
description. will return them to the user. It uses :any:`construct_search_paths` to
construct the candidate folders that header may exist in accounting
automatically for typical header folder names.
Parameters
----------
name : str
The name of the header file.
subpaths : [:obj:`str`], optional
See :any:`construct_search_paths`
subpaths : :obj:`str`, optional
See :any:`construct_search_paths`
Returns
-------
[str]
A list of filenames that exist on the filesystem, matching your
description.
""" """
headerpaths = [] headerpaths = []
...@@ -146,44 +172,37 @@ def find_header(name, subpaths=None, prefixes=None): ...@@ -146,44 +172,37 @@ def find_header(name, subpaths=None, prefixes=None):
return find_file(name, my_subpaths, prefixes) return find_file(name, my_subpaths, prefixes)
def find_library(name, version=None, subpaths=None, prefixes=None, def find_library(name, version=None, subpaths=None, prefixes=None,
only_static=False): only_static=False):
"""Finds a library file on the file system. Returns all candidates. """Finds a library file on the file system. Returns all candidates.
This method will find all occurrences of a given name on the file system and This method will find all occurrences of a given name on the file system and
will return them to the user. will return them to the user. It uses :any:`construct_search_paths` to
construct the candidate folders that the library may exist in accounting
If the environment variable ``BOB_PREFIX_PATH`` is set, then it is automatically for typical library folder names.
considered a unix path list that is prepended to the list of prefixes to
search for. The environment variable has the highest priority on the search Parameters
order. The order on the variable for each path is respected. ----------
name : str
Parameters: The name of the module to be found. If you'd like to find libz.so, for
example, specify ``"z"``. For libmath.so, specify ``"math"``.
name, str version : :obj:`str`, optional
The name of the module to be found. If you'd like to find libz.so, for The version of the library we are searching for. If not specified, then
example, specify ``"z"``. For libmath.so, specify ``"math"``. look only for the default names, such as ``libz.so`` and the such.
subpaths : [:obj:`str`], optional
version, str See :any:`construct_search_paths`
The version of the library we are searching for. If not specified, then subpaths : :obj:`str`, optional
look only for the default names, such as ``libz.so`` and the such. See :any:`construct_search_paths`
only_static : :obj:`bool`, optional
subpaths, str list A boolean, indicating if we should try only to search for static versions
A list of subpaths to be appended to each prefix for the search. For of the libraries. If not set, any would do.
example, if you specificy ``['foo', 'bar']`` for this parameter, then
search on ``os.path.join(prefixes[0], 'foo')``, ``os.path.join(prefixes[0], Returns
'bar')``, and so on. -------
[str]
prefixes, str list A list of filenames that exist on the filesystem, matching your
A list of prefixes that will be searched prioritarily to the description.
``DEFAULT_PREFIXES`` defined in this module.
static (bool)
A boolean, indicating if we should try only to search for static versions
of the libraries. If not set, any would do.
Returns a list of filenames that exist on the filesystem, matching your
description.
""" """
libpaths = [] libpaths = []
...@@ -246,30 +265,24 @@ def find_executable(name, subpaths=None, prefixes=None): ...@@ -246,30 +265,24 @@ def find_executable(name, subpaths=None, prefixes=None):
"""Finds an executable on the file system. Returns all candidates. """Finds an executable on the file system. Returns all candidates.
This method will find all occurrences of a given name on the file system and This method will find all occurrences of a given name on the file system and
will return them to the user. will return them to the user. It uses :any:`construct_search_paths` to
construct the candidate folders that the executable may exist in accounting
If the environment variable ``BOB_PREFIX_PATH`` is set, then it is automatically for typical executable folder names.
considered a unix path list that is prepended to the list of prefixes to
search for. The environment variable has the highest priority on the search Parameters
order. The order on the variable for each path is respected. ----------
name : str
Parameters: The name of the file. For example, ``gcc``.
subpaths : [:obj:`str`], optional
name, str See :any:`construct_search_paths`
The name of the executable to be found. subpaths : :obj:`str`, optional
See :any:`construct_search_paths`
subpaths, str list
A list of subpaths to be appended to each prefix for the search. For Returns
example, if you specificy ``['foo', 'bar']`` for this parameter, then -------
search on ``os.path.join(prefixes[0], 'foo')``, ``os.path.join(prefixes[0], [str]
'bar')``, and so on. A list of filenames that exist on the filesystem, matching your
description.
prefixes, str list
A list of prefixes that will be searched prioritarily to the
``DEFAULT_PREFIXES`` defined in this module.
Returns a list of filenames that exist on the filesystem, matching your
description.
""" """
binpaths = [] binpaths = []
......
...@@ -8,11 +8,74 @@ ...@@ -8,11 +8,74 @@
This section includes information for using the Python API of ``bob.extension``. This section includes information for using the Python API of ``bob.extension``.
Functions Summary
--------- -------
Core Functionality
^^^^^^^^^^^^^^^^^^
.. autosummary::
bob.extension.boost
bob.extension.build_ext
bob.extension.check_packages
bob.extension.CMakeListsGenerator
bob.extension.construct_search_paths
bob.extension.DEFAULT_PREFIXES
bob.extension.Extension
bob.extension.find_executable
bob.extension.find_library
bob.extension.generate_self_macros
bob.extension.get_bob_libraries
bob.extension.get_config
bob.extension.get_full_libname
bob.extension.Library
bob.extension.load_bob_library
bob.extension.normalize_requirements
bob.extension.pkgconfig
bob.extension.rc
bob.extension.reorganize_isystem
bob.extension.uniq
bob.extension.uniq_paths
Utilities
^^^^^^^^^
.. autosummary::
bob.extension.utils.egrep
bob.extension.utils.find_file
bob.extension.utils.find_header
bob.extension.utils.find_packages
bob.extension.utils.link_documentation
bob.extension.utils.load_requirements
Configuration
^^^^^^^^^^^^^
.. autosummary::
bob.extension.rc_config.ENVNAME
bob.extension.rc_config.RCFILENAME
bob.extension.config.load
Stacked Processors
^^^^^^^^^^^^^^^^^^
.. autosummary::
bob.extension.processors.SequentialProcessor
bob.extension.processors.ParallelProcessor
Core Functionality
------------------
.. automodule:: bob.extension .. automodule:: bob.extension
Utilities
---------
.. automodule:: bob.extension.utils
:exclude-members: find_executable,find_library,uniq,uniq_paths,construct_search_paths
Configuration Configuration
------------- -------------
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment