e5fe750915519d022ef23502121f0cdd6970db2a
[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[:-4]
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
44                 if repo.exists():
45                         if config.pull_config_dirs:
46                                 repo.pull()
47                 else:
48                         repo.clone()
49         else:
50                 if not isdir(path):
51                         raise Error('Config dir does not exist: %s' % path)
52
53         if path not in config.initial_config_dirs:
54                 config.config_dirs.append(path)
55
56 def pull_config_dirs(flag):
57         config.pull_config_dirs = flag
58
59 def root(url, branch='master'):
60         config.roots.append((url, branch))
61
62 class Board(object):
63         def __init__(self, name, arch, gcc_march,
64                      gcc_mcpu=None,
65                      gcc_mfpu=None,
66                      gcc_options=None,
67                      gnu_host=None,
68                      flash_erase_size=65536,
69                      flash_pad_size=0,
70                      flash_compression=None,
71                      ubifs_leb_size=0,
72                      ubifs_max_leb_count=0,
73                      ubifs_min_io_size=0,
74                      ubinize_config_vol_size=0):
75
76                 self.name = name
77                 self.arch = arch
78                 self.gcc_march = gcc_march
79                 self.gcc_mcpu = gcc_mcpu or ''
80                 self.gcc_mfpu = gcc_mfpu or ''
81                 self.gcc_options = _make_list(gcc_options)
82                 self.gnu_host = gnu_host or ''
83                 self.flash_erase_size = flash_erase_size
84                 self.flash_pad_size = flash_pad_size
85                 self.flash_compression = flash_compression or ''
86                 self.ubifs_leb_size = ubifs_leb_size
87                 self.ubifs_max_leb_count = ubifs_max_leb_count
88                 self.ubifs_min_io_size = ubifs_min_io_size
89                 self.ubinize_config_vol_size = ubinize_config_vol_size
90
91                 config.boards[name] = self
92
93 def component(*args, **kwargs):
94         import components
95
96         c = components.Component(*args, **kwargs)
97         config.components[c.name] = c
98         return c
99
100 def provide_component(name):
101         c = config.components.get(name)
102         if not c:
103                 c = component(name)
104         c.cached = True
105         return c
106
107 def parse(pattern, require=True):
108         if isabs(pattern):
109                 dirs = [None]
110         else:
111                 config_dirs = config.config_dirs + config.initial_config_dirs
112                 dirs = [join(config.top_dir, dir) for dir in config_dirs]
113                 dirs.append(config.top_dir)
114
115         found = False
116
117         for dir in dirs:
118                 for path in glob(join(dir, pattern)):
119                         if exclude.match(basename(path)):
120                                 continue
121
122                         found = True
123
124                         if config.debug:
125                                 print 'Parsing', path
126
127                         execfile(path, actions.copy(), {})
128
129         if not found:
130                 msg = 'Config file(s) not found: %s' % pattern
131                 if require:
132                         raise Error(msg)
133                 elif config.debug:
134                         print msg
135
136 def set_flag(name):
137         config.flags.add(name)
138
139 def clear_flag(name):
140         config.flags.discard(name)
141
142 def use_board(name):
143         config.board = name
144
145 def cache_dir(path):
146         config.cache_dir = path
147
148 def sb2_target(name):
149         config.sb2_target = name
150
151 def sb2_compiler(path):
152         config.sb2_compiler = path
153
154 def sb2_init_options(args):
155         config.sb2_init_options = list(args)
156
157 def get_variables():
158         return config
159
160 def rootfs_root(path, target = None):
161         rootfs.path = path
162         rootfs.target = target
163
164 def include_paths(paths):
165         rootfs.include_paths.extend(paths)
166
167 def include_files(files):
168         rootfs.include_files.extend(files)
169
170 def exclude_paths(paths):
171         rootfs.exclude_paths.extend(paths)
172
173 def exclude_files(files):
174         rootfs.exclude_files.extend(files)
175
176 def exclude_expressions(expressions):
177         rootfs.exclude_expressions.extend(expressions)
178
179 def created_paths(paths):
180         rootfs.created_paths.extend(paths)
181
182 def file_modes(modes):
183         rootfs.file_modes.update(modes)
184
185 def directory_owners(owners):
186         rootfs.directory_owners.update(owners)
187
188 def device_nodes(devices):
189         rootfs.devices.update(devices)
190
191 def remove_account(uid=None, gid=None):
192         rootfs.remove_uid = uid
193         rootfs.remove_gid = gid
194
195 class RootFS(object):
196         def __init__(self):
197                 self.path = None
198                 self.target = None
199                 self.include_paths = []
200                 self.include_files = []
201                 self.exclude_paths = []
202                 self.exclude_files = []
203                 self.exclude_expressions = []
204                 self.created_paths = []
205                 self.devices = {}
206                 self.file_modes = {}
207                 self.directory_owners = {}
208                 self.remove_uid = None
209                 self.remove_gid = None
210
211 class Config(object):
212         def __init__(self):
213                 self.initial_config_dirs = []
214                 self.config_dirs = []
215
216                 self.top_dir = getenv('MATRIX_TOPDIR', '')
217                 __cache_dir = join(self.top_dir, 'build-cache')
218                 self.cache_dir = getenv('MATRIX_CACHEDIR', __cache_dir)
219                 self.script_dir = None
220
221                 self.boards = {}
222                 self.board = None
223                 self.components = {}
224                 self.roots = []
225                 self.flags = set()
226                 self.verbose = False
227                 self.debug = False
228                 self.force = False
229                 self.keep_going = False
230                 self.pull_config_dirs = False
231                 self.jobs = 1
232                 self.make_jobs = 1
233
234                 self.sb2_target = None
235                 self.sb2_compiler = None
236                 self.sb2_init_options = []
237
238 actions = dict(
239         Board = Board,
240         CacheDir = cache_dir,
241         ClearFlag = clear_flag,
242         Component = component,
243         ConfigDir = config_dir,
244         GetVariables = get_variables,
245         Parse = parse,
246         ProvideComponent = provide_component,
247         PullConfigDirs = pull_config_dirs,
248         Root = root,
249         SB2Compiler = sb2_compiler,
250         SB2InitOptions = sb2_init_options,
251         SB2Target = sb2_target,
252         SetFlag = set_flag,
253         UseBoard = use_board,
254         RootFSRootPath = rootfs_root,
255         RootFSPaths = include_paths,
256         RootFSFiles = include_files,
257         RootFSExcludePaths = exclude_paths,
258         RootFSExcludeFiles = exclude_files,
259         RootFSExcludeExpressions = exclude_expressions,
260         RootFSCreatePaths = created_paths,
261         RootFSFileModes = file_modes,
262         RootFSDirectoryOwners = directory_owners,
263         RootFSDeviceNodes = device_nodes,
264         RootFSRemoveAccount = remove_account,
265 )
266
267 config = Config()
268 rootfs = RootFS()
269