diff options
Diffstat (limited to 'meta/classes/externalsrc.bbclass')
-rw-r--r-- | meta/classes/externalsrc.bbclass | 91 |
1 files changed, 54 insertions, 37 deletions
diff --git a/meta/classes/externalsrc.bbclass b/meta/classes/externalsrc.bbclass index c7b2bf2f49..70e27a8d35 100644 --- a/meta/classes/externalsrc.bbclass +++ b/meta/classes/externalsrc.bbclass | |||
@@ -2,7 +2,8 @@ | |||
2 | # Author: Richard Purdie | 2 | # Author: Richard Purdie |
3 | # Some code and influence taken from srctree.bbclass: | 3 | # Some code and influence taken from srctree.bbclass: |
4 | # Copyright (C) 2009 Chris Larson <clarson@kergoth.com> | 4 | # Copyright (C) 2009 Chris Larson <clarson@kergoth.com> |
5 | # Released under the MIT license (see COPYING.MIT for the terms) | 5 | # |
6 | # SPDX-License-Identifier: MIT | ||
6 | # | 7 | # |
7 | # externalsrc.bbclass enables use of an existing source tree, usually external to | 8 | # externalsrc.bbclass enables use of an existing source tree, usually external to |
8 | # the build system to build a piece of software rather than the usual fetch/unpack/patch | 9 | # the build system to build a piece of software rather than the usual fetch/unpack/patch |
@@ -13,7 +14,7 @@ | |||
13 | # called "myrecipe" you would do: | 14 | # called "myrecipe" you would do: |
14 | # | 15 | # |
15 | # INHERIT += "externalsrc" | 16 | # INHERIT += "externalsrc" |
16 | # EXTERNALSRC_pn-myrecipe = "/path/to/my/source/tree" | 17 | # EXTERNALSRC:pn-myrecipe = "/path/to/my/source/tree" |
17 | # | 18 | # |
18 | # In order to make this class work for both target and native versions (or with | 19 | # In order to make this class work for both target and native versions (or with |
19 | # multilibs/cross or other BBCLASSEXTEND variants), B is set to point to a separate | 20 | # multilibs/cross or other BBCLASSEXTEND variants), B is set to point to a separate |
@@ -21,7 +22,7 @@ | |||
21 | # the default, but the build directory can be set to the source directory if | 22 | # the default, but the build directory can be set to the source directory if |
22 | # circumstances dictate by setting EXTERNALSRC_BUILD to the same value, e.g.: | 23 | # circumstances dictate by setting EXTERNALSRC_BUILD to the same value, e.g.: |
23 | # | 24 | # |
24 | # EXTERNALSRC_BUILD_pn-myrecipe = "/path/to/my/source/tree" | 25 | # EXTERNALSRC_BUILD:pn-myrecipe = "/path/to/my/source/tree" |
25 | # | 26 | # |
26 | 27 | ||
27 | SRCTREECOVEREDTASKS ?= "do_patch do_unpack do_fetch" | 28 | SRCTREECOVEREDTASKS ?= "do_patch do_unpack do_fetch" |
@@ -45,11 +46,11 @@ python () { | |||
45 | if bpn == d.getVar('PN') or not classextend: | 46 | if bpn == d.getVar('PN') or not classextend: |
46 | if (externalsrc or | 47 | if (externalsrc or |
47 | ('native' in classextend and | 48 | ('native' in classextend and |
48 | d.getVar('EXTERNALSRC_pn-%s-native' % bpn)) or | 49 | d.getVar('EXTERNALSRC:pn-%s-native' % bpn)) or |
49 | ('nativesdk' in classextend and | 50 | ('nativesdk' in classextend and |
50 | d.getVar('EXTERNALSRC_pn-nativesdk-%s' % bpn)) or | 51 | d.getVar('EXTERNALSRC:pn-nativesdk-%s' % bpn)) or |
51 | ('cross' in classextend and | 52 | ('cross' in classextend and |
52 | d.getVar('EXTERNALSRC_pn-%s-cross' % bpn))): | 53 | d.getVar('EXTERNALSRC:pn-%s-cross' % bpn))): |
53 | d.setVar('BB_DONT_CACHE', '1') | 54 | d.setVar('BB_DONT_CACHE', '1') |
54 | 55 | ||
55 | if externalsrc: | 56 | if externalsrc: |
@@ -60,22 +61,21 @@ python () { | |||
60 | if externalsrcbuild: | 61 | if externalsrcbuild: |
61 | d.setVar('B', externalsrcbuild) | 62 | d.setVar('B', externalsrcbuild) |
62 | else: | 63 | else: |
63 | d.setVar('B', '${WORKDIR}/${BPN}-${PV}/') | 64 | d.setVar('B', '${WORKDIR}/${BPN}-${PV}') |
64 | 65 | ||
66 | bb.fetch.get_hashvalue(d) | ||
65 | local_srcuri = [] | 67 | local_srcuri = [] |
66 | fetch = bb.fetch2.Fetch((d.getVar('SRC_URI') or '').split(), d) | 68 | fetch = bb.fetch2.Fetch((d.getVar('SRC_URI') or '').split(), d) |
67 | for url in fetch.urls: | 69 | for url in fetch.urls: |
68 | url_data = fetch.ud[url] | 70 | url_data = fetch.ud[url] |
69 | parm = url_data.parm | 71 | parm = url_data.parm |
70 | if (url_data.type == 'file' or | 72 | if url_data.type in ['file', 'npmsw', 'crate'] or parm.get('type') in ['kmeta', 'git-dependency']: |
71 | url_data.type == 'npmsw' or | ||
72 | 'type' in parm and parm['type'] == 'kmeta'): | ||
73 | local_srcuri.append(url) | 73 | local_srcuri.append(url) |
74 | 74 | ||
75 | d.setVar('SRC_URI', ' '.join(local_srcuri)) | 75 | d.setVar('SRC_URI', ' '.join(local_srcuri)) |
76 | 76 | ||
77 | # Dummy value because the default function can't be called with blank SRC_URI | 77 | # sstate is never going to work for external source trees, disable it |
78 | d.setVar('SRCPV', '999') | 78 | d.setVar('SSTATE_SKIP_CREATION', '1') |
79 | 79 | ||
80 | if d.getVar('CONFIGUREOPT_DEPTRACK') == '--disable-dependency-tracking': | 80 | if d.getVar('CONFIGUREOPT_DEPTRACK') == '--disable-dependency-tracking': |
81 | d.setVar('CONFIGUREOPT_DEPTRACK', '') | 81 | d.setVar('CONFIGUREOPT_DEPTRACK', '') |
@@ -83,32 +83,42 @@ python () { | |||
83 | tasks = filter(lambda k: d.getVarFlag(k, "task"), d.keys()) | 83 | tasks = filter(lambda k: d.getVarFlag(k, "task"), d.keys()) |
84 | 84 | ||
85 | for task in tasks: | 85 | for task in tasks: |
86 | if task.endswith("_setscene"): | 86 | if os.path.realpath(d.getVar('S')) == os.path.realpath(d.getVar('B')): |
87 | # sstate is never going to work for external source trees, disable it | ||
88 | bb.build.deltask(task, d) | ||
89 | elif os.path.realpath(d.getVar('S')) == os.path.realpath(d.getVar('B')): | ||
90 | # Since configure will likely touch ${S}, ensure only we lock so one task has access at a time | 87 | # Since configure will likely touch ${S}, ensure only we lock so one task has access at a time |
91 | d.appendVarFlag(task, "lockfiles", " ${S}/singletask.lock") | 88 | d.appendVarFlag(task, "lockfiles", " ${S}/singletask.lock") |
92 | 89 | ||
93 | # We do not want our source to be wiped out, ever (kernel.bbclass does this for do_clean) | 90 | for v in d.keys(): |
94 | cleandirs = oe.recipeutils.split_var_value(d.getVarFlag(task, 'cleandirs', False) or '') | 91 | cleandirs = d.getVarFlag(v, "cleandirs", False) |
95 | setvalue = False | 92 | if cleandirs: |
96 | for cleandir in cleandirs[:]: | 93 | # We do not want our source to be wiped out, ever (kernel.bbclass does this for do_clean) |
97 | if oe.path.is_path_parent(externalsrc, d.expand(cleandir)): | 94 | cleandirs = oe.recipeutils.split_var_value(cleandirs) |
98 | cleandirs.remove(cleandir) | 95 | setvalue = False |
99 | setvalue = True | 96 | for cleandir in cleandirs[:]: |
100 | if setvalue: | 97 | if oe.path.is_path_parent(externalsrc, d.expand(cleandir)): |
101 | d.setVarFlag(task, 'cleandirs', ' '.join(cleandirs)) | 98 | cleandirs.remove(cleandir) |
99 | setvalue = True | ||
100 | if setvalue: | ||
101 | d.setVarFlag(v, 'cleandirs', ' '.join(cleandirs)) | ||
102 | 102 | ||
103 | fetch_tasks = ['do_fetch', 'do_unpack'] | 103 | fetch_tasks = ['do_fetch', 'do_unpack'] |
104 | # If we deltask do_patch, there's no dependency to ensure do_unpack gets run, so add one | 104 | # If we deltask do_patch, there's no dependency to ensure do_unpack gets run, so add one |
105 | # Note that we cannot use d.appendVarFlag() here because deps is expected to be a list object, not a string | 105 | # Note that we cannot use d.appendVarFlag() here because deps is expected to be a list object, not a string |
106 | d.setVarFlag('do_configure', 'deps', (d.getVarFlag('do_configure', 'deps', False) or []) + ['do_unpack']) | 106 | d.setVarFlag('do_configure', 'deps', (d.getVarFlag('do_configure', 'deps', False) or []) + ['do_unpack']) |
107 | d.setVarFlag('do_populate_lic', 'deps', (d.getVarFlag('do_populate_lic', 'deps', False) or []) + ['do_unpack']) | ||
107 | 108 | ||
108 | for task in d.getVar("SRCTREECOVEREDTASKS").split(): | 109 | for task in d.getVar("SRCTREECOVEREDTASKS").split(): |
109 | if local_srcuri and task in fetch_tasks: | 110 | if local_srcuri and task in fetch_tasks: |
110 | continue | 111 | continue |
111 | bb.build.deltask(task, d) | 112 | bb.build.deltask(task, d) |
113 | if task == 'do_unpack': | ||
114 | # The reproducible build create_source_date_epoch_stamp function must | ||
115 | # be run after the source is available and before the | ||
116 | # do_deploy_source_date_epoch task. In the normal case, it's attached | ||
117 | # to do_unpack as a postfuncs, but since we removed do_unpack (above) | ||
118 | # we need to move the function elsewhere. The easiest thing to do is | ||
119 | # move it into the prefuncs of the do_deploy_source_date_epoch task. | ||
120 | # This is safe, as externalsrc runs with the source already unpacked. | ||
121 | d.prependVarFlag('do_deploy_source_date_epoch', 'prefuncs', 'create_source_date_epoch_stamp ') | ||
112 | 122 | ||
113 | d.prependVarFlag('do_compile', 'prefuncs', "externalsrc_compile_prefunc ") | 123 | d.prependVarFlag('do_compile', 'prefuncs', "externalsrc_compile_prefunc ") |
114 | d.prependVarFlag('do_configure', 'prefuncs', "externalsrc_configure_prefunc ") | 124 | d.prependVarFlag('do_configure', 'prefuncs', "externalsrc_configure_prefunc ") |
@@ -116,6 +126,9 @@ python () { | |||
116 | d.setVarFlag('do_compile', 'file-checksums', '${@srctree_hash_files(d)}') | 126 | d.setVarFlag('do_compile', 'file-checksums', '${@srctree_hash_files(d)}') |
117 | d.setVarFlag('do_configure', 'file-checksums', '${@srctree_configure_hash_files(d)}') | 127 | d.setVarFlag('do_configure', 'file-checksums', '${@srctree_configure_hash_files(d)}') |
118 | 128 | ||
129 | d.appendVarFlag('do_compile', 'prefuncs', ' fetcher_hashes_dummyfunc') | ||
130 | d.appendVarFlag('do_configure', 'prefuncs', ' fetcher_hashes_dummyfunc') | ||
131 | |||
119 | # We don't want the workdir to go away | 132 | # We don't want the workdir to go away |
120 | d.appendVar('RM_WORK_EXCLUDE', ' ' + d.getVar('PN')) | 133 | d.appendVar('RM_WORK_EXCLUDE', ' ' + d.getVar('PN')) |
121 | 134 | ||
@@ -199,8 +212,8 @@ def srctree_hash_files(d, srcdir=None): | |||
199 | try: | 212 | try: |
200 | git_dir = os.path.join(s_dir, | 213 | git_dir = os.path.join(s_dir, |
201 | subprocess.check_output(['git', '-C', s_dir, 'rev-parse', '--git-dir'], stderr=subprocess.DEVNULL).decode("utf-8").rstrip()) | 214 | subprocess.check_output(['git', '-C', s_dir, 'rev-parse', '--git-dir'], stderr=subprocess.DEVNULL).decode("utf-8").rstrip()) |
202 | top_git_dir = os.path.join(s_dir, subprocess.check_output(['git', '-C', d.getVar("TOPDIR"), 'rev-parse', '--git-dir'], | 215 | top_git_dir = os.path.join(d.getVar("TOPDIR"), |
203 | stderr=subprocess.DEVNULL).decode("utf-8").rstrip()) | 216 | subprocess.check_output(['git', '-C', d.getVar("TOPDIR"), 'rev-parse', '--git-dir'], stderr=subprocess.DEVNULL).decode("utf-8").rstrip()) |
204 | if git_dir == top_git_dir: | 217 | if git_dir == top_git_dir: |
205 | git_dir = None | 218 | git_dir = None |
206 | except subprocess.CalledProcessError: | 219 | except subprocess.CalledProcessError: |
@@ -217,14 +230,16 @@ def srctree_hash_files(d, srcdir=None): | |||
217 | env['GIT_INDEX_FILE'] = tmp_index.name | 230 | env['GIT_INDEX_FILE'] = tmp_index.name |
218 | subprocess.check_output(['git', 'add', '-A', '.'], cwd=s_dir, env=env) | 231 | subprocess.check_output(['git', 'add', '-A', '.'], cwd=s_dir, env=env) |
219 | git_sha1 = subprocess.check_output(['git', 'write-tree'], cwd=s_dir, env=env).decode("utf-8") | 232 | git_sha1 = subprocess.check_output(['git', 'write-tree'], cwd=s_dir, env=env).decode("utf-8") |
220 | submodule_helper = subprocess.check_output(['git', 'submodule--helper', 'list'], cwd=s_dir, env=env).decode("utf-8") | 233 | if os.path.exists(os.path.join(s_dir, ".gitmodules")) and os.path.getsize(os.path.join(s_dir, ".gitmodules")) > 0: |
221 | for line in submodule_helper.splitlines(): | 234 | submodule_helper = subprocess.check_output(["git", "config", "--file", ".gitmodules", "--get-regexp", "path"], cwd=s_dir, env=env).decode("utf-8") |
222 | module_dir = os.path.join(s_dir, line.rsplit(maxsplit=1)[1]) | 235 | for line in submodule_helper.splitlines(): |
223 | proc = subprocess.Popen(['git', 'add', '-A', '.'], cwd=module_dir, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) | 236 | module_dir = os.path.join(s_dir, line.rsplit(maxsplit=1)[1]) |
224 | proc.communicate() | 237 | if os.path.isdir(module_dir): |
225 | proc = subprocess.Popen(['git', 'write-tree'], cwd=module_dir, env=env, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) | 238 | proc = subprocess.Popen(['git', 'add', '-A', '.'], cwd=module_dir, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) |
226 | stdout, _ = proc.communicate() | 239 | proc.communicate() |
227 | git_sha1 += stdout.decode("utf-8") | 240 | proc = subprocess.Popen(['git', 'write-tree'], cwd=module_dir, env=env, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) |
241 | stdout, _ = proc.communicate() | ||
242 | git_sha1 += stdout.decode("utf-8") | ||
228 | sha1 = hashlib.sha1(git_sha1.encode("utf-8")).hexdigest() | 243 | sha1 = hashlib.sha1(git_sha1.encode("utf-8")).hexdigest() |
229 | with open(oe_hash_file, 'w') as fobj: | 244 | with open(oe_hash_file, 'w') as fobj: |
230 | fobj.write(sha1) | 245 | fobj.write(sha1) |
@@ -238,6 +253,8 @@ def srctree_configure_hash_files(d): | |||
238 | Get the list of files that should trigger do_configure to re-execute, | 253 | Get the list of files that should trigger do_configure to re-execute, |
239 | based on the value of CONFIGURE_FILES | 254 | based on the value of CONFIGURE_FILES |
240 | """ | 255 | """ |
256 | import fnmatch | ||
257 | |||
241 | in_files = (d.getVar('CONFIGURE_FILES') or '').split() | 258 | in_files = (d.getVar('CONFIGURE_FILES') or '').split() |
242 | out_items = [] | 259 | out_items = [] |
243 | search_files = [] | 260 | search_files = [] |
@@ -249,8 +266,8 @@ def srctree_configure_hash_files(d): | |||
249 | if search_files: | 266 | if search_files: |
250 | s_dir = d.getVar('EXTERNALSRC') | 267 | s_dir = d.getVar('EXTERNALSRC') |
251 | for root, _, files in os.walk(s_dir): | 268 | for root, _, files in os.walk(s_dir): |
252 | for f in files: | 269 | for p in search_files: |
253 | if f in search_files: | 270 | for f in fnmatch.filter(files, p): |
254 | out_items.append('%s:True' % os.path.join(root, f)) | 271 | out_items.append('%s:True' % os.path.join(root, f)) |
255 | return ' '.join(out_items) | 272 | return ' '.join(out_items) |
256 | 273 | ||