3d54168ef0be79666157211ecfcf6e515b9d00b1
[matrix.git] / matrix / config.py
1 # Copyright (C) 2007-2009 Movial Creative Technologies Inc.
2 # Authors: Timo Savola
3 #          Kalle Vahlman <kalle.vahlman@movial.com>
4 #          Daniel Bainton <daniel.bainton@movial.com>
5
6 import re
7 from glob import glob
8 from os import getenv
9 from os.path import basename, exists, isabs, isdir, join
10 from sets import Set as set
11
12 Error = RuntimeError
13
14 exclude = re.compile(r'^[.#].*|.*[~#]$')
15
16 def _make_list(arg):
17         if arg is None:
18                 return []
19
20         if isinstance(arg, basestring):
21                 return arg.split()
22
23         return list(arg)
24
25 def config_dir(path=None, url=None, branch='master', optional=False):
26         from repositories import Repository
27
28         if not path:
29                 if not url:
30                         raise Error('No path or URL specified')
31
32                 path = basename(url)
33                 if path.endswith('.git'):
34                         path = path[:-4]
35
36         if optional and path not in config.initial_config_dirs:
37                 if config.debug:
38                         print 'Skipping', path
39                 return
40
41         if url:
42                 name = basename(path)
43                 repo = Repository(name=name, path=path, url=url, branch=branch)
44
45                 if repo.exists():
46                         if config.pull_config_dirs:
47                                 repo.pull()
48                 else:
49                         repo.clone()
50         else:
51                 if not isdir(path):
52                         raise Error('Config dir does not exist: %s' % path)
53
54         if path not in config.initial_config_dirs:
55                 config.config_dirs.append(path)
56
57 def pull_config_dirs(flag):
58         config.pull_config_dirs = flag
59
60 def root(url, branch='master'):
61         config.roots.append((url, branch))
62
63 class Board(object):
64         def __init__(self, name, arch, gcc_march,
65                      gcc_mcpu=None,
66                      gcc_mfpu=None,
67                      gcc_options=None,
68                      gnu_host=None,
69                      flash_erase_size=65536,
70                      flash_pad_size=0,
71                      flash_compression=None,
72                      ubifs_leb_size=0,
73                      ubifs_max_leb_count=0,
74                      ubifs_min_io_size=0,
75                      ubinize_config_vol_size=0,
76                      cleanmarkers="unknown",
77                      flags=[]):
78
79                 self.name = name
80                 self.arch = arch
81                 self.gcc_march = gcc_march
82                 self.gcc_mcpu = gcc_mcpu or ''
83                 self.gcc_mfpu = gcc_mfpu or ''
84                 self.gcc_options = _make_list(gcc_options)
85                 self.gnu_host = gnu_host or ''
86                 self.flash_erase_size = flash_erase_size
87                 self.flash_pad_size = flash_pad_size
88                 self.flash_compression = flash_compression or ''
89                 self.ubifs_leb_size = ubifs_leb_size
90                 self.ubifs_max_leb_count = ubifs_max_leb_count
91                 self.ubifs_min_io_size = ubifs_min_io_size
92                 self.ubinize_config_vol_size = ubinize_config_vol_size
93                 self.cleanmarkers = cleanmarkers
94                 self.flags = flags
95
96                 config.boards[name] = self
97
98 def component(*args, **kwargs):
99         import components
100
101         c = components.Component(*args, **kwargs)
102         config.components[c.name] = c
103         return c
104
105 def provide_component(name):
106         c = config.components.get(name)
107         if not c:
108                 c = component(name)
109         c.cached = True
110         return c
111
112 def parse(pattern, require=True):
113         if isabs(pattern):
114                 dirs = [None]
115         else:
116                 config_dirs = config.config_dirs + config.initial_config_dirs
117                 dirs = [join(config.top_dir, dir) for dir in config_dirs]
118                 dirs.append(config.top_dir)
119
120         found = False
121
122         for dir in dirs:
123                 for path in glob(join(dir, pattern)):
124                         if exclude.match(basename(path)):
125                                 continue
126
127                         found = True
128
129                         if config.debug:
130                                 print 'Parsing', path
131
132                         execfile(path, actions.copy(), {})
133
134         if not found:
135                 msg = 'Config file(s) not found: %s' % pattern
136                 if require:
137                         raise Error(msg)
138                 elif config.debug:
139                         print msg
140
141 def set_flag(name):
142         config.flags.add(name)
143
144 def clear_flag(name):
145         config.flags.discard(name)
146
147 def use_board(name):
148         config.board = name
149
150 def cache_dir(path):
151         config.cache_dir = path
152
153 def sb2_target(name):
154         config.sb2_target = name
155
156 def sb2_compiler(path):
157         config.sb2_compiler = path
158
159 def sb2_init_options(args):
160         config.sb2_init_options = list(args)
161
162 def get_variables():
163         return config
164
165 def rootfs_root(path, target = None):
166         rootfs.path = path
167         rootfs.target = target
168
169 def include_paths(paths):
170         rootfs.include_paths.extend(paths)
171
172 def include_files(files):
173         rootfs.include_files.extend(files)
174
175 def exclude_paths(paths):
176         rootfs.exclude_paths.extend(paths)
177
178 def exclude_files(files):
179         rootfs.exclude_files.extend(files)
180
181 def exclude_expressions(expressions):
182         rootfs.exclude_expressions.extend(expressions)
183
184 def created_paths(paths):
185         rootfs.created_paths.extend(paths)
186
187 def file_modes(modes):
188         rootfs.file_modes.update(modes)
189
190 def directory_owners(owners):
191         rootfs.directory_owners.update(owners)
192
193 def device_nodes(devices):
194         rootfs.devices.update(devices)
195
196 def remove_account(uid=None, gid=None):
197         rootfs.remove_uid = uid
198         rootfs.remove_gid = gid
199
200 class RootFS(object):
201         def __init__(self):
202                 self.path = None
203                 self.target = None
204                 self.include_paths = []
205                 self.include_files = []
206                 self.exclude_paths = []
207                 self.exclude_files = []
208                 self.exclude_expressions = []
209                 self.created_paths = []
210                 self.devices = {}
211                 self.file_modes = {}
212                 self.directory_owners = {}
213                 self.remove_uid = None
214                 self.remove_gid = None
215
216 class Config(object):
217         def __init__(self):
218                 self.initial_config_dirs = []
219                 self.config_dirs = []
220
221                 self.top_dir = getenv('MATRIX_TOPDIR', '')
222                 __cache_dir = join(self.top_dir, 'build-cache')
223                 self.cache_dir = getenv('MATRIX_CACHEDIR', __cache_dir)
224                 self.script_dir = None
225
226                 self.boards = {}
227                 self.board = None
228                 self.components = {}
229                 self.roots = []
230                 self.flags = set()
231                 self.verbose = False
232                 self.debug = False
233                 self.protocol = False
234                 self.force = False
235                 self.keep_going = False
236                 self.pull_config_dirs = False
237                 self.jobs = 1
238                 self.make_jobs = 1
239
240                 self.sb2_target = None
241                 self.sb2_compiler = None
242                 self.sb2_init_options = []
243
244 actions = dict(
245         Board = Board,
246         CacheDir = cache_dir,
247         ClearFlag = clear_flag,
248         Component = component,
249         ConfigDir = config_dir,
250         GetVariables = get_variables,
251         Parse = parse,
252         ProvideComponent = provide_component,
253         PullConfigDirs = pull_config_dirs,
254         Root = root,
255         SB2Compiler = sb2_compiler,
256         SB2InitOptions = sb2_init_options,
257         SB2Target = sb2_target,
258         SetFlag = set_flag,
259         UseBoard = use_board,
260         RootFSRootPath = rootfs_root,
261         RootFSPaths = include_paths,
262         RootFSFiles = include_files,
263         RootFSExcludePaths = exclude_paths,
264         RootFSExcludeFiles = exclude_files,
265         RootFSExcludeExpressions = exclude_expressions,
266         RootFSCreatePaths = created_paths,
267         RootFSFileModes = file_modes,
268         RootFSDirectoryOwners = directory_owners,
269         RootFSDeviceNodes = device_nodes,
270         RootFSRemoveAccount = remove_account,
271 )
272
273 config = Config()
274 rootfs = RootFS()
275