summaryrefslogtreecommitdiffstats
path: root/scripts/lib/devtool/standard.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/devtool/standard.py')
-rw-r--r--scripts/lib/devtool/standard.py194
1 files changed, 59 insertions, 135 deletions
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py
index 05161942b7..1d0fe13788 100644
--- a/scripts/lib/devtool/standard.py
+++ b/scripts/lib/devtool/standard.py
@@ -387,6 +387,19 @@ def _git_ls_tree(repodir, treeish='HEAD', recursive=False):
387 ret[split[3]] = split[0:3] 387 ret[split[3]] = split[0:3]
388 return ret 388 return ret
389 389
390def _git_modified(repodir):
391 """List the difference between HEAD and the index"""
392 import bb
393 cmd = ['git', 'status', '--porcelain']
394 out, _ = bb.process.run(cmd, cwd=repodir)
395 ret = []
396 if out:
397 for line in out.split("\n"):
398 if line and not line.startswith('??'):
399 ret.append(line[3:])
400 return ret
401
402
390def _git_exclude_path(srctree, path): 403def _git_exclude_path(srctree, path):
391 """Return pathspec (list of paths) that excludes certain path""" 404 """Return pathspec (list of paths) that excludes certain path"""
392 # NOTE: "Filtering out" files/paths in this way is not entirely reliable - 405 # NOTE: "Filtering out" files/paths in this way is not entirely reliable -
@@ -460,32 +473,6 @@ def sync(args, config, basepath, workspace):
460 finally: 473 finally:
461 tinfoil.shutdown() 474 tinfoil.shutdown()
462 475
463def symlink_oelocal_files_srctree(rd, srctree):
464 import oe.patch
465 if os.path.abspath(rd.getVar('S')) == os.path.abspath(rd.getVar('WORKDIR')):
466 # If recipe extracts to ${WORKDIR}, symlink the files into the srctree
467 # (otherwise the recipe won't build as expected)
468 local_files_dir = os.path.join(srctree, 'oe-local-files')
469 addfiles = []
470 for root, _, files in os.walk(local_files_dir):
471 relpth = os.path.relpath(root, local_files_dir)
472 if relpth != '.':
473 bb.utils.mkdirhier(os.path.join(srctree, relpth))
474 for fn in files:
475 if fn == '.gitignore':
476 continue
477 destpth = os.path.join(srctree, relpth, fn)
478 if os.path.exists(destpth):
479 os.unlink(destpth)
480 if relpth != '.':
481 back_relpth = os.path.relpath(local_files_dir, root)
482 os.symlink('%s/oe-local-files/%s/%s' % (back_relpth, relpth, fn), destpth)
483 else:
484 os.symlink('oe-local-files/%s' % fn, destpth)
485 addfiles.append(os.path.join(relpth, fn))
486 if addfiles:
487 oe.patch.GitApplyTree.commitIgnored("Add local file symlinks", dir=srctree, files=addfiles, d=rd)
488
489def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, workspace, fixed_setup, d, tinfoil, no_overrides=False): 476def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, workspace, fixed_setup, d, tinfoil, no_overrides=False):
490 """Extract sources of a recipe""" 477 """Extract sources of a recipe"""
491 import oe.recipeutils 478 import oe.recipeutils
@@ -657,9 +644,6 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works
657 elif not os.path.exists(workshareddir): 644 elif not os.path.exists(workshareddir):
658 oe.path.copyhardlinktree(srcsubdir, workshareddir) 645 oe.path.copyhardlinktree(srcsubdir, workshareddir)
659 646
660 tempdir_localdir = os.path.join(tempdir, 'oe-local-files')
661 srctree_localdir = os.path.join(srctree, 'oe-local-files')
662
663 if sync: 647 if sync:
664 try: 648 try:
665 logger.info('Backing up current %s branch as branch: %s.bak' % (devbranch, devbranch)) 649 logger.info('Backing up current %s branch as branch: %s.bak' % (devbranch, devbranch))
@@ -674,29 +658,8 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works
674 except bb.process.ExecutionError as e: 658 except bb.process.ExecutionError as e:
675 raise DevtoolError("Error when syncing source files to local checkout: %s" % str(e)) 659 raise DevtoolError("Error when syncing source files to local checkout: %s" % str(e))
676 660
677 # Move the oe-local-files directory to srctree.
678 # As oe-local-files is not part of the constructed git tree,
679 # removing it directly during the synchronization might surprise
680 # the user. Instead, we move it to oe-local-files.bak and remind
681 # the user in the log message.
682 if os.path.exists(srctree_localdir + '.bak'):
683 shutil.rmtree(srctree_localdir + '.bak')
684
685 if os.path.exists(srctree_localdir):
686 logger.info('Backing up current local file directory %s' % srctree_localdir)
687 shutil.move(srctree_localdir, srctree_localdir + '.bak')
688
689 if os.path.exists(tempdir_localdir):
690 logger.info('Syncing local source files to srctree...')
691 shutil.copytree(tempdir_localdir, srctree_localdir)
692 else: 661 else:
693 # Move oe-local-files directory to srctree
694 if os.path.exists(tempdir_localdir):
695 logger.info('Adding local source files to srctree...')
696 shutil.move(tempdir_localdir, srcsubdir)
697
698 shutil.move(srcsubdir, srctree) 662 shutil.move(srcsubdir, srctree)
699 symlink_oelocal_files_srctree(d, srctree)
700 663
701 if is_kernel_yocto: 664 if is_kernel_yocto:
702 logger.info('Copying kernel config to srctree') 665 logger.info('Copying kernel config to srctree')
@@ -852,34 +815,22 @@ def modify(args, config, basepath, workspace):
852 if (os.path.exists(srcdir) and os.listdir(srcdir)) and (kernelVersion in staging_kerVer and staging_kbranch == kbranch): 815 if (os.path.exists(srcdir) and os.listdir(srcdir)) and (kernelVersion in staging_kerVer and staging_kbranch == kbranch):
853 oe.path.copyhardlinktree(srcdir, srctree) 816 oe.path.copyhardlinktree(srcdir, srctree)
854 workdir = rd.getVar('WORKDIR') 817 workdir = rd.getVar('WORKDIR')
818 unpackdir = rd.getVar('UNPACKDIR')
855 srcsubdir = rd.getVar('S') 819 srcsubdir = rd.getVar('S')
856 localfilesdir = os.path.join(srctree, 'oe-local-files') 820 localfilesdir = os.path.join(srctree, 'oe-local-files')
857 # Move local source files into separate subdir
858 recipe_patches = [os.path.basename(patch) for patch in oe.recipeutils.get_recipe_patches(rd)]
859 local_files = oe.recipeutils.get_recipe_local_files(rd)
860 821
861 for key in local_files.copy(): 822 # Add locally copied files to gitignore as we add back to the metadata directly
862 if key.endswith('scc'): 823 local_files = oe.recipeutils.get_recipe_local_files(rd)
863 sccfile = open(local_files[key], 'r')
864 for l in sccfile:
865 line = l.split()
866 if line and line[0] in ('kconf', 'patch'):
867 cfg = os.path.join(os.path.dirname(local_files[key]), line[-1])
868 if not cfg in local_files.values():
869 local_files[line[-1]] = cfg
870 shutil.copy2(cfg, workdir)
871 sccfile.close()
872
873 # Ignore local files with subdir={BP}
874 srcabspath = os.path.abspath(srcsubdir) 824 srcabspath = os.path.abspath(srcsubdir)
875 local_files = [fname for fname in local_files if os.path.exists(os.path.join(workdir, fname)) and (srcabspath == workdir or not os.path.join(workdir, fname).startswith(srcabspath + os.sep))] 825 local_files = [fname for fname in local_files if
826 os.path.exists(os.path.join(unpackdir, fname)) and
827 srcabspath == unpackdir]
876 if local_files: 828 if local_files:
877 for fname in local_files: 829 with open(os.path.join(srctree, '.gitignore'), 'a+') as f:
878 _move_file(os.path.join(workdir, fname), os.path.join(srctree, 'oe-local-files', fname)) 830 f.write('# Ignore local files, by default. Remove following lines'
879 with open(os.path.join(srctree, 'oe-local-files', '.gitignore'), 'w') as f: 831 'if you want to commit the directory to Git\n')
880 f.write('# Ignore local files, by default. Remove this file if you want to commit the directory to Git\n*\n') 832 for fname in local_files:
881 833 f.write('%s\n' % fname)
882 symlink_oelocal_files_srctree(rd, srctree)
883 834
884 task = 'do_configure' 835 task = 'do_configure'
885 res = tinfoil.build_targets(pn, task, handle_events=True) 836 res = tinfoil.build_targets(pn, task, handle_events=True)
@@ -1478,6 +1429,7 @@ def _export_local_files(srctree, rd, destdir, srctreebase):
1478 # Instead they are directly copied over the original source files (in 1429 # Instead they are directly copied over the original source files (in
1479 # recipe space). 1430 # recipe space).
1480 existing_files = oe.recipeutils.get_recipe_local_files(rd) 1431 existing_files = oe.recipeutils.get_recipe_local_files(rd)
1432
1481 new_set = None 1433 new_set = None
1482 updated = OrderedDict() 1434 updated = OrderedDict()
1483 added = OrderedDict() 1435 added = OrderedDict()
@@ -1494,24 +1446,28 @@ def _export_local_files(srctree, rd, destdir, srctreebase):
1494 if branchname.startswith(override_branch_prefix): 1446 if branchname.startswith(override_branch_prefix):
1495 return (updated, added, removed) 1447 return (updated, added, removed)
1496 1448
1497 local_files_dir = os.path.join(srctreebase, 'oe-local-files') 1449 files = _git_modified(srctree)
1498 git_files = _git_ls_tree(srctree) 1450 #if not files:
1499 if 'oe-local-files' in git_files: 1451 # files = _ls_tree(srctree)
1500 # If tracked by Git, take the files from srctree HEAD. First get 1452 for f in files:
1501 # the tree object of the directory 1453 fullfile = os.path.join(srctree, f)
1502 tmp_index = os.path.join(srctree, '.git', 'index.tmp.devtool') 1454 if os.path.exists(os.path.join(fullfile, ".git")):
1503 tree = git_files['oe-local-files'][2] 1455 # submodules handled elsewhere
1504 bb.process.run(['git', 'checkout', tree, '--', '.'], cwd=srctree, 1456 continue
1505 env=dict(os.environ, GIT_WORK_TREE=destdir, 1457 if f not in existing_files:
1506 GIT_INDEX_FILE=tmp_index)) 1458 added[f] = {}
1507 new_set = list(_git_ls_tree(srctree, tree, True).keys()) 1459 if os.path.isdir(os.path.join(srctree, f)):
1508 elif os.path.isdir(local_files_dir): 1460 shutil.copytree(fullfile, os.path.join(destdir, f))
1509 # If not tracked by Git, just copy from working copy 1461 else:
1510 new_set = _ls_tree(local_files_dir) 1462 shutil.copy2(fullfile, os.path.join(destdir, f))
1511 bb.process.run(['cp', '-ax', 1463 elif not os.path.exists(fullfile):
1512 os.path.join(local_files_dir, '.'), destdir]) 1464 removed[f] = existing_files[f]
1513 else: 1465 elif f in existing_files:
1514 new_set = [] 1466 updated[f] = {'path' : existing_files[f]}
1467 if os.path.isdir(os.path.join(srctree, f)):
1468 shutil.copytree(fullfile, os.path.join(destdir, f))
1469 else:
1470 shutil.copy2(fullfile, os.path.join(destdir, f))
1515 1471
1516 # Special handling for kernel config 1472 # Special handling for kernel config
1517 if bb.data.inherits_class('kernel-yocto', rd): 1473 if bb.data.inherits_class('kernel-yocto', rd):
@@ -1519,17 +1475,14 @@ def _export_local_files(srctree, rd, destdir, srctreebase):
1519 fragment_path = os.path.join(destdir, fragment_fn) 1475 fragment_path = os.path.join(destdir, fragment_fn)
1520 if _create_kconfig_diff(srctree, rd, fragment_path): 1476 if _create_kconfig_diff(srctree, rd, fragment_path):
1521 if os.path.exists(fragment_path): 1477 if os.path.exists(fragment_path):
1522 if fragment_fn not in new_set: 1478 if fragment_fn in removed:
1523 new_set.append(fragment_fn) 1479 del removed[fragment_fn]
1524 # Copy fragment to local-files 1480 if fragment_fn not in updated and fragment_fn not in added:
1525 if os.path.isdir(local_files_dir): 1481 added[fragment_fn] = {}
1526 shutil.copy2(fragment_path, local_files_dir)
1527 else: 1482 else:
1528 if fragment_fn in new_set: 1483 if fragment_fn in updated:
1529 new_set.remove(fragment_fn) 1484 revoved[fragment_fn] = updated[fragment_fn]
1530 # Remove fragment from local-files 1485 del updated[fragment_fn]
1531 if os.path.exists(os.path.join(local_files_dir, fragment_fn)):
1532 os.unlink(os.path.join(local_files_dir, fragment_fn))
1533 1486
1534 # Special handling for cml1, ccmake, etc bbclasses that generated 1487 # Special handling for cml1, ccmake, etc bbclasses that generated
1535 # configuration fragment files that are consumed as source files 1488 # configuration fragment files that are consumed as source files
@@ -1537,42 +1490,13 @@ def _export_local_files(srctree, rd, destdir, srctreebase):
1537 if bb.data.inherits_class(frag_class, rd): 1490 if bb.data.inherits_class(frag_class, rd):
1538 srcpath = os.path.join(rd.getVar('WORKDIR'), frag_name) 1491 srcpath = os.path.join(rd.getVar('WORKDIR'), frag_name)
1539 if os.path.exists(srcpath): 1492 if os.path.exists(srcpath):
1540 if frag_name not in new_set: 1493 if frag_name in removed:
1541 new_set.append(frag_name) 1494 del removed[frag_name]
1495 if frag_name not in updated:
1496 added[frag_name] = {}
1542 # copy fragment into destdir 1497 # copy fragment into destdir
1543 shutil.copy2(srcpath, destdir) 1498 shutil.copy2(srcpath, destdir)
1544 # copy fragment into local files if exists 1499
1545 if os.path.isdir(local_files_dir):
1546 shutil.copy2(srcpath, local_files_dir)
1547
1548 if new_set is not None:
1549 for fname in new_set:
1550 if fname in existing_files:
1551 origpath = existing_files.pop(fname)
1552 workpath = os.path.join(local_files_dir, fname)
1553 if not filecmp.cmp(origpath, workpath):
1554 updated[fname] = {'path' : origpath}
1555 elif fname != '.gitignore':
1556 added[fname] = {}
1557
1558 workdir = rd.getVar('WORKDIR')
1559 s = rd.getVar('S')
1560 if not s.endswith(os.sep):
1561 s += os.sep
1562
1563 if workdir != s:
1564 # Handle files where subdir= was specified
1565 for fname in list(existing_files.keys()):
1566 # FIXME handle both subdir starting with BP and not?
1567 fworkpath = os.path.join(workdir, fname)
1568 if fworkpath.startswith(s):
1569 fpath = os.path.join(srctree, os.path.relpath(fworkpath, s))
1570 if os.path.exists(fpath):
1571 origpath = existing_files.pop(fname)
1572 if not filecmp.cmp(origpath, fpath):
1573 updated[fpath] = {'path' : origpath}
1574
1575 removed = existing_files
1576 return (updated, added, removed) 1500 return (updated, added, removed)
1577 1501
1578 1502