-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathebuild_function.py
executable file
·247 lines (208 loc) · 8.33 KB
/
ebuild_function.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Ebuild function generator to migrate src_install into GN.
Default values follow the default values of ebuild (see manpage of ebuild).
https://dev.gentoo.org/~zmedico/portage/doc/man/ebuild.5.html
"""
from __future__ import print_function
import os
VALID_INSTALL_TYPES = ('bin', 'ins', 'lib.a', 'lib.so', 'sbin')
class EbuildFunctionError(Exception):
"""The base exception for ebuild_function."""
class InvalidInstallTypeError(EbuildFunctionError):
"""Invalid type exception that is raised when install type is invalid."""
def __init__(self):
message = f'install_type must be {", ".join(VALID_INSTALL_TYPES)}'
super().__init__(message)
def generate(sources, install_path=None, outputs=None, symlinks=None,
recursive=False, options=None, command_type=None):
"""Generates commandlines for installing files using a ebuild function.
Args:
sources: A list of source files to be installed.
install_path: A string of path to install into. When both install_path and
symlinks are specified, it joins a install_path to symlinks.
When command_type is "executable", "shared_library" or
"static_library", install_path must end with "bin", "sbin" or "lib".
outputs: A list of new file names to be installed as. If not specified,
original file names are used.
symlinks: A list of new symbolic links to be created. If specified,
installation command becomes "dosym" and args except for sources are
ignored.
recursive: A boolean if you install them recursively. This is only
available when command_type and symlinks are not specified.
options: A string to be passed to xxopts. This is only available when
command_type and symlinks are not specified.
command_type: A string of where is the config defined.
"executable", "shared_library", "static_library" and None are only
allowed to be specified.
The generated command depends on command_type.
executable: dobin, dosbin, newbin, newsbin
shared_library: dolib.so, newlib.so
static_library: dolib.a, newlib.a
None: doins, newins, dosym
Returns:
A list of commandlines correspond to given args.
It can generate "doins", "dobin", "dosbin", "dolib.a", "dolib.so" and
"dosym". When "outputs" is specified, it generates new-command of those
except for "dosym".
doins:
[
['insinto', 'path/to/install'],
['insopts', '-m0644'],
['doins', 'sources[0]', 'sources[1]', ...],
]
dobin):
[
['into', 'path/to/install'],
['dobin', 'sources[0]', 'sources[1]', ...],
]
dosym:
[
['dosym', 'sources[0]', 'path/to/symlink[0]'],
['dosym', 'sources[1]', 'path/to/symlink[1]'],
...
]
dolib.a and dolib.so is the same as dobin.
When "outputs" are specified, installation commands change to multiple
commands of "newxxx" like dosym.
"""
if not command_type:
if not symlinks:
install_type = 'ins'
else:
install_type = 'sym'
if install_path:
outputs = [os.path.join(install_path, symlink) for symlink in symlinks]
else:
outputs = symlinks
elif command_type == 'executable':
install_path, install_type = os.path.split(install_path)
assert install_type in ('bin', 'sbin'), ('install_path must end in bin'
' or sbin in an executable target')
elif command_type == 'shared_library':
install_path, lib = os.path.split(install_path)
assert lib == 'lib', ('install_path must end in lib in a shared_library'
' target')
install_type = 'lib.so'
elif command_type == 'static_library':
install_path, lib = os.path.split(install_path)
assert lib == 'lib', ('install_path must end in lib in a static_library'
' target')
install_type = 'lib.a'
else:
raise AssertionError('unknown type. type must be executable,'
' shared_library or static_library')
cmd_list = option_cmd(install_type, install_path, options)
cmd_list += install(install_type, sources, outputs, recursive)
return cmd_list
def sym_install(sources, symlinks):
"""Generates "dosym" commandlines.
Args:
sources: A list of source files of symbolic links.
symlinks: A list of symbolic links to be created.
Returns:
A list of commandlines of "dosym".
[
['dosym', 'sources[0]', 'symlinks[0]'],
['dosym', 'sources[1]', 'symlinks[1]'],
...
]
"""
assert len(sources) == len(symlinks), ('the number of symlinks must be the'
' same as sources')
return [['dosym', source, symlink]
for source, symlink in zip(sources, symlinks)]
def option_cmd(install_type, install_path='', options=None):
"""Generates commandlines of options appropriate for the |install_type|.
Args:
install_type: A string of a suffix of an installation command.
install_path: A string of path to be installed into. This is passed to
"xxxinto" commands.
options: A string of options of installation. This is available only when
install_type == "ins". This is passed to "xxxopts".
Returns:
A list of commandlines for specifying options.
doins options (install_type == "ins"):
[
['insinto', 'path/to/install'],
['insopts', '-m0644'],
]
dobin, dosbin, dolib.so, dolib.a options:
[
['into', 'path/to/install']
]
"""
if install_type == 'ins':
return [
['insinto', install_path or '/'],
['insopts', options or '-m0644'],
]
if install_type in VALID_INSTALL_TYPES:
return [['into', install_path or '/usr']]
return []
def install(install_type, sources, outputs=None, recursive=False):
"""Generates commandlines for installation.
When |outputs| is specified, it generates new command.
Args:
install_type: A string of a suffix of an installation command.
sources: A list of source files to be installed.
outputs: A list of new file names to be installed as. If not specified,
original file names are used.
recursive: A boolean if you install them recursively. This is available
only when install_type == "ins" and outputs are not specified.
Returns:
A list of commandlines for installation.
"""
if install_type == 'sym':
return sym_install(sources, outputs)
if not outputs:
return do_command(install_type, sources, recursive)
return new_command(install_type, sources, outputs)
def do_command(install_type, sources, recursive=False):
"""Generates commandlines of do-command.
Args:
install_type: A string of a suffix of an installation command.
"ins", "bin", "sbin", "lib.so" and "lib.a" are allowed.
sources: A list of source files to be installed.
recursive: A boolean if you install them recursively. This is available
only when install_type == "ins".
Returns:
A list of commandlines for installation.
[
['dobin', 'sources[0]', 'sources[1]', ...]
]
Especially, when install_type == "ins" and recursive == true:
[
['doins', '-r', 'sources[0]', 'sources[1]', ...]
]
"""
if install_type not in VALID_INSTALL_TYPES:
raise InvalidInstallTypeError()
recursive_opts = []
if install_type == 'ins' and recursive:
recursive_opts = ['-r']
return [['do%s' % install_type] + recursive_opts + sources]
def new_command(install_type, sources, outputs):
"""Generates commandlines of new-command.
Args:
install_type: A string of a suffix of an installation command.
"ins", "bin", "sbin", "lib.so" and "lib.a" are allowed.
sources: A list of source files to be installed.
outputs: A list of new file names to be installed as.
Returns:
A list of commandlines for installation.
[
['newins', 'sources[0]', 'outputs[0]'],
['newins', 'sources[1]', 'outputs[1]'],
...
]
"""
if install_type not in VALID_INSTALL_TYPES:
raise InvalidInstallTypeError()
assert len(sources) == len(outputs), ('the number of outputs must be the same'
' as sources')
return [['new%s' % install_type, source, output]
for source, output in zip(sources, outputs)]