envwrapper.py 4.25 KB
Newer Older
1
2
3
4
5
6
7
8
9
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Andre Anjos <andre.anjos@idiap.ch>
# Mon  4 Feb 09:24:35 2013 CET

"""A wrapper for defining environment variables for the compilation
"""

import os
André Anjos's avatar
André Anjos committed
10
import string
11
import logging
12
13
import platform

André Anjos's avatar
André Anjos committed
14
15
16
17
18
19

def substitute(value, d):
  """Substitutes ${} expressions on ``value`` with values from ``d``, using
  string.Template"""

  return string.Template(value).substitute(**d)
20
21
22
23
24
25

class EnvironmentWrapper(object):
  """Provides methods for wrapping other install() methods with environment
  settings from initialization.
  """

26
27
28
29
  # Note: CLang does not work well with BZ_DEBUG
  # 24.01.2017: we only support gcc on both Linux and MacOSX
  DEBUG_CFLAGS = '-O0 -g -DBOB_DEBUG -pthread -DBZ_DEBUG'
  RELEASE_CFLAGS = '-O3 -g0 -DNDEBUG -mtune=generic -pthread'
30

André Anjos's avatar
André Anjos committed
31
  def __init__(self, logger, debug=None, prefixes=None, environ=None):
32

André Anjos's avatar
André Anjos committed
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    self.debug = debug
    self.environ = dict(environ) if environ else {}

    # do environment variable substitution on user dictionary
    for key in self.environ:
      self.environ[key] = substitute(self.environ[key], self.environ)

    # if PKG_CONFIG_PATH is set on self.environ, then prefix it
    pkgcfg = []
    if 'PKG_CONFIG_PATH' in self.environ:
      pkgcfg += self.environ['PKG_CONFIG_PATH'].split(os.pathsep)

    # set the pkg-config paths to look at, environment settings in front
    prefixes = prefixes if prefixes else []
André Anjos's avatar
André Anjos committed
47
48
49
50
    if 'CMAKE_PREFIX_PATH' in self.environ:
      prefixes = self.environ['CMAKE_PREFIX_PATH'].split(os.pathsep) + prefixes
    if 'CMAKE_PREFIX_PATH' in os.environ:
      prefixes = os.environ['CMAKE_PREFIX_PATH'].split(os.pathsep) + prefixes
51
52
    if 'BOB_PREFIX_PATH' in self.environ:
      prefixes = self.environ['BOB_PREFIX_PATH'].split(os.pathsep) + prefixes
André Anjos's avatar
André Anjos committed
53
54
    if 'BOB_PREFIX_PATH' in os.environ:
      prefixes = os.environ['BOB_PREFIX_PATH'].split(os.pathsep) + prefixes
André Anjos's avatar
André Anjos committed
55
    pkgcfg += [os.path.join(k, 'lib', 'pkgconfig') for k in prefixes]
56
57
    pkgcfg += [os.path.join(k, 'lib64', 'pkgconfig') for k in prefixes]
    pkgcfg += [os.path.join(k, 'lib32', 'pkgconfig') for k in prefixes]
58

André Anjos's avatar
André Anjos committed
59
60
61
    def __remove_environ(key):
      if key in self.environ: del self.environ[key]

André Anjos's avatar
André Anjos committed
62
63
64
65
66
67
68
69
70
71
    def __append_to_environ(key, value, sep=' '):
      if self.environ.get(key):
        if value:
          self.environ[key] += sep + value.strip(sep)
      else:
        if value:
          self.environ[key] = value.strip(sep)

    # joins all paths, respecting potential environment variables set by the
    # user, with priority
André Anjos's avatar
André Anjos committed
72
    __remove_environ('BOB_PREFIX_PATH')
André Anjos's avatar
André Anjos committed
73
74
75
    __append_to_environ('BOB_PREFIX_PATH', os.pathsep.join(prefixes),
        os.pathsep)

André Anjos's avatar
André Anjos committed
76
    __remove_environ('CMAKE_PREFIX_PATH')
André Anjos's avatar
André Anjos committed
77
78
79
    __append_to_environ('CMAKE_PREFIX_PATH', os.pathsep.join(prefixes),
        os.pathsep)

André Anjos's avatar
André Anjos committed
80
    __remove_environ('PKG_CONFIG_PATH')
André Anjos's avatar
André Anjos committed
81
82
83
    __append_to_environ('PKG_CONFIG_PATH', os.environ.get('PKG_CONFIG_PATH'),
        os.pathsep)
    __append_to_environ('PKG_CONFIG_PATH', os.pathsep.join(pkgcfg), os.pathsep)
84

André Anjos's avatar
André Anjos committed
85
86
    # reset the CFLAGS and CXXFLAGS depending on the user input
    cflags = None
André Anjos's avatar
André Anjos committed
87
88
    if self.debug is True: cflags = str(EnvironmentWrapper.DEBUG_CFLAGS)
    elif self.debug is False: cflags = str(EnvironmentWrapper.RELEASE_CFLAGS)
André Anjos's avatar
André Anjos committed
89
    # else: pass
90

André Anjos's avatar
André Anjos committed
91
92
93
    def _order_flags(key, internal=None):
      if internal:
        # prepend internal
André Anjos's avatar
André Anjos committed
94
95
        saved = self.environ.get(key)
        __remove_environ(key)
André Anjos's avatar
André Anjos committed
96
        __append_to_environ(key, internal)
André Anjos's avatar
André Anjos committed
97
        __append_to_environ(key, saved)
André Anjos's avatar
André Anjos committed
98
99
100
101
102
      __append_to_environ(key, os.environ.get(key))

    # for these environment variables, values set on the environment come last
    # so they can override, values set on the buildout recipe or our internal
    # settings
André Anjos's avatar
André Anjos committed
103
104
105
    if cflags is not None:
      _order_flags('CFLAGS', cflags)
      _order_flags('CXXFLAGS', cflags)
106

André Anjos's avatar
André Anjos committed
107
108
109
  def set(self):
    """Sets the current environment for variables needed for the setup of the
    package to be compiled"""
110

André Anjos's avatar
André Anjos committed
111
112
    self._saved_environment = dict(os.environ) #copy
    os.environ.update(self.environ)
113

114
115
116
  def unset(self):
    """Resets the environment back to its previous state"""

André Anjos's avatar
André Anjos committed
117
118
119
120
    # cleanup
    if self._saved_environment:
      os.environ = self._saved_environment
      self._saved_environment = {}
121
122
123
124
125
126

  def __enter__(self):
    self.set()

  def __exit__(self, *exc_details):
    self.unset()