diff options
Diffstat (limited to 'scripts/lib/devtool')
| -rw-r--r-- | scripts/lib/devtool/build_image.py | 124 | ||||
| -rw-r--r-- | scripts/lib/devtool/deploy.py | 141 | ||||
| -rw-r--r-- | scripts/lib/devtool/runqemu.py | 8 | ||||
| -rw-r--r-- | scripts/lib/devtool/standard.py | 355 | ||||
| -rw-r--r-- | scripts/lib/devtool/upgrade.py | 85 |
5 files changed, 369 insertions, 344 deletions
diff --git a/scripts/lib/devtool/build_image.py b/scripts/lib/devtool/build_image.py index 14c646a066..ae75511dc7 100644 --- a/scripts/lib/devtool/build_image.py +++ b/scripts/lib/devtool/build_image.py | |||
| @@ -86,70 +86,76 @@ def build_image_task(config, basepath, workspace, image, add_packages=None, task | |||
| 86 | raise | 86 | raise |
| 87 | 87 | ||
| 88 | tinfoil = setup_tinfoil(basepath=basepath) | 88 | tinfoil = setup_tinfoil(basepath=basepath) |
| 89 | rd = parse_recipe(config, tinfoil, image, True) | ||
| 90 | if not rd: | ||
| 91 | # Error already shown | ||
| 92 | return (1, None) | ||
| 93 | if not bb.data.inherits_class('image', rd): | ||
| 94 | raise TargetNotImageError() | ||
| 95 | |||
| 96 | # Get the actual filename used and strip the .bb and full path | ||
| 97 | target_basename = rd.getVar('FILE', True) | ||
| 98 | target_basename = os.path.splitext(os.path.basename(target_basename))[0] | ||
| 99 | config.set('SDK', 'target_basename', target_basename) | ||
| 100 | config.write() | ||
| 101 | |||
| 102 | appendfile = os.path.join(config.workspace_path, 'appends', | ||
| 103 | '%s.bbappend' % target_basename) | ||
| 104 | |||
| 105 | outputdir = None | ||
| 106 | try: | 89 | try: |
| 107 | if workspace or add_packages: | 90 | rd = parse_recipe(config, tinfoil, image, True) |
| 108 | if add_packages: | 91 | if not rd: |
| 109 | packages = add_packages | 92 | # Error already shown |
| 110 | else: | 93 | return (1, None) |
| 111 | packages = _get_packages(tinfoil, workspace, config) | 94 | if not bb.data.inherits_class('image', rd): |
| 112 | else: | 95 | raise TargetNotImageError() |
| 113 | packages = None | 96 | |
| 114 | if not task: | 97 | # Get the actual filename used and strip the .bb and full path |
| 115 | if not packages and not add_packages and workspace: | 98 | target_basename = rd.getVar('FILE', True) |
| 116 | logger.warning('No recipes in workspace, building image %s unmodified', image) | 99 | target_basename = os.path.splitext(os.path.basename(target_basename))[0] |
| 117 | elif not packages: | 100 | config.set('SDK', 'target_basename', target_basename) |
| 118 | logger.warning('No packages to add, building image %s unmodified', image) | 101 | config.write() |
| 119 | |||
| 120 | if packages or extra_append: | ||
| 121 | bb.utils.mkdirhier(os.path.dirname(appendfile)) | ||
| 122 | with open(appendfile, 'w') as afile: | ||
| 123 | if packages: | ||
| 124 | # include packages from workspace recipes into the image | ||
| 125 | afile.write('IMAGE_INSTALL_append = " %s"\n' % ' '.join(packages)) | ||
| 126 | if not task: | ||
| 127 | logger.info('Building image %s with the following ' | ||
| 128 | 'additional packages: %s', image, ' '.join(packages)) | ||
| 129 | if extra_append: | ||
| 130 | for line in extra_append: | ||
| 131 | afile.write('%s\n' % line) | ||
| 132 | |||
| 133 | if task in ['populate_sdk', 'populate_sdk_ext']: | ||
| 134 | outputdir = rd.getVar('SDK_DEPLOY', True) | ||
| 135 | else: | ||
| 136 | outputdir = rd.getVar('DEPLOY_DIR_IMAGE', True) | ||
| 137 | |||
| 138 | tinfoil.shutdown() | ||
| 139 | 102 | ||
| 140 | options = '' | 103 | appendfile = os.path.join(config.workspace_path, 'appends', |
| 141 | if task: | 104 | '%s.bbappend' % target_basename) |
| 142 | options += '-c %s' % task | ||
| 143 | 105 | ||
| 144 | # run bitbake to build image (or specified task) | 106 | outputdir = None |
| 145 | try: | 107 | try: |
| 146 | exec_build_env_command(config.init_path, basepath, | 108 | if workspace or add_packages: |
| 147 | 'bitbake %s %s' % (options, image), watch=True) | 109 | if add_packages: |
| 148 | except ExecutionError as err: | 110 | packages = add_packages |
| 149 | return (err.exitcode, None) | 111 | else: |
| 112 | packages = _get_packages(tinfoil, workspace, config) | ||
| 113 | else: | ||
| 114 | packages = None | ||
| 115 | if not task: | ||
| 116 | if not packages and not add_packages and workspace: | ||
| 117 | logger.warning('No recipes in workspace, building image %s unmodified', image) | ||
| 118 | elif not packages: | ||
| 119 | logger.warning('No packages to add, building image %s unmodified', image) | ||
| 120 | |||
| 121 | if packages or extra_append: | ||
| 122 | bb.utils.mkdirhier(os.path.dirname(appendfile)) | ||
| 123 | with open(appendfile, 'w') as afile: | ||
| 124 | if packages: | ||
| 125 | # include packages from workspace recipes into the image | ||
| 126 | afile.write('IMAGE_INSTALL_append = " %s"\n' % ' '.join(packages)) | ||
| 127 | if not task: | ||
| 128 | logger.info('Building image %s with the following ' | ||
| 129 | 'additional packages: %s', image, ' '.join(packages)) | ||
| 130 | if extra_append: | ||
| 131 | for line in extra_append: | ||
| 132 | afile.write('%s\n' % line) | ||
| 133 | |||
| 134 | if task in ['populate_sdk', 'populate_sdk_ext']: | ||
| 135 | outputdir = rd.getVar('SDK_DEPLOY', True) | ||
| 136 | else: | ||
| 137 | outputdir = rd.getVar('DEPLOY_DIR_IMAGE', True) | ||
| 138 | |||
| 139 | tmp_tinfoil = tinfoil | ||
| 140 | tinfoil = None | ||
| 141 | tmp_tinfoil.shutdown() | ||
| 142 | |||
| 143 | options = '' | ||
| 144 | if task: | ||
| 145 | options += '-c %s' % task | ||
| 146 | |||
| 147 | # run bitbake to build image (or specified task) | ||
| 148 | try: | ||
| 149 | exec_build_env_command(config.init_path, basepath, | ||
| 150 | 'bitbake %s %s' % (options, image), watch=True) | ||
| 151 | except ExecutionError as err: | ||
| 152 | return (err.exitcode, None) | ||
| 153 | finally: | ||
| 154 | if os.path.isfile(appendfile): | ||
| 155 | os.unlink(appendfile) | ||
| 150 | finally: | 156 | finally: |
| 151 | if os.path.isfile(appendfile): | 157 | if tinfoil: |
| 152 | os.unlink(appendfile) | 158 | tinfoil.shutdown() |
| 153 | return (0, outputdir) | 159 | return (0, outputdir) |
| 154 | 160 | ||
| 155 | 161 | ||
diff --git a/scripts/lib/devtool/deploy.py b/scripts/lib/devtool/deploy.py index 66644ccb6a..fb84f2dd08 100644 --- a/scripts/lib/devtool/deploy.py +++ b/scripts/lib/devtool/deploy.py | |||
| @@ -155,83 +155,86 @@ def deploy(args, config, basepath, workspace): | |||
| 155 | 155 | ||
| 156 | tinfoil = setup_tinfoil(basepath=basepath) | 156 | tinfoil = setup_tinfoil(basepath=basepath) |
| 157 | try: | 157 | try: |
| 158 | rd = oe.recipeutils.parse_recipe_simple(tinfoil.cooker, args.recipename, tinfoil.config_data) | 158 | try: |
| 159 | except Exception as e: | 159 | rd = oe.recipeutils.parse_recipe_simple(tinfoil.cooker, args.recipename, tinfoil.config_data) |
| 160 | raise DevtoolError('Exception parsing recipe %s: %s' % | 160 | except Exception as e: |
| 161 | (args.recipename, e)) | 161 | raise DevtoolError('Exception parsing recipe %s: %s' % |
| 162 | recipe_outdir = rd.getVar('D', True) | 162 | (args.recipename, e)) |
| 163 | if not os.path.exists(recipe_outdir) or not os.listdir(recipe_outdir): | 163 | recipe_outdir = rd.getVar('D', True) |
| 164 | raise DevtoolError('No files to deploy - have you built the %s ' | 164 | if not os.path.exists(recipe_outdir) or not os.listdir(recipe_outdir): |
| 165 | 'recipe? If so, the install step has not installed ' | 165 | raise DevtoolError('No files to deploy - have you built the %s ' |
| 166 | 'any files.' % args.recipename) | 166 | 'recipe? If so, the install step has not installed ' |
| 167 | 'any files.' % args.recipename) | ||
| 167 | 168 | ||
| 168 | filelist = [] | 169 | filelist = [] |
| 169 | ftotalsize = 0 | 170 | ftotalsize = 0 |
| 170 | for root, _, files in os.walk(recipe_outdir): | 171 | for root, _, files in os.walk(recipe_outdir): |
| 171 | for fn in files: | 172 | for fn in files: |
| 172 | # Get the size in kiB (since we'll be comparing it to the output of du -k) | 173 | # Get the size in kiB (since we'll be comparing it to the output of du -k) |
| 173 | # MUST use lstat() here not stat() or getfilesize() since we don't want to | 174 | # MUST use lstat() here not stat() or getfilesize() since we don't want to |
| 174 | # dereference symlinks | 175 | # dereference symlinks |
| 175 | fsize = int(math.ceil(float(os.lstat(os.path.join(root, fn)).st_size)/1024)) | 176 | fsize = int(math.ceil(float(os.lstat(os.path.join(root, fn)).st_size)/1024)) |
| 176 | ftotalsize += fsize | 177 | ftotalsize += fsize |
| 177 | # The path as it would appear on the target | 178 | # The path as it would appear on the target |
| 178 | fpath = os.path.join(destdir, os.path.relpath(root, recipe_outdir), fn) | 179 | fpath = os.path.join(destdir, os.path.relpath(root, recipe_outdir), fn) |
| 179 | filelist.append((fpath, fsize)) | 180 | filelist.append((fpath, fsize)) |
| 180 | 181 | ||
| 181 | if args.dry_run: | 182 | if args.dry_run: |
| 182 | print('Files to be deployed for %s on target %s:' % (args.recipename, args.target)) | 183 | print('Files to be deployed for %s on target %s:' % (args.recipename, args.target)) |
| 183 | for item, _ in filelist: | 184 | for item, _ in filelist: |
| 184 | print(' %s' % item) | 185 | print(' %s' % item) |
| 185 | return 0 | 186 | return 0 |
| 186 | 187 | ||
| 187 | 188 | ||
| 188 | extraoptions = '' | 189 | extraoptions = '' |
| 189 | if args.no_host_check: | 190 | if args.no_host_check: |
| 190 | extraoptions += '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' | 191 | extraoptions += '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' |
| 191 | if not args.show_status: | 192 | if not args.show_status: |
| 192 | extraoptions += ' -q' | 193 | extraoptions += ' -q' |
| 193 | 194 | ||
| 194 | # In order to delete previously deployed files and have the manifest file on | 195 | # In order to delete previously deployed files and have the manifest file on |
| 195 | # the target, we write out a shell script and then copy it to the target | 196 | # the target, we write out a shell script and then copy it to the target |
| 196 | # so we can then run it (piping tar output to it). | 197 | # so we can then run it (piping tar output to it). |
| 197 | # (We cannot use scp here, because it doesn't preserve symlinks.) | 198 | # (We cannot use scp here, because it doesn't preserve symlinks.) |
| 198 | tmpdir = tempfile.mkdtemp(prefix='devtool') | 199 | tmpdir = tempfile.mkdtemp(prefix='devtool') |
| 199 | try: | 200 | try: |
| 200 | tmpscript = '/tmp/devtool_deploy.sh' | 201 | tmpscript = '/tmp/devtool_deploy.sh' |
| 201 | tmpfilelist = os.path.join(os.path.dirname(tmpscript), 'devtool_deploy.list') | 202 | tmpfilelist = os.path.join(os.path.dirname(tmpscript), 'devtool_deploy.list') |
| 202 | shellscript = _prepare_remote_script(deploy=True, | 203 | shellscript = _prepare_remote_script(deploy=True, |
| 203 | verbose=args.show_status, | 204 | verbose=args.show_status, |
| 204 | nopreserve=args.no_preserve, | 205 | nopreserve=args.no_preserve, |
| 205 | nocheckspace=args.no_check_space) | 206 | nocheckspace=args.no_check_space) |
| 206 | # Write out the script to a file | 207 | # Write out the script to a file |
| 207 | with open(os.path.join(tmpdir, os.path.basename(tmpscript)), 'w') as f: | 208 | with open(os.path.join(tmpdir, os.path.basename(tmpscript)), 'w') as f: |
| 208 | f.write(shellscript) | 209 | f.write(shellscript) |
| 209 | # Write out the file list | 210 | # Write out the file list |
| 210 | with open(os.path.join(tmpdir, os.path.basename(tmpfilelist)), 'w') as f: | 211 | with open(os.path.join(tmpdir, os.path.basename(tmpfilelist)), 'w') as f: |
| 211 | f.write('%d\n' % ftotalsize) | 212 | f.write('%d\n' % ftotalsize) |
| 212 | for fpath, fsize in filelist: | 213 | for fpath, fsize in filelist: |
| 213 | f.write('%s %d\n' % (fpath, fsize)) | 214 | f.write('%s %d\n' % (fpath, fsize)) |
| 214 | # Copy them to the target | 215 | # Copy them to the target |
| 215 | ret = subprocess.call("scp %s %s/* %s:%s" % (extraoptions, tmpdir, args.target, os.path.dirname(tmpscript)), shell=True) | 216 | ret = subprocess.call("scp %s %s/* %s:%s" % (extraoptions, tmpdir, args.target, os.path.dirname(tmpscript)), shell=True) |
| 216 | if ret != 0: | 217 | if ret != 0: |
| 217 | raise DevtoolError('Failed to copy script to %s - rerun with -s to ' | 218 | raise DevtoolError('Failed to copy script to %s - rerun with -s to ' |
| 218 | 'get a complete error message' % args.target) | 219 | 'get a complete error message' % args.target) |
| 219 | finally: | 220 | finally: |
| 220 | shutil.rmtree(tmpdir) | 221 | shutil.rmtree(tmpdir) |
| 221 | 222 | ||
| 222 | # Now run the script | 223 | # Now run the script |
| 223 | ret = exec_fakeroot(rd, 'tar cf - . | ssh %s %s \'sh %s %s %s %s\'' % (extraoptions, args.target, tmpscript, args.recipename, destdir, tmpfilelist), cwd=recipe_outdir, shell=True) | 224 | ret = exec_fakeroot(rd, 'tar cf - . | ssh %s %s \'sh %s %s %s %s\'' % (extraoptions, args.target, tmpscript, args.recipename, destdir, tmpfilelist), cwd=recipe_outdir, shell=True) |
| 224 | if ret != 0: | 225 | if ret != 0: |
| 225 | raise DevtoolError('Deploy failed - rerun with -s to get a complete ' | 226 | raise DevtoolError('Deploy failed - rerun with -s to get a complete ' |
| 226 | 'error message') | 227 | 'error message') |
| 227 | 228 | ||
| 228 | logger.info('Successfully deployed %s' % recipe_outdir) | 229 | logger.info('Successfully deployed %s' % recipe_outdir) |
| 229 | 230 | ||
| 230 | files_list = [] | 231 | files_list = [] |
| 231 | for root, _, files in os.walk(recipe_outdir): | 232 | for root, _, files in os.walk(recipe_outdir): |
| 232 | for filename in files: | 233 | for filename in files: |
| 233 | filename = os.path.relpath(os.path.join(root, filename), recipe_outdir) | 234 | filename = os.path.relpath(os.path.join(root, filename), recipe_outdir) |
| 234 | files_list.append(os.path.join(destdir, filename)) | 235 | files_list.append(os.path.join(destdir, filename)) |
| 236 | finally: | ||
| 237 | tinfoil.shutdown() | ||
| 235 | 238 | ||
| 236 | return 0 | 239 | return 0 |
| 237 | 240 | ||
diff --git a/scripts/lib/devtool/runqemu.py b/scripts/lib/devtool/runqemu.py index daee7fbbe3..303abcae4f 100644 --- a/scripts/lib/devtool/runqemu.py +++ b/scripts/lib/devtool/runqemu.py | |||
| @@ -30,9 +30,11 @@ def runqemu(args, config, basepath, workspace): | |||
| 30 | """Entry point for the devtool 'runqemu' subcommand""" | 30 | """Entry point for the devtool 'runqemu' subcommand""" |
| 31 | 31 | ||
| 32 | tinfoil = setup_tinfoil(config_only=True, basepath=basepath) | 32 | tinfoil = setup_tinfoil(config_only=True, basepath=basepath) |
| 33 | machine = tinfoil.config_data.getVar('MACHINE', True) | 33 | try: |
| 34 | bindir_native = tinfoil.config_data.getVar('STAGING_BINDIR_NATIVE', True) | 34 | machine = tinfoil.config_data.getVar('MACHINE', True) |
| 35 | tinfoil.shutdown() | 35 | bindir_native = tinfoil.config_data.getVar('STAGING_BINDIR_NATIVE', True) |
| 36 | finally: | ||
| 37 | tinfoil.shutdown() | ||
| 36 | 38 | ||
| 37 | if not glob.glob(os.path.join(bindir_native, 'qemu-system-*')): | 39 | if not glob.glob(os.path.join(bindir_native, 'qemu-system-*')): |
| 38 | raise DevtoolError('QEMU is not available within this SDK') | 40 | raise DevtoolError('QEMU is not available within this SDK') |
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py index 0d5a42197b..98451da441 100644 --- a/scripts/lib/devtool/standard.py +++ b/scripts/lib/devtool/standard.py | |||
| @@ -213,54 +213,56 @@ def add(args, config, basepath, workspace): | |||
| 213 | _add_md5(config, recipename, os.path.join(recipedir, fn)) | 213 | _add_md5(config, recipename, os.path.join(recipedir, fn)) |
| 214 | 214 | ||
| 215 | tinfoil = setup_tinfoil(config_only=True, basepath=basepath) | 215 | tinfoil = setup_tinfoil(config_only=True, basepath=basepath) |
| 216 | rd = oe.recipeutils.parse_recipe(tinfoil.cooker, recipefile, None) | 216 | try: |
| 217 | if not rd: | 217 | rd = oe.recipeutils.parse_recipe(tinfoil.cooker, recipefile, None) |
| 218 | return 1 | 218 | if not rd: |
| 219 | 219 | return 1 | |
| 220 | if args.fetchuri and not args.no_git: | ||
| 221 | setup_git_repo(srctree, args.version, 'devtool', d=tinfoil.config_data) | ||
| 222 | |||
| 223 | initial_rev = None | ||
| 224 | if os.path.exists(os.path.join(srctree, '.git')): | ||
| 225 | (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree) | ||
| 226 | initial_rev = stdout.rstrip() | ||
| 227 | |||
| 228 | if args.src_subdir: | ||
| 229 | srctree = os.path.join(srctree, args.src_subdir) | ||
| 230 | |||
| 231 | bb.utils.mkdirhier(os.path.dirname(appendfile)) | ||
| 232 | with open(appendfile, 'w') as f: | ||
| 233 | f.write('inherit externalsrc\n') | ||
| 234 | f.write('EXTERNALSRC = "%s"\n' % srctree) | ||
| 235 | |||
| 236 | b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd) | ||
| 237 | if b_is_s: | ||
| 238 | f.write('EXTERNALSRC_BUILD = "%s"\n' % srctree) | ||
| 239 | if initial_rev: | ||
| 240 | f.write('\n# initial_rev: %s\n' % initial_rev) | ||
| 241 | |||
| 242 | if args.binary: | ||
| 243 | f.write('do_install_append() {\n') | ||
| 244 | f.write(' rm -rf ${D}/.git\n') | ||
| 245 | f.write(' rm -f ${D}/singletask.lock\n') | ||
| 246 | f.write('}\n') | ||
| 247 | |||
| 248 | if bb.data.inherits_class('npm', rd): | ||
| 249 | f.write('do_install_append() {\n') | ||
| 250 | f.write(' # Remove files added to source dir by devtool/externalsrc\n') | ||
| 251 | f.write(' rm -f ${NPM_INSTALLDIR}/singletask.lock\n') | ||
| 252 | f.write(' rm -rf ${NPM_INSTALLDIR}/.git\n') | ||
| 253 | f.write(' rm -rf ${NPM_INSTALLDIR}/oe-local-files\n') | ||
| 254 | f.write(' for symlink in ${EXTERNALSRC_SYMLINKS} ; do\n') | ||
| 255 | f.write(' rm -f ${NPM_INSTALLDIR}/${symlink%%:*}\n') | ||
| 256 | f.write(' done\n') | ||
| 257 | f.write('}\n') | ||
| 258 | 220 | ||
| 259 | _add_md5(config, recipename, appendfile) | 221 | if args.fetchuri and not args.no_git: |
| 222 | setup_git_repo(srctree, args.version, 'devtool', d=tinfoil.config_data) | ||
| 260 | 223 | ||
| 261 | logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile) | 224 | initial_rev = None |
| 225 | if os.path.exists(os.path.join(srctree, '.git')): | ||
| 226 | (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree) | ||
| 227 | initial_rev = stdout.rstrip() | ||
| 228 | |||
| 229 | if args.src_subdir: | ||
| 230 | srctree = os.path.join(srctree, args.src_subdir) | ||
| 231 | |||
| 232 | bb.utils.mkdirhier(os.path.dirname(appendfile)) | ||
| 233 | with open(appendfile, 'w') as f: | ||
| 234 | f.write('inherit externalsrc\n') | ||
| 235 | f.write('EXTERNALSRC = "%s"\n' % srctree) | ||
| 236 | |||
| 237 | b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd) | ||
| 238 | if b_is_s: | ||
| 239 | f.write('EXTERNALSRC_BUILD = "%s"\n' % srctree) | ||
| 240 | if initial_rev: | ||
| 241 | f.write('\n# initial_rev: %s\n' % initial_rev) | ||
| 242 | |||
| 243 | if args.binary: | ||
| 244 | f.write('do_install_append() {\n') | ||
| 245 | f.write(' rm -rf ${D}/.git\n') | ||
| 246 | f.write(' rm -f ${D}/singletask.lock\n') | ||
| 247 | f.write('}\n') | ||
| 248 | |||
| 249 | if bb.data.inherits_class('npm', rd): | ||
| 250 | f.write('do_install_append() {\n') | ||
| 251 | f.write(' # Remove files added to source dir by devtool/externalsrc\n') | ||
| 252 | f.write(' rm -f ${NPM_INSTALLDIR}/singletask.lock\n') | ||
| 253 | f.write(' rm -rf ${NPM_INSTALLDIR}/.git\n') | ||
| 254 | f.write(' rm -rf ${NPM_INSTALLDIR}/oe-local-files\n') | ||
| 255 | f.write(' for symlink in ${EXTERNALSRC_SYMLINKS} ; do\n') | ||
| 256 | f.write(' rm -f ${NPM_INSTALLDIR}/${symlink%%:*}\n') | ||
| 257 | f.write(' done\n') | ||
| 258 | f.write('}\n') | ||
| 259 | |||
| 260 | _add_md5(config, recipename, appendfile) | ||
| 261 | |||
| 262 | logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile) | ||
| 262 | 263 | ||
| 263 | tinfoil.shutdown() | 264 | finally: |
| 265 | tinfoil.shutdown() | ||
| 264 | 266 | ||
| 265 | return 0 | 267 | return 0 |
| 266 | 268 | ||
| @@ -352,19 +354,21 @@ def extract(args, config, basepath, workspace): | |||
| 352 | if not tinfoil: | 354 | if not tinfoil: |
| 353 | # Error already shown | 355 | # Error already shown |
| 354 | return 1 | 356 | return 1 |
| 357 | try: | ||
| 358 | rd = parse_recipe(config, tinfoil, args.recipename, True) | ||
| 359 | if not rd: | ||
| 360 | return 1 | ||
| 355 | 361 | ||
| 356 | rd = parse_recipe(config, tinfoil, args.recipename, True) | 362 | srctree = os.path.abspath(args.srctree) |
| 357 | if not rd: | 363 | initial_rev = _extract_source(srctree, args.keep_temp, args.branch, False, rd) |
| 358 | return 1 | 364 | logger.info('Source tree extracted to %s' % srctree) |
| 359 | |||
| 360 | srctree = os.path.abspath(args.srctree) | ||
| 361 | initial_rev = _extract_source(srctree, args.keep_temp, args.branch, False, rd) | ||
| 362 | logger.info('Source tree extracted to %s' % srctree) | ||
| 363 | 365 | ||
| 364 | if initial_rev: | 366 | if initial_rev: |
| 365 | return 0 | 367 | return 0 |
| 366 | else: | 368 | else: |
| 367 | return 1 | 369 | return 1 |
| 370 | finally: | ||
| 371 | tinfoil.shutdown() | ||
| 368 | 372 | ||
| 369 | def sync(args, config, basepath, workspace): | 373 | def sync(args, config, basepath, workspace): |
| 370 | """Entry point for the devtool 'sync' subcommand""" | 374 | """Entry point for the devtool 'sync' subcommand""" |
| @@ -374,19 +378,21 @@ def sync(args, config, basepath, workspace): | |||
| 374 | if not tinfoil: | 378 | if not tinfoil: |
| 375 | # Error already shown | 379 | # Error already shown |
| 376 | return 1 | 380 | return 1 |
| 381 | try: | ||
| 382 | rd = parse_recipe(config, tinfoil, args.recipename, True) | ||
| 383 | if not rd: | ||
| 384 | return 1 | ||
| 377 | 385 | ||
| 378 | rd = parse_recipe(config, tinfoil, args.recipename, True) | 386 | srctree = os.path.abspath(args.srctree) |
| 379 | if not rd: | 387 | initial_rev = _extract_source(srctree, args.keep_temp, args.branch, True, rd) |
| 380 | return 1 | 388 | logger.info('Source tree %s synchronized' % srctree) |
| 381 | |||
| 382 | srctree = os.path.abspath(args.srctree) | ||
| 383 | initial_rev = _extract_source(srctree, args.keep_temp, args.branch, True, rd) | ||
| 384 | logger.info('Source tree %s synchronized' % srctree) | ||
| 385 | 389 | ||
| 386 | if initial_rev: | 390 | if initial_rev: |
| 387 | return 0 | 391 | return 0 |
| 388 | else: | 392 | else: |
| 389 | return 1 | 393 | return 1 |
| 394 | finally: | ||
| 395 | tinfoil.shutdown() | ||
| 390 | 396 | ||
| 391 | class BbTaskExecutor(object): | 397 | class BbTaskExecutor(object): |
| 392 | """Class for executing bitbake tasks for a recipe | 398 | """Class for executing bitbake tasks for a recipe |
| @@ -715,109 +721,111 @@ def modify(args, config, basepath, workspace): | |||
| 715 | args.recipename) | 721 | args.recipename) |
| 716 | 722 | ||
| 717 | tinfoil = setup_tinfoil(basepath=basepath) | 723 | tinfoil = setup_tinfoil(basepath=basepath) |
| 718 | rd = parse_recipe(config, tinfoil, args.recipename, True) | 724 | try: |
| 719 | if not rd: | 725 | rd = parse_recipe(config, tinfoil, args.recipename, True) |
| 720 | return 1 | 726 | if not rd: |
| 721 | |||
| 722 | pn = rd.getVar('PN', True) | ||
| 723 | if pn != args.recipename: | ||
| 724 | logger.info('Mapping %s to %s' % (args.recipename, pn)) | ||
| 725 | if pn in workspace: | ||
| 726 | raise DevtoolError("recipe %s is already in your workspace" % | ||
| 727 | pn) | ||
| 728 | |||
| 729 | if args.srctree: | ||
| 730 | srctree = os.path.abspath(args.srctree) | ||
| 731 | else: | ||
| 732 | srctree = get_default_srctree(config, pn) | ||
| 733 | |||
| 734 | if args.no_extract and not os.path.isdir(srctree): | ||
| 735 | raise DevtoolError("--no-extract specified and source path %s does " | ||
| 736 | "not exist or is not a directory" % | ||
| 737 | srctree) | ||
| 738 | if not args.no_extract: | ||
| 739 | tinfoil = _prep_extract_operation(config, basepath, pn, tinfoil) | ||
| 740 | if not tinfoil: | ||
| 741 | # Error already shown | ||
| 742 | return 1 | 727 | return 1 |
| 743 | 728 | ||
| 744 | recipefile = rd.getVar('FILE', True) | 729 | pn = rd.getVar('PN', True) |
| 745 | appendfile = recipe_to_append(recipefile, config, args.wildcard) | 730 | if pn != args.recipename: |
| 746 | if os.path.exists(appendfile): | 731 | logger.info('Mapping %s to %s' % (args.recipename, pn)) |
| 747 | raise DevtoolError("Another variant of recipe %s is already in your " | 732 | if pn in workspace: |
| 748 | "workspace (only one variant of a recipe can " | 733 | raise DevtoolError("recipe %s is already in your workspace" % |
| 749 | "currently be worked on at once)" | 734 | pn) |
| 750 | % pn) | ||
| 751 | |||
| 752 | _check_compatible_recipe(pn, rd) | ||
| 753 | 735 | ||
| 754 | initial_rev = None | 736 | if args.srctree: |
| 755 | commits = [] | 737 | srctree = os.path.abspath(args.srctree) |
| 756 | if not args.no_extract: | 738 | else: |
| 757 | initial_rev = _extract_source(srctree, False, args.branch, False, rd) | 739 | srctree = get_default_srctree(config, pn) |
| 758 | if not initial_rev: | 740 | |
| 759 | return 1 | 741 | if args.no_extract and not os.path.isdir(srctree): |
| 760 | logger.info('Source tree extracted to %s' % srctree) | 742 | raise DevtoolError("--no-extract specified and source path %s does " |
| 761 | # Get list of commits since this revision | 743 | "not exist or is not a directory" % |
| 762 | (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree) | 744 | srctree) |
| 763 | commits = stdout.split() | 745 | if not args.no_extract: |
| 764 | else: | 746 | tinfoil = _prep_extract_operation(config, basepath, pn, tinfoil) |
| 765 | if os.path.exists(os.path.join(srctree, '.git')): | 747 | if not tinfoil: |
| 766 | # Check if it's a tree previously extracted by us | 748 | # Error already shown |
| 767 | try: | 749 | return 1 |
| 768 | (stdout, _) = bb.process.run('git branch --contains devtool-base', cwd=srctree) | 750 | |
| 769 | except bb.process.ExecutionError: | 751 | recipefile = rd.getVar('FILE', True) |
| 770 | stdout = '' | 752 | appendfile = recipe_to_append(recipefile, config, args.wildcard) |
| 771 | for line in stdout.splitlines(): | 753 | if os.path.exists(appendfile): |
| 772 | if line.startswith('*'): | 754 | raise DevtoolError("Another variant of recipe %s is already in your " |
| 773 | (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=srctree) | 755 | "workspace (only one variant of a recipe can " |
| 774 | initial_rev = stdout.rstrip() | 756 | "currently be worked on at once)" |
| 757 | % pn) | ||
| 758 | |||
| 759 | _check_compatible_recipe(pn, rd) | ||
| 760 | |||
| 761 | initial_rev = None | ||
| 762 | commits = [] | ||
| 763 | if not args.no_extract: | ||
| 764 | initial_rev = _extract_source(srctree, False, args.branch, False, rd) | ||
| 775 | if not initial_rev: | 765 | if not initial_rev: |
| 776 | # Otherwise, just grab the head revision | 766 | return 1 |
| 777 | (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree) | 767 | logger.info('Source tree extracted to %s' % srctree) |
| 778 | initial_rev = stdout.rstrip() | 768 | # Get list of commits since this revision |
| 779 | 769 | (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree) | |
| 780 | # Check that recipe isn't using a shared workdir | 770 | commits = stdout.split() |
| 781 | s = os.path.abspath(rd.getVar('S', True)) | 771 | else: |
| 782 | workdir = os.path.abspath(rd.getVar('WORKDIR', True)) | 772 | if os.path.exists(os.path.join(srctree, '.git')): |
| 783 | if s.startswith(workdir) and s != workdir and os.path.dirname(s) != workdir: | 773 | # Check if it's a tree previously extracted by us |
| 784 | # Handle if S is set to a subdirectory of the source | 774 | try: |
| 785 | srcsubdir = os.path.relpath(s, workdir).split(os.sep, 1)[1] | 775 | (stdout, _) = bb.process.run('git branch --contains devtool-base', cwd=srctree) |
| 786 | srctree = os.path.join(srctree, srcsubdir) | 776 | except bb.process.ExecutionError: |
| 787 | 777 | stdout = '' | |
| 788 | bb.utils.mkdirhier(os.path.dirname(appendfile)) | 778 | for line in stdout.splitlines(): |
| 789 | with open(appendfile, 'w') as f: | 779 | if line.startswith('*'): |
| 790 | f.write('FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n') | 780 | (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=srctree) |
| 791 | # Local files can be modified/tracked in separate subdir under srctree | 781 | initial_rev = stdout.rstrip() |
| 792 | # Mostly useful for packages with S != WORKDIR | 782 | if not initial_rev: |
| 793 | f.write('FILESPATH_prepend := "%s:"\n' % | 783 | # Otherwise, just grab the head revision |
| 794 | os.path.join(srctree, 'oe-local-files')) | 784 | (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree) |
| 795 | 785 | initial_rev = stdout.rstrip() | |
| 796 | f.write('\ninherit externalsrc\n') | ||
| 797 | f.write('# NOTE: We use pn- overrides here to avoid affecting multiple variants in the case where the recipe uses BBCLASSEXTEND\n') | ||
| 798 | f.write('EXTERNALSRC_pn-%s = "%s"\n' % (pn, srctree)) | ||
| 799 | |||
| 800 | b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd) | ||
| 801 | if b_is_s: | ||
| 802 | f.write('EXTERNALSRC_BUILD_pn-%s = "%s"\n' % (pn, srctree)) | ||
| 803 | |||
| 804 | if bb.data.inherits_class('kernel', rd): | ||
| 805 | f.write('SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout ' | ||
| 806 | 'do_fetch do_unpack do_patch do_kernel_configme do_kernel_configcheck"\n') | ||
| 807 | f.write('\ndo_configure_append() {\n' | ||
| 808 | ' cp ${B}/.config ${S}/.config.baseline\n' | ||
| 809 | ' ln -sfT ${B}/.config ${S}/.config.new\n' | ||
| 810 | '}\n') | ||
| 811 | if initial_rev: | ||
| 812 | f.write('\n# initial_rev: %s\n' % initial_rev) | ||
| 813 | for commit in commits: | ||
| 814 | f.write('# commit: %s\n' % commit) | ||
| 815 | |||
| 816 | _add_md5(config, pn, appendfile) | ||
| 817 | 786 | ||
| 818 | logger.info('Recipe %s now set up to build from %s' % (pn, srctree)) | 787 | # Check that recipe isn't using a shared workdir |
| 788 | s = os.path.abspath(rd.getVar('S', True)) | ||
| 789 | workdir = os.path.abspath(rd.getVar('WORKDIR', True)) | ||
| 790 | if s.startswith(workdir) and s != workdir and os.path.dirname(s) != workdir: | ||
| 791 | # Handle if S is set to a subdirectory of the source | ||
| 792 | srcsubdir = os.path.relpath(s, workdir).split(os.sep, 1)[1] | ||
| 793 | srctree = os.path.join(srctree, srcsubdir) | ||
| 794 | |||
| 795 | bb.utils.mkdirhier(os.path.dirname(appendfile)) | ||
| 796 | with open(appendfile, 'w') as f: | ||
| 797 | f.write('FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n') | ||
| 798 | # Local files can be modified/tracked in separate subdir under srctree | ||
| 799 | # Mostly useful for packages with S != WORKDIR | ||
| 800 | f.write('FILESPATH_prepend := "%s:"\n' % | ||
| 801 | os.path.join(srctree, 'oe-local-files')) | ||
| 802 | |||
| 803 | f.write('\ninherit externalsrc\n') | ||
| 804 | f.write('# NOTE: We use pn- overrides here to avoid affecting multiple variants in the case where the recipe uses BBCLASSEXTEND\n') | ||
| 805 | f.write('EXTERNALSRC_pn-%s = "%s"\n' % (pn, srctree)) | ||
| 806 | |||
| 807 | b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd) | ||
| 808 | if b_is_s: | ||
| 809 | f.write('EXTERNALSRC_BUILD_pn-%s = "%s"\n' % (pn, srctree)) | ||
| 810 | |||
| 811 | if bb.data.inherits_class('kernel', rd): | ||
| 812 | f.write('SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout ' | ||
| 813 | 'do_fetch do_unpack do_patch do_kernel_configme do_kernel_configcheck"\n') | ||
| 814 | f.write('\ndo_configure_append() {\n' | ||
| 815 | ' cp ${B}/.config ${S}/.config.baseline\n' | ||
| 816 | ' ln -sfT ${B}/.config ${S}/.config.new\n' | ||
| 817 | '}\n') | ||
| 818 | if initial_rev: | ||
| 819 | f.write('\n# initial_rev: %s\n' % initial_rev) | ||
| 820 | for commit in commits: | ||
| 821 | f.write('# commit: %s\n' % commit) | ||
| 822 | |||
| 823 | _add_md5(config, pn, appendfile) | ||
| 824 | |||
| 825 | logger.info('Recipe %s now set up to build from %s' % (pn, srctree)) | ||
| 819 | 826 | ||
| 820 | tinfoil.shutdown() | 827 | finally: |
| 828 | tinfoil.shutdown() | ||
| 821 | 829 | ||
| 822 | return 0 | 830 | return 0 |
| 823 | 831 | ||
| @@ -1290,17 +1298,20 @@ def update_recipe(args, config, basepath, workspace): | |||
| 1290 | 'destination layer "%s"' % args.append) | 1298 | 'destination layer "%s"' % args.append) |
| 1291 | 1299 | ||
| 1292 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) | 1300 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) |
| 1301 | try: | ||
| 1293 | 1302 | ||
| 1294 | rd = parse_recipe(config, tinfoil, args.recipename, True) | 1303 | rd = parse_recipe(config, tinfoil, args.recipename, True) |
| 1295 | if not rd: | 1304 | if not rd: |
| 1296 | return 1 | 1305 | return 1 |
| 1297 | 1306 | ||
| 1298 | updated = _update_recipe(args.recipename, workspace, rd, args.mode, args.append, args.wildcard_version, args.no_remove, args.initial_rev) | 1307 | updated = _update_recipe(args.recipename, workspace, rd, args.mode, args.append, args.wildcard_version, args.no_remove, args.initial_rev) |
| 1299 | 1308 | ||
| 1300 | if updated: | 1309 | if updated: |
| 1301 | rf = rd.getVar('FILE', True) | 1310 | rf = rd.getVar('FILE', True) |
| 1302 | if rf.startswith(config.workspace_path): | 1311 | if rf.startswith(config.workspace_path): |
| 1303 | logger.warn('Recipe file %s has been updated but is inside the workspace - you will need to move it (and any associated files next to it) out to the desired layer before using "devtool reset" in order to keep any changes' % rf) | 1312 | logger.warn('Recipe file %s has been updated but is inside the workspace - you will need to move it (and any associated files next to it) out to the desired layer before using "devtool reset" in order to keep any changes' % rf) |
| 1313 | finally: | ||
| 1314 | tinfoil.shutdown() | ||
| 1304 | 1315 | ||
| 1305 | return 0 | 1316 | return 0 |
| 1306 | 1317 | ||
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py index a5063f57a9..a4239f1cd2 100644 --- a/scripts/lib/devtool/upgrade.py +++ b/scripts/lib/devtool/upgrade.py | |||
| @@ -336,48 +336,51 @@ def upgrade(args, config, basepath, workspace): | |||
| 336 | raise DevtoolError("If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision" % args.recipename) | 336 | raise DevtoolError("If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision" % args.recipename) |
| 337 | 337 | ||
| 338 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) | 338 | tinfoil = setup_tinfoil(basepath=basepath, tracking=True) |
| 339 | rd = parse_recipe(config, tinfoil, args.recipename, True) | ||
| 340 | if not rd: | ||
| 341 | return 1 | ||
| 342 | |||
| 343 | pn = rd.getVar('PN', True) | ||
| 344 | if pn != args.recipename: | ||
| 345 | logger.info('Mapping %s to %s' % (args.recipename, pn)) | ||
| 346 | if pn in workspace: | ||
| 347 | raise DevtoolError("recipe %s is already in your workspace" % pn) | ||
| 348 | |||
| 349 | if args.srctree: | ||
| 350 | srctree = os.path.abspath(args.srctree) | ||
| 351 | else: | ||
| 352 | srctree = standard.get_default_srctree(config, pn) | ||
| 353 | |||
| 354 | standard._check_compatible_recipe(pn, rd) | ||
| 355 | old_srcrev = rd.getVar('SRCREV', True) | ||
| 356 | if old_srcrev == 'INVALID': | ||
| 357 | old_srcrev = None | ||
| 358 | if old_srcrev and not args.srcrev: | ||
| 359 | raise DevtoolError("Recipe specifies a SRCREV value; you must specify a new one when upgrading") | ||
| 360 | if rd.getVar('PV', True) == args.version and old_srcrev == args.srcrev: | ||
| 361 | raise DevtoolError("Current and upgrade versions are the same version") | ||
| 362 | |||
| 363 | rf = None | ||
| 364 | try: | 339 | try: |
| 365 | rev1 = standard._extract_source(srctree, False, 'devtool-orig', False, rd) | 340 | rd = parse_recipe(config, tinfoil, args.recipename, True) |
| 366 | rev2, md5, sha256 = _extract_new_source(args.version, srctree, args.no_patch, | 341 | if not rd: |
| 367 | args.srcrev, args.branch, args.keep_temp, | 342 | return 1 |
| 368 | tinfoil, rd) | 343 | |
| 369 | rf, copied = _create_new_recipe(args.version, md5, sha256, args.srcrev, args.srcbranch, config.workspace_path, tinfoil, rd) | 344 | pn = rd.getVar('PN', True) |
| 370 | except bb.process.CmdError as e: | 345 | if pn != args.recipename: |
| 371 | _upgrade_error(e, rf, srctree) | 346 | logger.info('Mapping %s to %s' % (args.recipename, pn)) |
| 372 | except DevtoolError as e: | 347 | if pn in workspace: |
| 373 | _upgrade_error(e, rf, srctree) | 348 | raise DevtoolError("recipe %s is already in your workspace" % pn) |
| 374 | standard._add_md5(config, pn, os.path.dirname(rf)) | 349 | |
| 375 | 350 | if args.srctree: | |
| 376 | af = _write_append(rf, srctree, args.same_dir, args.no_same_dir, rev2, | 351 | srctree = os.path.abspath(args.srctree) |
| 377 | copied, config.workspace_path, rd) | 352 | else: |
| 378 | standard._add_md5(config, pn, af) | 353 | srctree = standard.get_default_srctree(config, pn) |
| 379 | logger.info('Upgraded source extracted to %s' % srctree) | 354 | |
| 380 | logger.info('New recipe is %s' % rf) | 355 | standard._check_compatible_recipe(pn, rd) |
| 356 | old_srcrev = rd.getVar('SRCREV', True) | ||
| 357 | if old_srcrev == 'INVALID': | ||
| 358 | old_srcrev = None | ||
| 359 | if old_srcrev and not args.srcrev: | ||
| 360 | raise DevtoolError("Recipe specifies a SRCREV value; you must specify a new one when upgrading") | ||
| 361 | if rd.getVar('PV', True) == args.version and old_srcrev == args.srcrev: | ||
| 362 | raise DevtoolError("Current and upgrade versions are the same version") | ||
| 363 | |||
| 364 | rf = None | ||
| 365 | try: | ||
| 366 | rev1 = standard._extract_source(srctree, False, 'devtool-orig', False, rd) | ||
| 367 | rev2, md5, sha256 = _extract_new_source(args.version, srctree, args.no_patch, | ||
| 368 | args.srcrev, args.branch, args.keep_temp, | ||
| 369 | tinfoil, rd) | ||
| 370 | rf, copied = _create_new_recipe(args.version, md5, sha256, args.srcrev, args.srcbranch, config.workspace_path, tinfoil, rd) | ||
| 371 | except bb.process.CmdError as e: | ||
| 372 | _upgrade_error(e, rf, srctree) | ||
| 373 | except DevtoolError as e: | ||
| 374 | _upgrade_error(e, rf, srctree) | ||
| 375 | standard._add_md5(config, pn, os.path.dirname(rf)) | ||
| 376 | |||
| 377 | af = _write_append(rf, srctree, args.same_dir, args.no_same_dir, rev2, | ||
| 378 | copied, config.workspace_path, rd) | ||
| 379 | standard._add_md5(config, pn, af) | ||
| 380 | logger.info('Upgraded source extracted to %s' % srctree) | ||
| 381 | logger.info('New recipe is %s' % rf) | ||
| 382 | finally: | ||
| 383 | tinfoil.shutdown() | ||
| 381 | return 0 | 384 | return 0 |
| 382 | 385 | ||
| 383 | def register_commands(subparsers, context): | 386 | def register_commands(subparsers, context): |
