config: optional config dir support
[matrix.git] / matrix / config.py
1 # Copyright (C) 2007-2008 Movial Oy
2 # Authors: Timo Savola <tsavola@movial.fi>
3 #          Kalle Vahlman <kalle.vahlman@movial.fi>
4
5 import sre
6 from glob import glob
7 from os import getenv
8 from os.path import basename, exists, isabs, isdir, join
9 from sets import Set as set
10
11 Error = RuntimeError
12
13 exclude = sre.compile(r'^[.#].*|.*[~#]$')
14
15 def _make_list(arg):
16         if arg is None:
17                 return []
18
19         if isinstance(arg, basestring):
20                 return arg.split()
21
22         return list(arg)
23
24 def config_dir(path=None, url=None, branch='master', optional=False):
25         from repositories import Repository
26
27         if not path:
28                 if not url:
29                         raise Error('No path or URL specified')
30
31                 path = basename(url)
32                 if path.endswith('.git'):
33                         path = path.rsplit('.', 1)[0]
34
35         if optional and path not in config.initial_config_dirs:
36                 if config.debug:
37                         print 'Skipping', path
38                 return
39
40         if url:
41                 name = basename(path)
42                 repo = Repository(name=name, path=path, url=url, branch=branch)
43                 if not repo.exists():
44                         repo.clone()
45         else:
46                 if not isdir(path):
47                         raise Error('Config dir does not exist: %s' % path)
48
49         config.config_dirs.append(path)
50
51 def root(url, branch='master'):
52         config.roots.append((url, branch))
53
54 class Board(object):
55         def __init__(self, name, arch, gcc_march,
56                      gcc_mcpu=None,
57                      gcc_mfpu=None,
58                      gcc_options=None,
59                      gnu_host=None,
60                      flash_erase_size=65536,
61                      flash_pad_size=0,
62                      flash_compression=None,
63                      ubifs_leb_size=0,
64                      ubifs_max_leb_count=0,
65                      ubifs_min_io_size=0,
66                      ubinize_config_vol_size=0):
67
68                 self.name = name
69                 self.arch = arch
70                 self.gcc_march = gcc_march
71                 self.gcc_mcpu = gcc_mcpu or ''
72                 self.gcc_mfpu = gcc_mfpu or ''
73                 self.gcc_options = _make_list(gcc_options)
74                 self.gnu_host = gnu_host or ''
75                 self.flash_erase_size = flash_erase_size
76                 self.flash_pad_size = flash_pad_size
77                 self.flash_compression = flash_compression or ''
78                 self.ubifs_leb_size = ubifs_leb_size
79                 self.ubifs_max_leb_count = ubifs_max_leb_count
80                 self.ubifs_min_io_size = ubifs_min_io_size
81                 self.ubinize_config_vol_size = ubinize_config_vol_size
82
83                 config.boards[name] = self
84
85 def component(*args, **kwargs):
86         import components
87
88         c = components.Component(*args, **kwargs)
89         config.components[c.name] = c
90         return c
91
92 def provide_component(name):
93         c = config.components.get(name)
94         if not c:
95                 c = component(name)
96         c.cached = True
97         return c
98
99 def parse(pattern, require=True):
100         if isabs(pattern):
101                 dirs = [None]
102         else:
103                 config_dirs = config.config_dirs + config.initial_config_dirs
104                 dirs = [join(config.top_dir, dir) for dir in config_dirs]
105                 dirs.append(config.top_dir)
106
107         found = False
108
109         for dir in dirs:
110                 for path in glob(join(dir, pattern)):
111                         if exclude.match(basename(path)):
112                                 continue
113
114                         found = True
115
116                         if config.debug:
117                                 print 'Parsing', path
118
119                         execfile(path, actions.copy(), {})
120
121         if not found:
122                 msg = 'Config file(s) not found: %s' % pattern
123                 if require:
124                         raise Error(msg)
125                 elif config.debug:
126                         print msg
127
128 def set_flag(name):
129         config.flags.add(name)
130
131 def clear_flag(name):
132         config.flags.discard(name)
133
134 def use_board(name):
135         config.board = name
136
137 def sb2_target(name):
138         config.sb2_target = name
139
140 def sb2_compiler(path):
141         config.sb2_compiler = path
142
143 def sb2_init_options(args):
144         config.sb2_init_options = list(args)
145
146 def get_variables():
147         return config
148
149 class Config(object):
150         def __init__(self):
151                 self.initial_config_dirs = []
152                 self.config_dirs = []
153
154                 self.top_dir = getenv('MATRIX_TOPDIR', '')
155                 __cache_dir = join(self.top_dir, 'build-cache')
156                 self.cache_dir = getenv('MATRIX_CACHEDIR', __cache_dir)
157                 self.script_dir = None
158
159                 self.boards = {}
160                 self.board = None
161                 self.components = {}
162                 self.roots = []
163                 self.flags = set()
164                 self.verbose = False
165                 self.debug = False
166                 self.force = False
167                 self.keep_going = False
168                 self.jobs = 1
169                 self.make_jobs = 1
170
171                 self.sb2_target = None
172                 self.sb2_compiler = None
173                 self.sb2_init_options = []
174
175 actions = dict(
176         Board = Board,
177         ClearFlag = clear_flag,
178         Component = component,
179         ConfigDir = config_dir,
180         GetVariables = get_variables,
181         Parse = parse,
182         ProvideComponent = provide_component,
183         Root = root,
184         SB2Compiler = sb2_compiler,
185         SB2InitOptions = sb2_init_options,
186         SB2Target = sb2_target,
187         SetFlag = set_flag,
188         UseBoard = use_board,
189 )
190
191 config = Config()