1 # jhbuild - a build script for GNOME 1.x and 2.x
2 # Copyright (C) 2001-2006 James Henstridge
3 # Copyright (C) 2007-2008 Frederic Peters
5 # config.py: configuration file parser
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 from jhbuild
.errors
import UsageError
, FatalError
, CommandError
28 from jhbuild
.utils
.cmds
import get_output
30 __all__
= [ 'Config' ]
32 _defaults_file
= os
.path
.join(os
.path
.dirname(__file__
), 'defaults.jhbuildrc')
33 _default_jhbuildrc
= os
.path
.join(os
.environ
['HOME'], '.jhbuildrc')
35 _known_keys
= [ 'moduleset', 'modules', 'skip', 'tags', 'prefix',
36 'checkoutroot', 'buildroot', 'autogenargs', 'makeargs',
37 'installprog', 'repos', 'branches', 'noxvfb', 'xvfbargs',
38 'builddir_pattern', 'module_autogenargs', 'module_makeargs',
39 'interact', 'buildscript', 'nonetwork',
40 'alwaysautogen', 'nobuild', 'makeclean', 'makecheck', 'module_makecheck',
41 'use_lib64', 'tinderbox_outputdir', 'sticky_date',
42 'tarballdir', 'pretty_print', 'svn_program', 'makedist',
43 'makedistcheck', 'nonotify', 'cvs_program',
44 'checkout_mode', 'copy_dir', 'module_checkout_mode',
45 'build_policy', 'trycheckout', 'min_time',
46 'nopoison', 'forcecheck', 'makecheck_advisory',
47 'quiet_mode', 'progress_bar', 'module_extra_env',
48 'jhbuildbot_master', 'jhbuildbot_slavename', 'jhbuildbot_password',
49 'jhbuildbot_svn_commits_box',
50 'use_local_modulesets', 'ignore_suggests', 'modulesets_dir',
51 'mirror_policy', 'module_mirror_policy', 'dvcs_mirror_dir',
55 def prependpath(envvar
, path
):
56 env_prepends
.setdefault(envvar
, []).append(path
)
58 def addpath(envvar
, path
):
59 '''Adds a path to an environment variable.'''
60 # special case ACLOCAL_FLAGS
61 if envvar
in [ 'ACLOCAL_FLAGS' ]:
62 envval
= os
.environ
.get(envvar
, '-I %s' % path
)
63 parts
= ['-I', path
] + envval
.split()
65 while i
< len(parts
)-1:
67 # check if "-I parts[i]" comes earlier
68 for j
in range(0, i
-1):
69 if parts
[j
] == '-I' and parts
[j
+1] == parts
[i
+1]:
76 envval
= ' '.join(parts
)
77 elif envvar
in [ 'LDFLAGS', 'CFLAGS', 'CXXFLAGS' ]:
78 envval
= os
.environ
.get(envvar
)
80 envval
= path
+ ' ' + envval
84 envval
= os
.environ
.get(envvar
, path
)
85 parts
= envval
.split(':')
87 # remove duplicate entries:
90 if parts
[i
] in parts
[:i
]:
92 elif envvar
== 'PYTHONPATH' and parts
[i
] == "":
96 envval
= ':'.join(parts
)
98 os
.environ
[envvar
] = envval
103 def __init__(self
, filename
=_default_jhbuildrc
):
105 '__file__': _defaults_file
,
107 'prependpath': prependpath
110 if not self
._orig
_environ
:
111 self
.__dict
__['_orig_environ'] = os
.environ
.copy()
116 raise FatalError(_('Obsolete jhbuild start script, do run \'make install\''))
120 execfile(_defaults_file
, self
._config
)
122 traceback
.print_exc()
123 raise FatalError(_('could not load config defaults'))
124 self
._config
['__file__'] = filename
125 self
.filename
= filename
126 if not os
.path
.exists(filename
):
127 raise FatalError(_('could not load config file, %s is missing') % filename
)
133 os
.environ
= self
._orig
_environ
.copy()
134 self
.__init
__(filename
=self
._config
.get('__file__'))
137 config
= self
._config
139 execfile(self
.filename
, config
)
141 traceback
.print_exc()
142 raise FatalError(_('could not load config file'))
144 if not config
.get('quiet_mode'):
146 for k
in config
.keys():
147 if k
in _known_keys
+ ['cvsroots', 'svnroots', 'cflags']:
151 if type(config
[k
]) in (types
.ModuleType
, types
.FunctionType
):
153 unknown_keys
.append(k
)
156 _('unknown keys defined in configuration file: %s') % \
157 ', '.join(unknown_keys
))
159 # backward compatibility, from the days when jhbuild only
160 # supported Gnome.org CVS.
161 if config
.get('cvsroot'):
163 _('the "%s" configuration variable is deprecated, '
164 'you should use "repos[\'gnome.org\']".') % 'cvsroot')
165 config
['repos'].update({'gnome.org': config
['cvsroot']})
166 if config
.get('cvsroots'):
168 _('the "%s" configuration variable is deprecated, '
169 'you should use "repos".') % 'cvsroots')
170 config
['repos'].update(config
['cvsroots'])
171 if config
.get('svnroots'):
173 _('the "%s" configuration variable is deprecated, '
174 'you should use "repos".') % 'svnroots')
175 config
['repos'].update(config
['svnroots'])
177 # environment variables
178 if config
.has_key('cflags') and config
['cflags']:
179 os
.environ
['CFLAGS'] = config
['cflags']
180 if config
.get('installprog') and os
.path
.exists(config
['installprog']):
181 os
.environ
['INSTALL'] = config
['installprog']
183 # copy known config keys to attributes on the instance
184 for name
in _known_keys
:
185 setattr(self
, name
, config
[name
])
187 # default tarballdir to checkoutroot
188 if not self
.tarballdir
: self
.tarballdir
= self
.checkoutroot
190 # check possible checkout_mode values
191 seen_copy_mode
= (self
.checkout_mode
== 'copy')
192 possible_checkout_modes
= ('update', 'clobber', 'export', 'copy')
193 if self
.checkout_mode
not in possible_checkout_modes
:
194 raise FatalError(_('invalid checkout mode'))
195 for module
, checkout_mode
in self
.module_checkout_mode
.items():
196 seen_copy_mode
= seen_copy_mode
or (checkout_mode
== 'copy')
197 if checkout_mode
not in possible_checkout_modes
:
198 raise FatalError(_('invalid checkout mode (module: %s)') % module
)
199 if seen_copy_mode
and not self
.copy_dir
:
200 raise FatalError(_('copy mode requires copy_dir to be set'))
202 if not os
.path
.exists(self
.modulesets_dir
):
203 if self
.use_local_modulesets
:
205 _('modulesets directory (%s) not found, '
206 'disabling use_local_modulesets') % self
.modulesets_dir
)
207 self
.use_local_modulesets
= False
208 self
.modulesets_dir
= None
211 '''set environment variables for using prefix'''
213 if not os
.path
.exists(self
.prefix
):
215 os
.makedirs(self
.prefix
)
217 raise FatalError(_('install prefix (%s) can not be created') % self
.prefix
)
219 os
.environ
['UNMANGLED_LD_LIBRARY_PATH'] = os
.environ
.get('LD_LIBRARY_PATH', '')
223 libdir
= os
.path
.join(self
.prefix
, 'lib64')
225 libdir
= os
.path
.join(self
.prefix
, 'lib')
226 addpath('LD_LIBRARY_PATH', libdir
)
228 # LDFLAGS and C_INCLUDE_PATH are required for autoconf configure
229 # scripts to find modules that do not use pkg-config (such as guile
230 # looking for gmp, or wireless-tools for NetworkManager)
231 # (see bug #377724 and bug #545018)
232 os
.environ
['LDFLAGS'] = ('-L%s ' % libdir
) + os
.environ
.get('LDFLAGS', '')
233 includedir
= os
.path
.join(self
.prefix
, 'include')
234 addpath('C_INCLUDE_PATH', includedir
)
235 addpath('CPLUS_INCLUDE_PATH', includedir
)
237 # On Mac OS X, we use DYLD_FALLBACK_LIBRARY_PATH
238 addpath('DYLD_FALLBACK_LIBRARY_PATH', libdir
)
241 bindir
= os
.path
.join(self
.prefix
, 'bin')
242 addpath('PATH', bindir
)
245 manpathdir
= os
.path
.join(self
.prefix
, 'share', 'man')
246 addpath('MANPATH', manpathdir
)
249 if os
.environ
.get('PKG_CONFIG_PATH') is None:
250 # add system pkgconfig lookup-directories by default, as pkg-config
251 # usage spread and is now used by libraries that are out of jhbuild
252 # realm; this also helps when building a single module with
253 # jhbuild. It is possible to avoid this by setting PKG_CONFIG_PATH
254 # to the empty string.
255 for dirname
in ('share', 'lib', 'lib64'):
256 full_name
= '/usr/%s/pkgconfig' % dirname
257 if os
.path
.exists(full_name
):
258 addpath('PKG_CONFIG_PATH', full_name
)
259 pkgconfigdatadir
= os
.path
.join(self
.prefix
, 'share', 'pkgconfig')
260 pkgconfigdir
= os
.path
.join(libdir
, 'pkgconfig')
261 addpath('PKG_CONFIG_PATH', pkgconfigdatadir
)
262 addpath('PKG_CONFIG_PATH', pkgconfigdir
)
265 xdgdatadir
= os
.path
.join(self
.prefix
, 'share')
266 addpath('XDG_DATA_DIRS', xdgdatadir
)
269 xdgconfigdir
= os
.path
.join(self
.prefix
, 'etc', 'xdg')
270 addpath('XDG_CONFIG_DIRS', xdgconfigdir
)
273 aclocaldir
= os
.path
.join(self
.prefix
, 'share', 'aclocal')
274 if not os
.path
.exists(aclocaldir
):
276 os
.makedirs(aclocaldir
)
278 raise FatalError(_("Can't create %s directory") % aclocaldir
)
279 addpath('ACLOCAL_FLAGS', aclocaldir
)
282 perl5lib
= os
.path
.join(self
.prefix
, 'lib', 'perl5')
283 addpath('PERL5LIB', perl5lib
)
285 os
.environ
['CERTIFIED_GNOMIE'] = 'yes'
288 # Python inside jhbuild may be different than Python executing jhbuild,
289 # so it is executed to get its version number (fallback to local
290 # version number should never happen)
291 python_bin
= os
.environ
.get('PYTHON', 'python')
293 pythonversion
= 'python' + get_output([python_bin
, '-c',
294 'import sys; print ".".join([str(x) for x in sys.version_info[:2]])'],
295 get_stderr
= False).strip()
297 pythonversion
= 'python' + str(sys
.version_info
[0]) + '.' + str(sys
.version_info
[1])
299 # In Python 2.6, site-packages got replaced by dist-packages, get the
300 # actual value by asking distutils
301 # <http://bugzilla.gnome.org/show_bug.cgi?id=575426>
303 python_packages_dir
= get_output([python_bin
, 'c',
304 'import os, distutils.sysconfig; '\
305 'print distutils.sysconfig.get_python_lib(prefix="").split(os.path.sep)[-1]'],
306 get_stderr
=False).strip()
308 python_packages_dir
= 'site-packages'
311 pythonpath
= os
.path
.join(self
.prefix
, 'lib64', pythonversion
, python_packages_dir
)
312 addpath('PYTHONPATH', pythonpath
)
313 if not os
.path
.exists(pythonpath
):
314 os
.makedirs(pythonpath
)
316 pythonpath
= os
.path
.join(self
.prefix
, 'lib', pythonversion
, python_packages_dir
)
317 addpath('PYTHONPATH', pythonpath
)
318 if not os
.path
.exists(pythonpath
):
319 os
.makedirs(pythonpath
)
321 # if there is a Python installed in JHBuild prefix, set it in PYTHON
322 # environment variable, so it gets picked up by configure scripts
323 # <http://bugzilla.gnome.org/show_bug.cgi?id=560872>
324 if os
.path
.exists(os
.path
.join(self
.prefix
, 'bin', 'python')):
325 os
.environ
['PYTHON'] = os
.path
.join(self
.prefix
, 'bin', 'python')
328 os
.environ
['MONO_PREFIX'] = self
.prefix
329 os
.environ
['MONO_GAC_PREFIX'] = self
.prefix
331 # handle environment prepends ...
332 for envvar
in env_prepends
.keys():
333 for path
in env_prepends
[envvar
]:
334 addpath(envvar
, path
)
337 # get rid of gdkxft from the env -- it will cause problems.
338 if os
.environ
.has_key('LD_PRELOAD'):
339 valarr
= os
.environ
['LD_PRELOAD'].split(' ')
341 if x
.find('libgdkxft.so') >= 0:
343 os
.environ
['LD_PRELOAD'] = ' '.join(valarr
)
345 def __setattr__(self
, k
, v
):
346 '''Override __setattr__ for additional checks on some options.'''
347 if k
== 'quiet_mode' and v
:
352 _('quiet mode has been disabled because the Python curses module is missing.'))