summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2017-09-05 10:56:18 +1200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-09-18 11:07:29 +0100
commit10af6d86b3effc523cfa0ec49741c5b02ee2cf86 (patch)
tree64974ae0b7f5fbfaa5647618bf401b98b1d93228
parent4842db00b7aaac96f7bbdfbea5d8bcdb2ebac81b (diff)
downloadpoky-10af6d86b3effc523cfa0ec49741c5b02ee2cf86.tar.gz
devtool: rework source extraction so that dependencies are handled
Since it was first implemented, devtool's source extraction (as used by the devtool modify, extract and upgrade subcommands) ignored other recipe dependencies - so for example if you ran devtool modify on a recipe that fetches from svn or is compressed using xz then it would fail if those dependencies hadn't been built first. Now that we can execute tasks in the normal way (i.e. tinfoil.build_targets()) then we can rework it to use that. This is slightly tricky in that the source extraction needs to insert some logic in between tasks; luckily we can use a helper class that conditionally adds prefuncs to make that possible. Some side-effects / aspects of this change worth noting: * Operations are a little slower because we have to go through the task dependency graph generation and other startup processing. There's not really any way to avoid this though. * devtool extract didn't used to require a workspace, now it does because it needs to create a temporary bbappend for the recipe. (As with other commands the workspace be created on the fly if it doesn't already exist.) * I want any existing sysroot files and stamps to be left alone during extraction since we are running the tasks off to the side, and especially devtool extract should be able to be used without touching these. However, this was hampered by the automatic removal process in sstate.bbclass triggered by bb.event.ReachableStamps when the task signatures change, thus I had to introduce a way to disable this removal on a per-recipe basis (we still want it to function for any dependencies that we aren't working on). To implement this I elected to use a file written to tmp/sstate-control which gets deleted automatically after reading so that there's less chance of stale files affecting future sessions. I could have used a variable but this would have needed to be whitelisted and I'd have to have poked its value in using the setVariable command. Fixes [YOCTO #11198]. (From OE-Core rev: 830dbd66992cbb9e731b48d56fddf8f220349666) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/classes/devtool-source.bbclass165
-rw-r--r--meta/classes/sstate.bbclass9
-rw-r--r--meta/lib/oeqa/selftest/cases/devtool.py10
-rw-r--r--scripts/lib/devtool/standard.py209
-rw-r--r--scripts/lib/devtool/upgrade.py2
5 files changed, 242 insertions, 153 deletions
diff --git a/meta/classes/devtool-source.bbclass b/meta/classes/devtool-source.bbclass
new file mode 100644
index 0000000000..8f5bc86b2e
--- /dev/null
+++ b/meta/classes/devtool-source.bbclass
@@ -0,0 +1,165 @@
1# Development tool - source extraction helper class
2#
3# NOTE: this class is intended for use by devtool and should not be
4# inherited manually.
5#
6# Copyright (C) 2014-2017 Intel Corporation
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21
22DEVTOOL_TEMPDIR ?= ""
23DEVTOOL_PATCH_SRCDIR = "${DEVTOOL_TEMPDIR}/patchworkdir"
24
25
26python() {
27 tempdir = d.getVar('DEVTOOL_TEMPDIR')
28
29 if not tempdir:
30 bb.fatal('devtool-source class is for internal use by devtool only')
31
32 # Make a subdir so we guard against WORKDIR==S
33 workdir = os.path.join(tempdir, 'workdir')
34 d.setVar('WORKDIR', workdir)
35 if not d.getVar('S').startswith(workdir):
36 # Usually a shared workdir recipe (kernel, gcc)
37 # Try to set a reasonable default
38 if bb.data.inherits_class('kernel', d):
39 d.setVar('S', '${WORKDIR}/source')
40 else:
41 d.setVar('S', '${WORKDIR}/%s' % os.path.basename(d.getVar('S')))
42 if bb.data.inherits_class('kernel', d):
43 # We don't want to move the source to STAGING_KERNEL_DIR here
44 d.setVar('STAGING_KERNEL_DIR', '${S}')
45
46 d.setVar('STAMPS_DIR', os.path.join(tempdir, 'stamps'))
47 d.setVar('T', os.path.join(tempdir, 'temp'))
48
49 # Hook in pre/postfuncs
50 is_kernel_yocto = bb.data.inherits_class('kernel-yocto', d)
51 if is_kernel_yocto:
52 unpacktask = 'do_kernel_checkout'
53 d.appendVarFlag('do_configure', 'postfuncs', ' devtool_post_configure')
54 else:
55 unpacktask = 'do_unpack'
56 d.appendVarFlag(unpacktask, 'postfuncs', ' devtool_post_unpack')
57 d.prependVarFlag('do_patch', 'prefuncs', ' devtool_pre_patch')
58 d.appendVarFlag('do_patch', 'postfuncs', ' devtool_post_patch')
59
60 # NOTE: in order for the patch stuff to be fully functional,
61 # PATCHTOOL and PATCH_COMMIT_FUNCTIONS need to be set; we can't
62 # do that here because we can't guarantee the order of the anonymous
63 # functions, so it gets done in the bbappend we create.
64}
65
66
67python devtool_post_unpack() {
68 import oe.recipeutils
69 import shutil
70 sys.path.insert(0, os.path.join(d.getVar('COREBASE'), 'scripts', 'lib'))
71 import scriptutils
72 from devtool import setup_git_repo
73
74 tempdir = d.getVar('DEVTOOL_TEMPDIR')
75 workdir = d.getVar('WORKDIR')
76 srcsubdir = d.getVar('S')
77
78 def _move_file(src, dst):
79 """Move a file. Creates all the directory components of destination path."""
80 dst_d = os.path.dirname(dst)
81 if dst_d:
82 bb.utils.mkdirhier(dst_d)
83 shutil.move(src, dst)
84
85 def _ls_tree(directory):
86 """Recursive listing of files in a directory"""
87 ret = []
88 for root, dirs, files in os.walk(directory):
89 ret.extend([os.path.relpath(os.path.join(root, fname), directory) for
90 fname in files])
91 return ret
92
93 # Move local source files into separate subdir
94 recipe_patches = [os.path.basename(patch) for patch in
95 oe.recipeutils.get_recipe_patches(d)]
96 local_files = oe.recipeutils.get_recipe_local_files(d)
97
98 # Ignore local files with subdir={BP}
99 srcabspath = os.path.abspath(srcsubdir)
100 local_files = [fname for fname in local_files if
101 os.path.exists(os.path.join(workdir, fname)) and
102 (srcabspath == workdir or not
103 os.path.join(workdir, fname).startswith(srcabspath +
104 os.sep))]
105 if local_files:
106 for fname in local_files:
107 _move_file(os.path.join(workdir, fname),
108 os.path.join(tempdir, 'oe-local-files', fname))
109 with open(os.path.join(tempdir, 'oe-local-files', '.gitignore'),
110 'w') as f:
111 f.write('# Ignore local files, by default. Remove this file '
112 'if you want to commit the directory to Git\n*\n')
113
114 if srcsubdir == workdir:
115 # Find non-patch non-local sources that were "unpacked" to srctree
116 # directory
117 src_files = [fname for fname in _ls_tree(workdir) if
118 os.path.basename(fname) not in recipe_patches]
119 srcsubdir = d.getVar('DEVTOOL_PATCH_SRCDIR')
120 # Move source files to S
121 for path in src_files:
122 _move_file(os.path.join(workdir, path),
123 os.path.join(srcsubdir, path))
124 elif os.path.dirname(srcsubdir) != workdir:
125 # Handle if S is set to a subdirectory of the source
126 srcsubdir = os.path.join(workdir, os.path.relpath(srcsubdir, workdir).split(os.sep)[0])
127
128 scriptutils.git_convert_standalone_clone(srcsubdir)
129
130 # Make sure that srcsubdir exists
131 bb.utils.mkdirhier(srcsubdir)
132 if not os.listdir(srcsubdir):
133 bb.warn("No source unpacked to S - either the %s recipe "
134 "doesn't use any source or the correct source "
135 "directory could not be determined" % d.getVar('PN'))
136
137 devbranch = d.getVar('DEVTOOL_DEVBRANCH')
138 setup_git_repo(srcsubdir, d.getVar('PV'), devbranch, d=d)
139
140 (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srcsubdir)
141 initial_rev = stdout.rstrip()
142 with open(os.path.join(tempdir, 'initial_rev'), 'w') as f:
143 f.write(initial_rev)
144
145 with open(os.path.join(tempdir, 'srcsubdir'), 'w') as f:
146 f.write(srcsubdir)
147}
148
149python devtool_pre_patch() {
150 if d.getVar('S') == d.getVar('WORKDIR'):
151 d.setVar('S', '${DEVTOOL_PATCH_SRCDIR}')
152}
153
154python devtool_post_patch() {
155 tempdir = d.getVar('DEVTOOL_TEMPDIR')
156 with open(os.path.join(tempdir, 'srcsubdir'), 'r') as f:
157 srcsubdir = f.read()
158 bb.process.run('git tag -f devtool-patched', cwd=srcsubdir)
159}
160
161python devtool_post_configure() {
162 import shutil
163 tempdir = d.getVar('DEVTOOL_TEMPDIR')
164 shutil.copy2(os.path.join(d.getVar('B'), '.config'), tempdir)
165}
diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index 6af0d388bc..2a54993d1d 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -1015,6 +1015,11 @@ python sstate_eventhandler2() {
1015 d = e.data 1015 d = e.data
1016 stamps = e.stamps.values() 1016 stamps = e.stamps.values()
1017 removeworkdir = (d.getVar("SSTATE_PRUNE_OBSOLETEWORKDIR", False) == "1") 1017 removeworkdir = (d.getVar("SSTATE_PRUNE_OBSOLETEWORKDIR", False) == "1")
1018 preservestampfile = d.expand('${SSTATE_MANIFESTS}/preserve-stamps')
1019 preservestamps = []
1020 if os.path.exists(preservestampfile):
1021 with open(preservestampfile, 'r') as f:
1022 preservestamps = f.readlines()
1018 seen = [] 1023 seen = []
1019 for a in d.getVar("SSTATE_ARCHS").split(): 1024 for a in d.getVar("SSTATE_ARCHS").split():
1020 toremove = [] 1025 toremove = []
@@ -1025,7 +1030,7 @@ python sstate_eventhandler2() {
1025 lines = f.readlines() 1030 lines = f.readlines()
1026 for l in lines: 1031 for l in lines:
1027 (stamp, manifest, workdir) = l.split() 1032 (stamp, manifest, workdir) = l.split()
1028 if stamp not in stamps: 1033 if stamp not in stamps and stamp not in preservestamps:
1029 toremove.append(l) 1034 toremove.append(l)
1030 if stamp not in seen: 1035 if stamp not in seen:
1031 bb.debug(2, "Stamp %s is not reachable, removing related manifests" % stamp) 1036 bb.debug(2, "Stamp %s is not reachable, removing related manifests" % stamp)
@@ -1047,4 +1052,6 @@ python sstate_eventhandler2() {
1047 with open(i, "w") as f: 1052 with open(i, "w") as f:
1048 for l in lines: 1053 for l in lines:
1049 f.write(l) 1054 f.write(l)
1055 if preservestamps:
1056 os.remove(preservestampfile)
1050} 1057}
diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py
index 1dfef599e6..3c537ee071 100644
--- a/meta/lib/oeqa/selftest/cases/devtool.py
+++ b/meta/lib/oeqa/selftest/cases/devtool.py
@@ -1073,7 +1073,7 @@ class DevtoolTests(DevtoolBase):
1073 1073
1074 @OETestID(1628) 1074 @OETestID(1628)
1075 def test_devtool_update_recipe_local_files_subdir(self): 1075 def test_devtool_update_recipe_local_files_subdir(self):
1076 # Try devtool extract on a recipe that has a file with subdir= set in 1076 # Try devtool update-recipe on a recipe that has a file with subdir= set in
1077 # SRC_URI such that it overwrites a file that was in an archive that 1077 # SRC_URI such that it overwrites a file that was in an archive that
1078 # was also in SRC_URI 1078 # was also in SRC_URI
1079 # First, modify the recipe 1079 # First, modify the recipe
@@ -1103,10 +1103,10 @@ class DevtoolTests(DevtoolBase):
1103 tempdir = tempfile.mkdtemp(prefix='devtoolqa') 1103 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1104 # Try devtool extract 1104 # Try devtool extract
1105 self.track_for_cleanup(tempdir) 1105 self.track_for_cleanup(tempdir)
1106 self.track_for_cleanup(self.workspacedir)
1107 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1106 result = runCmd('devtool extract matchbox-terminal %s' % tempdir) 1108 result = runCmd('devtool extract matchbox-terminal %s' % tempdir)
1107 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found') 1109 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found')
1108 # devtool extract shouldn't create the workspace
1109 self.assertNotExists(self.workspacedir)
1110 self._check_src_repo(tempdir) 1110 self._check_src_repo(tempdir)
1111 1111
1112 @OETestID(1379) 1112 @OETestID(1379)
@@ -1114,10 +1114,10 @@ class DevtoolTests(DevtoolBase):
1114 tempdir = tempfile.mkdtemp(prefix='devtoolqa') 1114 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1115 # Try devtool extract 1115 # Try devtool extract
1116 self.track_for_cleanup(tempdir) 1116 self.track_for_cleanup(tempdir)
1117 self.track_for_cleanup(self.workspacedir)
1118 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1117 result = runCmd('devtool extract virtual/make %s' % tempdir) 1119 result = runCmd('devtool extract virtual/make %s' % tempdir)
1118 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found') 1120 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found')
1119 # devtool extract shouldn't create the workspace
1120 self.assertNotExists(self.workspacedir)
1121 self._check_src_repo(tempdir) 1121 self._check_src_repo(tempdir)
1122 1122
1123 @OETestID(1168) 1123 @OETestID(1168)
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py
index 4b489cfd79..b7f278f394 100644
--- a/scripts/lib/devtool/standard.py
+++ b/scripts/lib/devtool/standard.py
@@ -407,7 +407,7 @@ def extract(args, config, basepath, workspace):
407 return 1 407 return 1
408 408
409 srctree = os.path.abspath(args.srctree) 409 srctree = os.path.abspath(args.srctree)
410 initial_rev = _extract_source(srctree, args.keep_temp, args.branch, False, rd, tinfoil) 410 initial_rev = _extract_source(srctree, args.keep_temp, args.branch, False, config, rd, tinfoil)
411 logger.info('Source tree extracted to %s' % srctree) 411 logger.info('Source tree extracted to %s' % srctree)
412 412
413 if initial_rev: 413 if initial_rev:
@@ -431,7 +431,7 @@ def sync(args, config, basepath, workspace):
431 return 1 431 return 1
432 432
433 srctree = os.path.abspath(args.srctree) 433 srctree = os.path.abspath(args.srctree)
434 initial_rev = _extract_source(srctree, args.keep_temp, args.branch, True, rd, tinfoil) 434 initial_rev = _extract_source(srctree, args.keep_temp, args.branch, True, config, rd, tinfoil)
435 logger.info('Source tree %s synchronized' % srctree) 435 logger.info('Source tree %s synchronized' % srctree)
436 436
437 if initial_rev: 437 if initial_rev:
@@ -442,9 +442,10 @@ def sync(args, config, basepath, workspace):
442 tinfoil.shutdown() 442 tinfoil.shutdown()
443 443
444 444
445def _extract_source(srctree, keep_temp, devbranch, sync, d, tinfoil): 445def _extract_source(srctree, keep_temp, devbranch, sync, config, d, tinfoil):
446 """Extract sources of a recipe""" 446 """Extract sources of a recipe"""
447 import oe.recipeutils 447 import oe.recipeutils
448 import oe.patch
448 449
449 pn = d.getVar('PN') 450 pn = d.getVar('PN')
450 451
@@ -466,15 +467,18 @@ def _extract_source(srctree, keep_temp, devbranch, sync, d, tinfoil):
466 raise DevtoolError("The %s recipe has do_unpack disabled, unable to " 467 raise DevtoolError("The %s recipe has do_unpack disabled, unable to "
467 "extract source" % pn, 4) 468 "extract source" % pn, 4)
468 469
469 if bb.data.inherits_class('kernel-yocto', d):
470 tinfoil.build_targets('kern-tools-native')
471
472 if not sync: 470 if not sync:
473 # Prepare for shutil.move later on 471 # Prepare for shutil.move later on
474 bb.utils.mkdirhier(srctree) 472 bb.utils.mkdirhier(srctree)
475 os.rmdir(srctree) 473 os.rmdir(srctree)
476 474
477 initial_rev = None 475 initial_rev = None
476
477 appendexisted = False
478 recipefile = d.getVar('FILE')
479 appendfile = recipe_to_append(recipefile, config)
480 is_kernel_yocto = bb.data.inherits_class('kernel-yocto', d)
481
478 # We need to redirect WORKDIR, STAMPS_DIR etc. under a temporary 482 # We need to redirect WORKDIR, STAMPS_DIR etc. under a temporary
479 # directory so that: 483 # directory so that:
480 # (a) we pick up all files that get unpacked to the WORKDIR, and 484 # (a) we pick up all files that get unpacked to the WORKDIR, and
@@ -493,147 +497,56 @@ def _extract_source(srctree, keep_temp, devbranch, sync, d, tinfoil):
493 try: 497 try:
494 tinfoil.logger.setLevel(logging.WARNING) 498 tinfoil.logger.setLevel(logging.WARNING)
495 499
496 crd = d.createCopy() 500 # FIXME this results in a cache reload under control of tinfoil, which is fine
497 # Make a subdir so we guard against WORKDIR==S 501 # except we don't get the knotty progress bar
498 workdir = os.path.join(tempdir, 'workdir')
499 crd.setVar('WORKDIR', workdir)
500 if not crd.getVar('S').startswith(workdir):
501 # Usually a shared workdir recipe (kernel, gcc)
502 # Try to set a reasonable default
503 if bb.data.inherits_class('kernel', d):
504 crd.setVar('S', '${WORKDIR}/source')
505 else:
506 crd.setVar('S', '${WORKDIR}/%s' % os.path.basename(d.getVar('S')))
507 if bb.data.inherits_class('kernel', d):
508 # We don't want to move the source to STAGING_KERNEL_DIR here
509 crd.setVar('STAGING_KERNEL_DIR', '${S}')
510
511 is_kernel_yocto = bb.data.inherits_class('kernel-yocto', d)
512 if not is_kernel_yocto:
513 crd.setVar('PATCHTOOL', 'git')
514 crd.setVar('PATCH_COMMIT_FUNCTIONS', '1')
515
516 # Apply our changes to the datastore to the server's datastore
517 for key in crd.localkeys():
518 tinfoil.config_data.setVar('%s_pn-%s' % (key, pn), crd.getVar(key, False))
519
520 tinfoil.config_data.setVar('STAMPS_DIR', os.path.join(tempdir, 'stamps'))
521 tinfoil.config_data.setVar('T', os.path.join(tempdir, 'temp'))
522 tinfoil.config_data.setVar('BUILDCFG_FUNCS', '')
523 tinfoil.config_data.setVar('BUILDCFG_HEADER', '')
524 tinfoil.config_data.setVar('BB_HASH_IGNORE_MISMATCH', '1')
525
526 tinfoil.set_event_mask(['bb.event.BuildStarted',
527 'bb.event.BuildCompleted',
528 'logging.LogRecord',
529 'bb.command.CommandCompleted',
530 'bb.command.CommandFailed',
531 'bb.cooker.CookerExit',
532 'bb.build.TaskStarted',
533 'bb.build.TaskSucceeded',
534 'bb.build.TaskFailed',
535 'bb.build.TaskFailedSilent'])
536
537 def runtask(target, task):
538 error = False
539 if tinfoil.build_file(target, task):
540 while True:
541 event = tinfoil.wait_event(0.25)
542 if event:
543 if isinstance(event, bb.command.CommandCompleted):
544 break
545 elif isinstance(event, bb.cooker.CookerExit):
546 # The server is going away, so drop the connection
547 tinfoil.server_connection = None
548 break
549 elif isinstance(event, bb.command.CommandFailed):
550 raise DevtoolError('Task do_%s failed: %s' % (task, event.error))
551 elif isinstance(event, bb.build.TaskFailed):
552 raise DevtoolError('Task do_%s failed' % task)
553 elif isinstance(event, bb.build.TaskStarted):
554 logger.info('Executing %s...' % event._task)
555 elif isinstance(event, logging.LogRecord):
556 if event.levelno <= logging.INFO:
557 continue
558 if event.levelno >= logging.ERROR:
559 error = True
560 logger.handle(event)
561 if error:
562 raise DevtoolError('An error occurred during do_%s, exiting' % task)
563
564 # we need virtual:native:/path/to/recipe if it's a BBCLASSEXTEND
565 fn = tinfoil.get_recipe_file(pn)
566 runtask(fn, 'unpack')
567
568 if bb.data.inherits_class('kernel-yocto', d):
569 # Extra step for kernel to populate the source directory
570 runtask(fn, 'kernel_checkout')
571
572 srcsubdir = crd.getVar('S')
573
574 # Move local source files into separate subdir
575 recipe_patches = [os.path.basename(patch) for patch in
576 oe.recipeutils.get_recipe_patches(crd)]
577 local_files = oe.recipeutils.get_recipe_local_files(crd)
578
579 # Ignore local files with subdir={BP}
580 srcabspath = os.path.abspath(srcsubdir)
581 local_files = [fname for fname in local_files if
582 os.path.exists(os.path.join(workdir, fname)) and
583 (srcabspath == workdir or not
584 os.path.join(workdir, fname).startswith(srcabspath +
585 os.sep))]
586 if local_files:
587 for fname in local_files:
588 _move_file(os.path.join(workdir, fname),
589 os.path.join(tempdir, 'oe-local-files', fname))
590 with open(os.path.join(tempdir, 'oe-local-files', '.gitignore'),
591 'w') as f:
592 f.write('# Ignore local files, by default. Remove this file '
593 'if you want to commit the directory to Git\n*\n')
594
595 if srcsubdir == workdir:
596 # Find non-patch non-local sources that were "unpacked" to srctree
597 # directory
598 src_files = [fname for fname in _ls_tree(workdir) if
599 os.path.basename(fname) not in recipe_patches]
600 # Force separate S so that patch files can be left out from srctree
601 srcsubdir = tempfile.mkdtemp(dir=workdir)
602 tinfoil.config_data.setVar('S_task-patch', srcsubdir)
603 # Move source files to S
604 for path in src_files:
605 _move_file(os.path.join(workdir, path),
606 os.path.join(srcsubdir, path))
607 elif os.path.dirname(srcsubdir) != workdir:
608 # Handle if S is set to a subdirectory of the source
609 srcsubdir = os.path.join(workdir, os.path.relpath(srcsubdir, workdir).split(os.sep)[0])
610
611 scriptutils.git_convert_standalone_clone(srcsubdir)
612 502
613 # Make sure that srcsubdir exists 503 if os.path.exists(appendfile):
614 bb.utils.mkdirhier(srcsubdir) 504 appendbackup = os.path.join(tempdir, os.path.basename(appendfile) + '.bak')
615 if not os.path.exists(srcsubdir) or not os.listdir(srcsubdir): 505 shutil.copyfile(appendfile, appendbackup)
616 logger.warning("no source unpacked to S, either the %s recipe " 506 else:
617 "doesn't use any source or the correct source " 507 appendbackup = None
618 "directory could not be determined" % pn) 508 bb.utils.mkdirhier(os.path.dirname(appendfile))
619 509 logger.debug('writing append file %s' % appendfile)
620 setup_git_repo(srcsubdir, crd.getVar('PV'), devbranch, d=d) 510 with open(appendfile, 'a') as f:
621 511 f.write('###--- _extract_source\n')
622 (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srcsubdir) 512 f.write('DEVTOOL_TEMPDIR = "%s"\n' % tempdir)
623 initial_rev = stdout.rstrip() 513 f.write('DEVTOOL_DEVBRANCH = "%s"\n' % devbranch)
514 if not is_kernel_yocto:
515 f.write('PATCHTOOL = "git"\n')
516 f.write('PATCH_COMMIT_FUNCTIONS = "1"\n')
517 f.write('inherit devtool-source\n')
518 f.write('###--- _extract_source\n')
519
520 update_unlockedsigs(basepath, workspace, fixed_setup, [pn])
521
522 sstate_manifests = d.getVar('SSTATE_MANIFESTS')
523 bb.utils.mkdirhier(sstate_manifests)
524 preservestampfile = os.path.join(sstate_manifests, 'preserve-stamps')
525 with open(preservestampfile, 'w') as f:
526 f.write(d.getVar('STAMP'))
527 try:
528 if bb.data.inherits_class('kernel-yocto', d):
529 # We need to generate the kernel config
530 task = 'do_configure'
531 else:
532 task = 'do_patch'
624 533
625 logger.info('Patching...') 534 # Run the fetch + unpack tasks
626 runtask(fn, 'patch') 535 res = tinfoil.build_targets(pn,
536 task,
537 handle_events=True)
538 finally:
539 if os.path.exists(preservestampfile):
540 os.remove(preservestampfile)
627 541
628 bb.process.run('git tag -f devtool-patched', cwd=srcsubdir) 542 if not res:
543 raise DevtoolError('Extracting source for %s failed' % pn)
629 544
630 kconfig = None 545 with open(os.path.join(tempdir, 'initial_rev'), 'r') as f:
631 if bb.data.inherits_class('kernel-yocto', d): 546 initial_rev = f.read()
632 # Store generate and store kernel config
633 logger.info('Generating kernel config')
634 runtask(fn, 'configure')
635 kconfig = os.path.join(crd.getVar('B'), '.config')
636 547
548 with open(os.path.join(tempdir, 'srcsubdir'), 'r') as f:
549 srcsubdir = f.read()
637 550
638 tempdir_localdir = os.path.join(tempdir, 'oe-local-files') 551 tempdir_localdir = os.path.join(tempdir, 'oe-local-files')
639 srctree_localdir = os.path.join(srctree, 'oe-local-files') 552 srctree_localdir = os.path.join(srctree, 'oe-local-files')
@@ -687,11 +600,15 @@ def _extract_source(srctree, keep_temp, devbranch, sync, d, tinfoil):
687 oe.patch.GitApplyTree.gitCommandUserOptions(useroptions, d=d) 600 oe.patch.GitApplyTree.gitCommandUserOptions(useroptions, d=d)
688 bb.process.run('git %s commit -a -m "Committing local file symlinks\n\n%s"' % (' '.join(useroptions), oe.patch.GitApplyTree.ignore_commit_prefix), cwd=srctree) 601 bb.process.run('git %s commit -a -m "Committing local file symlinks\n\n%s"' % (' '.join(useroptions), oe.patch.GitApplyTree.ignore_commit_prefix), cwd=srctree)
689 602
690 if kconfig: 603 if is_kernel_yocto:
691 logger.info('Copying kernel config to srctree') 604 logger.info('Copying kernel config to srctree')
692 shutil.copy2(kconfig, srctree) 605 shutil.copy2(os.path.join(tempdir, '.config'), srctree)
693 606
694 finally: 607 finally:
608 if appendbackup:
609 shutil.copyfile(appendbackup, appendfile)
610 elif os.path.exists(appendfile):
611 os.remove(appendfile)
695 if keep_temp: 612 if keep_temp:
696 logger.info('Preserving temporary directory %s' % tempdir) 613 logger.info('Preserving temporary directory %s' % tempdir)
697 else: 614 else:
@@ -794,7 +711,7 @@ def modify(args, config, basepath, workspace):
794 initial_rev = None 711 initial_rev = None
795 commits = [] 712 commits = []
796 if not args.no_extract: 713 if not args.no_extract:
797 initial_rev = _extract_source(srctree, args.keep_temp, args.branch, False, rd, tinfoil) 714 initial_rev = _extract_source(srctree, args.keep_temp, args.branch, False, config, rd, tinfoil)
798 if not initial_rev: 715 if not initial_rev:
799 return 1 716 return 1
800 logger.info('Source tree extracted to %s' % srctree) 717 logger.info('Source tree extracted to %s' % srctree)
@@ -1894,7 +1811,7 @@ def register_commands(subparsers, context):
1894 parser_extract.add_argument('srctree', help='Path to where to extract the source tree') 1811 parser_extract.add_argument('srctree', help='Path to where to extract the source tree')
1895 parser_extract.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (default "%(default)s")') 1812 parser_extract.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (default "%(default)s")')
1896 parser_extract.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)') 1813 parser_extract.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)')
1897 parser_extract.set_defaults(func=extract, no_workspace=True) 1814 parser_extract.set_defaults(func=extract)
1898 1815
1899 parser_sync = subparsers.add_parser('sync', help='Synchronize the source tree for an existing recipe', 1816 parser_sync = subparsers.add_parser('sync', help='Synchronize the source tree for an existing recipe',
1900 description='Synchronize the previously extracted source tree for an existing recipe', 1817 description='Synchronize the previously extracted source tree for an existing recipe',
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py
index 41bd34e61a..39d0bd72db 100644
--- a/scripts/lib/devtool/upgrade.py
+++ b/scripts/lib/devtool/upgrade.py
@@ -418,7 +418,7 @@ def upgrade(args, config, basepath, workspace):
418 418
419 rf = None 419 rf = None
420 try: 420 try:
421 rev1 = standard._extract_source(srctree, False, 'devtool-orig', False, rd, tinfoil) 421 rev1 = standard._extract_source(srctree, False, 'devtool-orig', False, config, rd, tinfoil)
422 rev2, md5, sha256, srcbranch = _extract_new_source(args.version, srctree, args.no_patch, 422 rev2, md5, sha256, srcbranch = _extract_new_source(args.version, srctree, args.no_patch,
423 args.srcrev, args.srcbranch, args.branch, args.keep_temp, 423 args.srcrev, args.srcbranch, args.branch, args.keep_temp,
424 tinfoil, rd) 424 tinfoil, rd)