from lib import bpkup as kup
from lib.tempdir import tempdir
from lib import bpreqs as reqs
+from lib import bpversion as gen_version
class Bp_Identity(object):
"""
export = re.compile(r'^EXPORT_SYMBOL(_GPL)?\((?P<sym>[^\)]*)\)')
bpi = kconfig.get_backport_info(os.path.join(args.bpid.target_dir, 'compat', 'Kconfig'))
configtree = kconfig.ConfigTree(os.path.join(args.bpid.target_dir, 'Kconfig'), args.bpid)
+ ignore=['Kconfig.kernel', 'Kconfig.versions']
+ configtree.verify_sources(ignore=ignore)
+ git_debug_snapshot(args, "verify sources for automatic backports")
all_selects = configtree.all_selects()
for sym, vals in bpi.items():
- if sym.startswith('BACKPORT_BUILD_'):
- if not sym[15:] in all_selects:
+ if sym.startswith('BPAUTO_BUILD_'):
+ if not sym[13:] in all_selects:
disable_list.append(sym)
continue
symtype, module_name, c_files, h_files = vals
logwrite("Failed to apply changes from %s" % print_name)
for line in output:
logwrite('> %s' % line)
- raise Exception('Patch failed')
+ return 2
if args.refresh:
pfilef = open(pfile + '.tmp', 'a')
logwrite("Failed to diff to refresh %s" % print_name)
pfilef.close()
os.unlink(pfile + '.tmp')
- raise Exception('Refresh failed')
+ return 2
pfilef.close()
os.rename(pfile + '.tmp', pfile)
print_name = cocci_file[prefix_len:]
if args.verbose:
logwrite("Applying SmPL patch %s" % print_name)
+ logwrite(" %s" % cmd)
sprocess = subprocess.Popen(cmd,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
close_fds=True, universal_newlines=True,
output = sprocess.communicate()[0]
sprocess.wait()
if sprocess.returncode != 0:
- logwrite("Failed to process SmPL patch %s" % print_name)
- raise Exception('SmPL patch failed')
+ logwrite("Failed to process SmPL patch %s with %i" % (print_name, sprocess.returncode))
+ return 2
output = output.split('\n')
if output[-1] == '':
output = output[:-1]
# Our binary requirements go here
req = reqs.Req()
req.require('git')
- req.coccinelle('1.0.0-rc21')
+ req.coccinelle('1.0.6')
if not req.reqs_match():
sys.exit(1)
'and we use git ls-tree to get the files.')
parser.add_argument('--clean', const=True, default=False, action="store_const",
help='Clean output directory instead of erroring if it isn\'t empty')
+ parser.add_argument('--integrate', const=True, default=False, action="store_const",
+ help='Integrate a future backported kernel solution into ' +
+ 'an older kernel tree source directory.')
parser.add_argument('--refresh', const=True, default=False, action="store_const",
help='Refresh patches as they are applied, the source dir will be modified!')
parser.add_argument('--base-name', metavar='<name>', type=str, default='Linux',
help='name of base tree, default just "Linux"')
- parser.add_argument('--gitdebug', const=True, default=False, action="store_const",
+ parser.add_argument('--gitdebug', '--git-debug', const=True, default=False, action="store_const",
help='Use git, in the output tree, to debug the various transformation steps ' +
'that the tree generation makes (apply patches, ...)')
parser.add_argument('--verbose', const=True, default=False, action="store_const",
# same prefix for packaging as with kernel integration but
# there are already some users of the CPTCFG prefix.
bpid = None
- integrate = False
- if integrate:
- bpid = Bp_Identity(integrate = integrate,
+ if args.integrate:
+ bpid = Bp_Identity(integrate = args.integrate,
kconfig_prefix = 'CONFIG_',
project_prefix = 'BACKPORT_',
project_dir = args.outdir,
kconfig_source_var = '$BACKPORT_DIR',
)
else:
- bpid = Bp_Identity(integrate = integrate,
+ bpid = Bp_Identity(integrate = args.integrate,
kconfig_prefix = 'CPTCFG_',
project_prefix = '',
project_dir = args.outdir,
test_cocci, profile_cocci)
rel_prep = None
+ if bpid.integrate:
+ if args.kup_test or args.test_cocci or args.profile_cocci or args.refresh:
+ logwrite('Cannot use integration with:\n\tkup_test\n\ttest_cocci\n\tprofile_cocci\n\trefresh\n');
+ sys.exit(1)
+
# start processing ...
if (args.kup or args.kup_test):
git_paranoia(source_dir, logwrite)
check_output_dir(bpid.target_dir, args.clean)
# do the copy
+ backport_integrate_files = [
+ ('Makefile.kernel', 'Makefile'),
+ ('Kconfig.integrate', 'Kconfig'),
+ ]
backport_package_files = [(x, x) for x in [
'Makefile',
'kconf/',
if not bpid.integrate:
backport_files += backport_package_files
+ else:
+ backport_files += backport_integrate_files
if not args.git_revision:
logwrite('Copy original source files ...')
git_debug_snapshot(args, 'Add driver sources')
disable_list = add_automatic_backports(args)
+ if git_tracked_version:
+ backports_version = "(see git)"
+ kernel_version = "(see git)"
+ else:
+ backports_version = git.describe(tree=source_dir, extra_args=['--long'])
+ kernel_version = git.describe(rev=args.git_revision or 'HEAD',
+ tree=args.kerneldir,
+ extra_args=['--long'])
+
+ if not bpid.integrate:
+ f = open(os.path.join(bpid.target_dir, 'versions'), 'w')
+ f.write('BACKPORTS_VERSION="%s"\n' % backports_version)
+ f.write('BACKPORTED_KERNEL_VERSION="%s"\n' % kernel_version)
+ f.write('BACKPORTED_KERNEL_NAME="%s"\n' % args.base_name)
+ if git_tracked_version:
+ f.write('BACKPORTS_GIT_TRACKED="backport tracker ID: $(shell git rev-parse HEAD 2>/dev/null || echo \'not built in git tree\')"\n')
+ f.close()
+ git_debug_snapshot(args, "add versions files")
+ else:
+ kconf_regexes = [
+ (re.compile(r'.*(?P<key>%%BACKPORT_DIR%%)'), '%%BACKPORT_DIR%%', 'backports/'),
+ (re.compile(r'.*(?P<key>%%BACKPORTS_VERSION%%).*'), '%%BACKPORTS_VERSION%%', backports_version),
+ (re.compile(r'.*(?P<key>%%BACKPORTED_KERNEL_VERSION%%).*'), '%%BACKPORTED_KERNEL_VERSION%%', kernel_version),
+ (re.compile(r'.*(?P<key>%%BACKPORTED_KERNEL_NAME%%).*'), '%%BACKPORTED_KERNEL_NAME%%', args.base_name),
+ ]
+ out = ''
+ for l in open(os.path.join(bpid.target_dir, 'Kconfig'), 'r'):
+ for r in kconf_regexes:
+ m = r[0].match(l)
+ if m:
+ l = re.sub(r'(' + r[1] + ')', r'' + r[2] + '', l)
+ out += l
+ outf = open(os.path.join(bpid.target_dir, 'Kconfig'), 'w')
+ outf.write(out)
+ outf.close()
+ git_debug_snapshot(args, "modify top level backports/Kconfig with backports identity")
if disable_list:
# No need to verify_sources() as compat's Kconfig has no 'source' call
bpcfg.disable_symbols(disable_list)
git_debug_snapshot(args, 'Add automatic backports')
- apply_patches(args, "backport", source_dir, 'patches', bpid.target_dir, logwrite)
+ failure = apply_patches(args, "backport", source_dir, 'patches', bpid.target_dir, logwrite)
+ if failure:
+ return failure
+
+ # Kernel integration requires Kconfig.versions already generated for you,
+ # we cannot do this for a package as we have no idea what kernel folks
+ # will be using.
+ if bpid.integrate:
+ kver = gen_version.kernelversion(bpid.project_dir)
+ rel_specs = gen_version.get_rel_spec_stable(kver)
+ if not rel_specs:
+ logwrite('Cannot parse source kernel version, update parser')
+ sys.exit(1)
+ data = gen_version.genkconfig_versions(rel_specs)
+ fo = open(os.path.join(bpid.target_dir, 'Kconfig.versions'), 'w')
+ fo.write(data)
+ fo.close()
+ git_debug_snapshot(args, "generate kernel version requirement Kconfig file")
# some post-processing is required
configtree = kconfig.ConfigTree(os.path.join(bpid.target_dir, 'Kconfig'), bpid)
- ignore=['Kconfig.kernel', 'Kconfig.versions']
+ ignore=['Kconfig.kernel', 'Kconfig.versions', 'Kconfig.local']
configtree.verify_sources(ignore=ignore)
git_debug_snapshot(args, "verify sources on top level backports Kconfig")
configtree.force_tristate_modular()
git_debug_snapshot(args, "force tristate options modular")
+ ignore = [os.path.join(bpid.target_dir, x) for x in [
+ 'Kconfig.package.hacks',
+ 'Kconfig.versions',
+ 'Kconfig.local',
+ 'Kconfig',
+ ]
+ ]
+ configtree.adjust_backported_configs(ignore=ignore, orig_symbols=orig_symbols)
+ git_debug_snapshot(args, "adjust backports config symbols we port")
+
configtree.modify_selects()
git_debug_snapshot(args, "convert select to depends on")
- # write the versioning file
- if git_tracked_version:
- backports_version = "(see git)"
- kernel_version = "(see git)"
- else:
- backports_version = git.describe(tree=source_dir, extra_args=['--long'])
- kernel_version = git.describe(rev=args.git_revision or 'HEAD',
- tree=args.kerneldir,
- extra_args=['--long'])
- f = open(os.path.join(bpid.target_dir, 'versions'), 'w')
- f.write('BACKPORTS_VERSION="%s"\n' % backports_version)
- f.write('BACKPORTED_KERNEL_VERSION="%s"\n' % kernel_version)
- f.write('BACKPORTED_KERNEL_NAME="%s"\n' % args.base_name)
- if git_tracked_version:
- f.write('BACKPORTS_GIT_TRACKED="backport tracker ID: $(shell git rev-parse HEAD 2>/dev/null || echo \'not built in git tree\')"\n')
- f.close()
- git_debug_snapshot(args, "add versions files")
-
symbols = configtree.symbols()
# write local symbol list -- needed during packaging build
if not bpid.integrate:
- f = open(os.path.join(bpid.target_dir, '.local-symbols'), 'w')
+ f = open(os.path.join(bpid.target_dir, 'local-symbols'), 'w')
for sym in symbols:
f.write('%s=\n' % sym)
f.close()
git_debug_snapshot(args, "add symbols files")
+ # also write Kconfig.local, representing all local symbols
+ # with a BACKPORTED_ prefix
+ f = open(os.path.join(bpid.target_dir, 'Kconfig.local'), 'w')
+ for sym in symbols:
+ f.write('config BACKPORTED_%s\n' % sym)
+ f.write('\ttristate\n')
+ f.write('\tdefault %s\n' % sym)
+ f.close()
+ git_debug_snapshot(args, "add Kconfig.local")
# add defconfigs that we want
defconfigs_dir = os.path.join(source_dir, 'backport', 'defconfigs')
# rewrite Makefile and source symbols
+ # symbols we know only we can provide under the backport project prefix
+ # for which we need an exception.
+ skip_orig_syms = [ bpid.project_prefix + x for x in [
+ 'INTEGRATE',
+ ]
+ ]
+ parse_orig_syms = [x for x in orig_symbols if x not in skip_orig_syms ]
regexes = []
- for some_symbols in [orig_symbols[i:i + 50] for i in range(0, len(orig_symbols), 50)]:
+ for some_symbols in [parse_orig_syms[i:i + 50] for i in range(0, len(parse_orig_syms), 50)]:
r = 'CONFIG_((' + '|'.join([s + '(_MODULE)?' for s in some_symbols]) + ')([^A-Za-z0-9_]|$))'
regexes.append(re.compile(r, re.MULTILINE))
for root, dirs, files in os.walk(bpid.target_dir):
data = open(os.path.join(root, f), 'r').read()
for r in regexes:
data = r.sub(r'' + bpid.full_prefix + '\\1', data)
+ # we have an absolue path in $(src) since we compile out of tree
+ data = re.sub(r'\$\(srctree\)/\$\(src\)', '$(src)', data)
data = re.sub(r'\$\(srctree\)', '$(backport_srctree)', data)
data = re.sub(r'-Idrivers', '-I$(backport_srctree)/drivers', data)
if bpid.integrate:
git_debug_snapshot(args, "rename config symbol / srctree usage")
# disable unbuildable Kconfig symbols and stuff Makefiles that doesn't exist
- maketree = make.MakeTree(os.path.join(bpid.target_dir, 'Makefile.kernel'))
+ if bpid.integrate:
+ maketree = make.MakeTree(os.path.join(bpid.target_dir, 'Makefile'))
+ else:
+ maketree = make.MakeTree(os.path.join(bpid.target_dir, 'Makefile.kernel'))
disable_kconfig = []
disable_makefile = []
for sym in maketree.get_impossible_symbols():
elif (dep == "DISABLE"):
new.append('BACKPORT_DISABLED_KCONFIG_OPTION')
else:
- new.append('!BACKPORT_KERNEL_%s' % dep.replace('.', '_'))
+ new.append('!KERNEL_%s' % dep.replace('.', '_'))
if bpid.integrate:
deplist[sym] = ["BACKPORT_" + x for x in new]
else:
# groups -- 50 seemed safer and is still fast)
regexes = []
for some_symbols in [disable_makefile[i:i + 50] for i in range(0, len(disable_makefile), 50)]:
- r = '^([^#].*((' + bpid.full_prefix_resafe + '|CONFIG_)(' + '|'.join([s for s in some_symbols]) + ')))'
+ r = '^(([^#].*((' + bpid.full_prefix_resafe + '|CONFIG_)(' + '|'.join([s for s in some_symbols]) + ')))\W)'
regexes.append(re.compile(r, re.MULTILINE))
for f in maketree.get_makefiles():
data = open(f, 'r').read()
fo.close()
git_debug_snapshot(args, "disable unsatisfied Makefile parts")
+ if bpid.integrate:
+ f = open(os.path.join(bpid.project_dir, 'Kconfig'), 'a')
+ f.write('source "backports/Kconfig"\n')
+ f.close()
+ git_debug_snapshot(args, "hooked backport to top level Kconfig")
+
+ failure = apply_patches(args, "integration", source_dir, 'integration-patches/',
+ bpid.project_dir, logwrite)
+ if failure:
+ return failure
+
if (args.kup or args.kup_test):
req = reqs.Req()
req.kup()