From 0a125948478095bd762a7669a453fc9d6d4477c7 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 24 Nov 2018 17:42:35 +0100 Subject: Added include_directories and extra_args keys to target introspection --- mesonbuild/mintro.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 3896c92..5509444 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -30,8 +30,11 @@ from . import compilers from . import optinterpreter from .interpreterbase import InvalidArguments from .backend import ninjabackend, backends +from .dependencies import base +from .compilers import compilers import sys, os import pathlib +import re def add_arguments(parser): parser.add_argument('--targets', action='store_true', dest='list_targets', default=False, @@ -88,11 +91,85 @@ def list_installed(installdata): res[path] = os.path.join(installdata.prefix, installpath) print(json.dumps(res)) +def include_dirs_to_path(inc_dirs, src_root, build_root): + result = [] + if isinstance(inc_dirs, build.IncludeDirs): + for i in inc_dirs.get_incdirs(): + abs_src = os.path.join(src_root, inc_dirs.get_curdir(), i) + abs_build = os.path.join(build_root, inc_dirs.get_curdir(), i) + + if os.path.isdir(abs_src): + result += [abs_src] + + if os.path.isdir(abs_build): + result += [abs_build] + + return result + +def extract_dependency_infromation(dep): + inc_dirs = [] + args = [] + if isinstance(dep, base.Dependency): + reg = re.compile(r'-I(.*)') + for i in dep.get_compile_args(): + match = reg.match(i) + if match: + inc_dirs += [match.group(1)] + else: + args += [i] + + return inc_dirs, args def list_targets(coredata, builddata, installdata): tlist = [] for (idname, target) in builddata.get_targets().items(): - t = {'name': target.get_basename(), 'id': idname} + src_root = builddata.environment.get_source_dir() + build_root = builddata.environment.get_build_dir() + + inc_dirs = [] + extra_args = {} + dep_args = [] + + def climb_stack(tgt, inc_dirs, extra_args, dep_args): + if isinstance(tgt, build.BuildTarget): + # The build directory is always in the include directories + absbase_src = os.path.join(src_root, tgt.subdir) + absbase_build = os.path.join(build_root, tgt.subdir) + inc_dirs += [absbase_src, absbase_build] + + for i in tgt.include_dirs: + inc_dirs += include_dirs_to_path(i, src_root, build_root) + + for i in tgt.external_deps: + dep_inc_dirs, args = extract_dependency_infromation(i) + inc_dirs += dep_inc_dirs + dep_args += args + + for i, comp in tgt.compilers.items(): + if isinstance(comp, compilers.Compiler): + lang = comp.get_language() + if lang not in extra_args: + extra_args[lang] = [] + + extra_args[i] += tgt.get_extra_args(lang) + extra_args[i] += builddata.get_global_args(comp, False) + extra_args[i] += builddata.get_project_args(comp, tgt.subproject, False) + + for i in tgt.link_targets: + climb_stack(i, inc_dirs, extra_args, dep_args) + + climb_stack(target, inc_dirs, extra_args, dep_args) + + # Add the dep_args, sort and remove duplicates + for i in extra_args: + extra_args[i] += dep_args + extra_args[i] = list(sorted(list(set(extra_args[i])))) + + # Remove duplicates, sort and make paths pretty + inc_dirs = list(sorted(list(set(inc_dirs)))) + inc_dirs = list(map(lambda x: os.path.realpath(x), inc_dirs)) + + t = {'name': target.get_basename(), 'id': idname, 'include_directories': inc_dirs, 'extra_args': extra_args} fname = target.get_filename() if isinstance(fname, list): fname = [os.path.join(target.subdir, x) for x in fname] -- cgit v1.1 From 9d13855544cd4af446b589d77342cdbb7fd2456c Mon Sep 17 00:00:00 2001 From: mensinda Date: Sat, 24 Nov 2018 19:45:49 +0100 Subject: Fixed hardcode is_cross = False --- mesonbuild/mintro.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 5509444..0459b4e 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -147,13 +147,12 @@ def list_targets(coredata, builddata, installdata): for i, comp in tgt.compilers.items(): if isinstance(comp, compilers.Compiler): - lang = comp.get_language() - if lang not in extra_args: - extra_args[lang] = [] + if i not in extra_args: + extra_args[i] = [] - extra_args[i] += tgt.get_extra_args(lang) - extra_args[i] += builddata.get_global_args(comp, False) - extra_args[i] += builddata.get_project_args(comp, tgt.subproject, False) + extra_args[i] += tgt.get_extra_args(i) + extra_args[i] += builddata.get_global_args(comp, tgt.is_cross) + extra_args[i] += builddata.get_project_args(comp, tgt.subproject, tgt.is_cross) for i in tgt.link_targets: climb_stack(i, inc_dirs, extra_args, dep_args) -- cgit v1.1 From 1a0e1afbddd51c8ddc4e78e8df4c9ab8e795b8d6 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Tue, 27 Nov 2018 17:55:59 +0100 Subject: Updated format to include sources --- mesonbuild/mintro.py | 66 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 13 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 0459b4e..5372b30 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -123,12 +123,16 @@ def extract_dependency_infromation(dep): def list_targets(coredata, builddata, installdata): tlist = [] for (idname, target) in builddata.get_targets().items(): + if not isinstance(target, build.Target): + raise RuntimeError('Something weird happened. File a bug.') + src_root = builddata.environment.get_source_dir() build_root = builddata.environment.get_build_dir() inc_dirs = [] extra_args = {} dep_args = [] + sources = {} def climb_stack(tgt, inc_dirs, extra_args, dep_args): if isinstance(tgt, build.BuildTarget): @@ -157,18 +161,54 @@ def list_targets(coredata, builddata, installdata): for i in tgt.link_targets: climb_stack(i, inc_dirs, extra_args, dep_args) - climb_stack(target, inc_dirs, extra_args, dep_args) - - # Add the dep_args, sort and remove duplicates - for i in extra_args: - extra_args[i] += dep_args - extra_args[i] = list(sorted(list(set(extra_args[i])))) - - # Remove duplicates, sort and make paths pretty - inc_dirs = list(sorted(list(set(inc_dirs)))) - inc_dirs = list(map(lambda x: os.path.realpath(x), inc_dirs)) - - t = {'name': target.get_basename(), 'id': idname, 'include_directories': inc_dirs, 'extra_args': extra_args} + if isinstance(target, build.BuildTarget): + climb_stack(target, inc_dirs, extra_args, dep_args) + + # Add the dep_args, sort and remove duplicates + for i in extra_args: + extra_args[i] += dep_args + extra_args[i] = list(sorted(list(set(extra_args[i])))) + + # Remove duplicates, sort and make paths pretty + inc_dirs = list(sorted(list(set(inc_dirs)))) + inc_dirs = list(map(lambda x: os.path.realpath(x), inc_dirs)) + + comp_list = target.compilers.values() + source_list = target.sources + target.extra_files + source_list = list(map(lambda x: (mesonlib.get_compiler_for_source(comp_list, x), x), source_list)) + + for comp, src in source_list: + if isinstance(comp, compilers.Compiler) and isinstance(src, mesonlib.File): + lang = comp.get_language() + if lang not in sources: + parameters = [] + + # Generate include directories + # Not all compilers have the get_include_args method + get_include_args = getattr(comp, 'get_include_args', None) + if callable(get_include_args): + for i in inc_dirs: + parameters += comp.get_include_args(i, False) + + # Extra args + if lang in extra_args: + parameters += extra_args[lang] + + sources[lang] = { + 'compiler': comp.get_exelist(), + 'parameters': parameters, + 'source_files': [] + } + + sources[lang]['source_files'] += [os.path.join(src.subdir, src.fname)] + + # Convert the dict to a list and add the language key. + # This list approach will also work if the gurantee is removed that all + # files in a target are compiled with the same parameters + # see https://github.com/mesonbuild/meson/pull/4547 + sources = list(map(lambda x: {'language': x[0], **x[1]}, sources.items())) + + t = {'name': target.get_basename(), 'id': idname, 'sources': sources} fname = target.get_filename() if isinstance(fname, list): fname = [os.path.join(target.subdir, x) for x in fname] @@ -195,7 +235,7 @@ def list_targets(coredata, builddata, installdata): t['installed'] = False t['build_by_default'] = target.build_by_default tlist.append(t) - print(json.dumps(tlist)) + print(json.dumps(tlist, indent=2)) def list_target_files(target_name, coredata, builddata): try: -- cgit v1.1 From 8288555aa1dcab1ae38831d40529c6a2fbe3c8fd Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 25 Nov 2018 21:40:38 +0100 Subject: mintro: Added option to introspect multiple parameters at once --- mesonbuild/mintro.py | 71 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 27 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 5372b30..70f0f09 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -57,6 +57,10 @@ def add_arguments(parser): help='Information about projects.') parser.add_argument('--backend', choices=cdata.backendlist, dest='backend', default='ninja', help='The backend to use for the --buildoptions introspection.') + parser.add_argument('-a', '--all', action='store_true', dest='all', default=False, + help='Print all available information.') + parser.add_argument('-i', '--indent', dest='indent', type=int, default=0, + help='Number of spaces used for indentation.') parser.add_argument('builddir', nargs='?', default='.', help='The build directory') def determine_installed_path(target, installdata): @@ -89,7 +93,7 @@ def list_installed(installdata): res[path] = os.path.join(installdata.prefix, installdir, os.path.basename(path)) for path, installpath, unused_custom_install_mode in installdata.man: res[path] = os.path.join(installdata.prefix, installpath) - print(json.dumps(res)) + return res def include_dirs_to_path(inc_dirs, src_root, build_root): result = [] @@ -235,7 +239,7 @@ def list_targets(coredata, builddata, installdata): t['installed'] = False t['build_by_default'] = target.build_by_default tlist.append(t) - print(json.dumps(tlist, indent=2)) + return tlist def list_target_files(target_name, coredata, builddata): try: @@ -249,7 +253,7 @@ def list_target_files(target_name, coredata, builddata): if isinstance(i, mesonlib.File): i = os.path.join(i.subdir, i.fname) out.append(i) - print(json.dumps(out)) + return out class BuildoptionsOptionHelper: # mimic an argparse namespace @@ -429,7 +433,7 @@ def list_buildoptions(coredata): add_keys(optlist, dir_options, 'directory') add_keys(optlist, coredata.user_options, 'user') add_keys(optlist, test_options, 'test') - print(json.dumps(optlist)) + return optlist def add_keys(optlist, options, section): keys = list(options.keys()) @@ -466,7 +470,7 @@ def find_buildsystem_files_list(src_dir): def list_buildsystem_files(builddata): src_dir = builddata.environment.get_source_dir() filelist = find_buildsystem_files_list(src_dir) - print(json.dumps(filelist)) + return filelist def list_deps(coredata): result = [] @@ -475,7 +479,7 @@ def list_deps(coredata): result += [{'name': d.name, 'compile_args': d.get_compile_args(), 'link_args': d.get_link_args()}] - print(json.dumps(result)) + return result def list_tests(testdata): result = [] @@ -496,7 +500,7 @@ def list_tests(testdata): to['suite'] = t.suite to['is_parallel'] = t.is_parallel result.append(to) - print(json.dumps(result)) + return result def list_projinfo(builddata): result = {'version': builddata.project_version, @@ -508,7 +512,7 @@ def list_projinfo(builddata): 'descriptive_name': builddata.projects.get(k)} subprojects.append(c) result['subprojects'] = subprojects - print(json.dumps(result)) + return result class ProjectInfoInterperter(astinterpreter.AstInterpreter): def __init__(self, source_root, subdir): @@ -593,25 +597,38 @@ def run(options): except FileNotFoundError: installdata = None - if options.list_targets: - list_targets(coredata, builddata, installdata) - elif options.list_installed: - list_installed(installdata) - elif options.target_files is not None: - list_target_files(options.target_files, coredata, builddata) - elif options.buildsystem_files: - list_buildsystem_files(builddata) - elif options.buildoptions: - list_buildoptions(coredata) - elif options.tests: - list_tests(testdata) - elif options.benchmarks: - list_tests(benchmarkdata) - elif options.dependencies: - list_deps(coredata) - elif options.projectinfo: - list_projinfo(builddata) - else: + results = [] + + if options.all or options.list_targets: + results += [('targets', list_targets(coredata, builddata, installdata))] + if options.all or options.list_installed: + results += [('installed', list_installed(installdata))] + if options.target_files is not None: + results += [('target_files', list_target_files(options.target_files, coredata, builddata))] + if options.all or options.buildsystem_files: + results += [('buildsystem_files', list_buildsystem_files(builddata))] + if options.all or options.buildoptions: + results += [('buildoptions', list_buildoptions(coredata))] + if options.all or options.tests: + results += [('tests', list_tests(testdata))] + if options.all or options.benchmarks: + results += [('benchmarks', list_tests(benchmarkdata))] + if options.all or options.dependencies: + results += [('dependencies', list_deps(coredata))] + if options.all or options.projectinfo: + results += [('projectinfo', list_projinfo(builddata))] + + indent = options.indent if options.indent > 0 else None + + if len(results) == 0: print('No command specified') return 1 + elif len(results) == 1: + # Make to keep the existing output format for a single option + print(json.dumps(results[0][1], indent=indent)) + else: + out = {} + for i in results: + out[i[0]] = i[1] + print(json.dumps(out, indent=indent)) return 0 -- cgit v1.1 From a6034d1f198cd08a48026d2478c4e4539a3d9b36 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Mon, 26 Nov 2018 18:58:03 +0100 Subject: Added option to force use the new format --- mesonbuild/mintro.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 70f0f09..8d106c9 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -61,6 +61,8 @@ def add_arguments(parser): help='Print all available information.') parser.add_argument('-i', '--indent', dest='indent', type=int, default=0, help='Number of spaces used for indentation.') + parser.add_argument('-f', '--force-new', action='store_true', dest='force_new', default=False, + help='Always use the new JSON format for multiple entries (even for 0 and 1 introspection commands)') parser.add_argument('builddir', nargs='?', default='.', help='The build directory') def determine_installed_path(target, installdata): @@ -620,10 +622,10 @@ def run(options): indent = options.indent if options.indent > 0 else None - if len(results) == 0: + if len(results) == 0 and not options.force_new: print('No command specified') return 1 - elif len(results) == 1: + elif len(results) == 1 and not options.force_new: # Make to keep the existing output format for a single option print(json.dumps(results[0][1], indent=indent)) else: -- cgit v1.1 From f4285f350e1acf6ffe10a6dafff4028c0d142924 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Tue, 27 Nov 2018 13:35:28 +0100 Subject: Initial automatic target file generation --- mesonbuild/mintro.py | 64 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 17 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 8d106c9..2f8b3f3 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -36,6 +36,8 @@ import sys, os import pathlib import re +INTROSPECTION_OUTPUT_FILE = 'meson-introspection.json' + def add_arguments(parser): parser.add_argument('--targets', action='store_true', dest='list_targets', default=False, help='List top level targets.') @@ -95,7 +97,7 @@ def list_installed(installdata): res[path] = os.path.join(installdata.prefix, installdir, os.path.basename(path)) for path, installpath, unused_custom_install_mode in installdata.man: res[path] = os.path.join(installdata.prefix, installpath) - return res + return ('installed', res) def include_dirs_to_path(inc_dirs, src_root, build_root): result = [] @@ -241,7 +243,7 @@ def list_targets(coredata, builddata, installdata): t['installed'] = False t['build_by_default'] = target.build_by_default tlist.append(t) - return tlist + return ('targets', tlist) def list_target_files(target_name, coredata, builddata): try: @@ -255,7 +257,7 @@ def list_target_files(target_name, coredata, builddata): if isinstance(i, mesonlib.File): i = os.path.join(i.subdir, i.fname) out.append(i) - return out + return ('target_files', out) class BuildoptionsOptionHelper: # mimic an argparse namespace @@ -435,7 +437,7 @@ def list_buildoptions(coredata): add_keys(optlist, dir_options, 'directory') add_keys(optlist, coredata.user_options, 'user') add_keys(optlist, test_options, 'test') - return optlist + return ('buildoptions', optlist) def add_keys(optlist, options, section): keys = list(options.keys()) @@ -467,7 +469,7 @@ def find_buildsystem_files_list(src_dir): for f in files: if f == 'meson.build' or f == 'meson_options.txt': filelist.append(os.path.relpath(os.path.join(root, f), src_dir)) - return filelist + return ('buildsystem_files', filelist) def list_buildsystem_files(builddata): src_dir = builddata.environment.get_source_dir() @@ -481,9 +483,9 @@ def list_deps(coredata): result += [{'name': d.name, 'compile_args': d.get_compile_args(), 'link_args': d.get_link_args()}] - return result + return ('dependencies', result) -def list_tests(testdata): +def get_test_list(testdata): result = [] for t in testdata: to = {} @@ -504,6 +506,12 @@ def list_tests(testdata): result.append(to) return result +def list_tests(testdata): + return ('tests', get_test_list(testdata)) + +def list_benchmarks(benchdata): + return ('benchmarks', get_test_list(benchdata)) + def list_projinfo(builddata): result = {'version': builddata.project_version, 'descriptive_name': builddata.project_name} @@ -514,7 +522,7 @@ def list_projinfo(builddata): 'descriptive_name': builddata.projects.get(k)} subprojects.append(c) result['subprojects'] = subprojects - return result + return ('projectinfo', result) class ProjectInfoInterperter(astinterpreter.AstInterpreter): def __init__(self, source_root, subdir): @@ -602,23 +610,23 @@ def run(options): results = [] if options.all or options.list_targets: - results += [('targets', list_targets(coredata, builddata, installdata))] + results += [list_targets(coredata, builddata, installdata)] if options.all or options.list_installed: - results += [('installed', list_installed(installdata))] + results += [list_installed(installdata)] if options.target_files is not None: - results += [('target_files', list_target_files(options.target_files, coredata, builddata))] + results += [list_target_files(options.target_files, coredata, builddata)] if options.all or options.buildsystem_files: - results += [('buildsystem_files', list_buildsystem_files(builddata))] + results += [list_buildsystem_files(builddata)] if options.all or options.buildoptions: - results += [('buildoptions', list_buildoptions(coredata))] + results += [list_buildoptions(coredata)] if options.all or options.tests: - results += [('tests', list_tests(testdata))] + results += [list_tests(testdata)] if options.all or options.benchmarks: - results += [('benchmarks', list_tests(benchmarkdata))] + results += [list_benchmarks(benchmarkdata)] if options.all or options.dependencies: - results += [('dependencies', list_deps(coredata))] + results += [list_deps(coredata)] if options.all or options.projectinfo: - results += [('projectinfo', list_projinfo(builddata))] + results += [list_projinfo(builddata)] indent = options.indent if options.indent > 0 else None @@ -634,3 +642,25 @@ def run(options): out[i[0]] = i[1] print(json.dumps(out, indent=indent)) return 0 + +def generate_introspection_file(coredata, builddata, testdata, benchmarkdata, installdata): + intro_info = [ + #list_benchmarks(benchmarkdata), + list_buildoptions(coredata, builddata), + list_buildsystem_files(builddata), + list_deps(coredata), + list_installed(installdata), + list_projinfo(builddata), + list_targets(coredata, builddata, installdata), + #list_tests(testdata) + ] + + outdict = {} + for i in intro_info: + outdict[i[0]] = i[1] + + outfile = os.path.join(builddata.environment.get_build_dir(), INTROSPECTION_OUTPUT_FILE) + outfile = os.path.abspath(outfile) + + with open(outfile, 'w') as fp: + json.dump(outdict, fp, indent=2) -- cgit v1.1 From 111e596200ac613f9e50a05d60410604fdd0ca61 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Tue, 27 Nov 2018 15:11:47 +0100 Subject: Fixed tests and benchmarks --- mesonbuild/mintro.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 2f8b3f3..5ab1d1f 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -645,14 +645,14 @@ def run(options): def generate_introspection_file(coredata, builddata, testdata, benchmarkdata, installdata): intro_info = [ - #list_benchmarks(benchmarkdata), + list_benchmarks(benchmarkdata), list_buildoptions(coredata, builddata), list_buildsystem_files(builddata), list_deps(coredata), list_installed(installdata), list_projinfo(builddata), list_targets(coredata, builddata, installdata), - #list_tests(testdata) + list_tests(testdata) ] outdict = {} -- cgit v1.1 From b2854e9edc8da3d945b4e53f80afc4c9f7129fd4 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Tue, 27 Nov 2018 21:40:31 +0100 Subject: Fixed rebase error --- mesonbuild/mintro.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 5ab1d1f..4f0e928 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -469,12 +469,12 @@ def find_buildsystem_files_list(src_dir): for f in files: if f == 'meson.build' or f == 'meson_options.txt': filelist.append(os.path.relpath(os.path.join(root, f), src_dir)) - return ('buildsystem_files', filelist) + return filelist def list_buildsystem_files(builddata): src_dir = builddata.environment.get_source_dir() filelist = find_buildsystem_files_list(src_dir) - return filelist + return ('buildsystem_files', filelist) def list_deps(coredata): result = [] -- cgit v1.1 From 98eb7a48ab3de0122e8c5e8a188527d71a23a914 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Tue, 27 Nov 2018 22:27:34 +0100 Subject: Added unit test --- mesonbuild/mintro.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 4f0e928..d372112 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -663,4 +663,4 @@ def generate_introspection_file(coredata, builddata, testdata, benchmarkdata, in outfile = os.path.abspath(outfile) with open(outfile, 'w') as fp: - json.dump(outdict, fp, indent=2) + json.dump(outdict, fp) -- cgit v1.1 From a0d478da39dbab0ce265f5b4997ccf29baa87242 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Wed, 28 Nov 2018 12:28:35 +0100 Subject: More refactoring --- mesonbuild/mintro.py | 71 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 26 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index d372112..9af9c6c 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -245,6 +245,7 @@ def list_targets(coredata, builddata, installdata): tlist.append(t) return ('targets', tlist) +<<<<<<< HEAD def list_target_files(target_name, coredata, builddata): try: t = builddata.targets[target_name] @@ -405,6 +406,22 @@ def list_buildoptions_from_source(sourcedir, backend): # Reenable logging just in case mlog.enable() list_buildoptions(intr.coredata) +======= +def list_target_files(target_name, targets): + return ('error: TODO implement', []) + #try: + # t = builddata.targets[target_name] + # sources = t.sources + t.extra_files + #except KeyError: + # print("Unknown target %s." % target_name) + # sys.exit(1) + #out = [] + #for i in sources: + # if isinstance(i, mesonlib.File): + # i = os.path.join(i.subdir, i.fname) + # out.append(i) + #return ('target_files', out) +>>>>>>> More refactoring def list_buildoptions(coredata): optlist = [] @@ -581,8 +598,10 @@ def list_projinfo_from_source(sourcedir): def run(options): datadir = 'meson-private' + introfile = INTROSPECTION_OUTPUT_FILE if options.builddir is not None: datadir = os.path.join(options.builddir, datadir) + introfile = os.path.join(options.builddir, introfile) if options.builddir.endswith('/meson.build') or options.builddir.endswith('\\meson.build') or options.builddir == 'meson.build': sourcedir = '.' if options.builddir == 'meson.build' else options.builddir[:-11] if options.projectinfo: @@ -591,42 +610,42 @@ def run(options): if options.buildoptions: list_buildoptions_from_source(sourcedir, options.backend) return 0 - if not os.path.isdir(datadir): + if not os.path.isdir(datadir) or not os.path.isfile(introfile): print('Current directory is not a build dir. Please specify it or ' 'change the working directory to it.') return 1 - coredata = cdata.load(options.builddir) - builddata = build.load(options.builddir) - testdata = mtest.load_tests(options.builddir) - benchmarkdata = mtest.load_benchmarks(options.builddir) - - # Install data is only available with the Ninja backend - try: - installdata = ninjabackend.load(options.builddir) - except FileNotFoundError: - installdata = None + rawdata = {} + with open(introfile, 'r') as fp: + rawdata = json.load(fp) results = [] + toextract = [] - if options.all or options.list_targets: - results += [list_targets(coredata, builddata, installdata)] - if options.all or options.list_installed: - results += [list_installed(installdata)] - if options.target_files is not None: - results += [list_target_files(options.target_files, coredata, builddata)] - if options.all or options.buildsystem_files: - results += [list_buildsystem_files(builddata)] + if options.all or options.benchmarks: + toextract += ['benchmarks'] if options.all or options.buildoptions: + coredata = cdata.load(options.builddir) results += [list_buildoptions(coredata)] - if options.all or options.tests: - results += [list_tests(testdata)] - if options.all or options.benchmarks: - results += [list_benchmarks(benchmarkdata)] + if options.all or options.buildsystem_files: + toextract += ['buildsystem_files'] if options.all or options.dependencies: - results += [list_deps(coredata)] + toextract += ['dependencies'] + if options.all or options.list_installed: + toextract += ['installed'] if options.all or options.projectinfo: - results += [list_projinfo(builddata)] + toextract += ['projectinfo'] + if options.all or options.list_targets: + toextract += ['targets'] + if options.target_files is not None: + results += [list_target_files(options.target_files, rawdata['targets'])] + if options.all or options.tests: + toextract += ['tests'] + + for i in toextract: + if i not in rawdata: + raise RuntimeError('Key "{}" missing in introspection file. Please report this a bug.'.format(i)) + results += [(i, rawdata[i])] indent = options.indent if options.indent > 0 else None @@ -646,7 +665,7 @@ def run(options): def generate_introspection_file(coredata, builddata, testdata, benchmarkdata, installdata): intro_info = [ list_benchmarks(benchmarkdata), - list_buildoptions(coredata, builddata), + list_buildoptions(coredata), list_buildsystem_files(builddata), list_deps(coredata), list_installed(installdata), -- cgit v1.1 From 71d17b44e45c68b8d0b5189a8ebe8412ab99c622 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Wed, 28 Nov 2018 15:15:54 +0100 Subject: Fixed list_target_files and list_targets --- mesonbuild/mintro.py | 68 +++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 33 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 9af9c6c..b6c00ec 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -183,10 +183,12 @@ def list_targets(coredata, builddata, installdata): comp_list = target.compilers.values() source_list = target.sources + target.extra_files - source_list = list(map(lambda x: (mesonlib.get_compiler_for_source(comp_list, x), x), source_list)) + source_list = list(map(lambda x: (mesonlib.get_compiler_for_source(comp_list, x, True), x), source_list)) for comp, src in source_list: - if isinstance(comp, compilers.Compiler) and isinstance(src, mesonlib.File): + if isinstance(src, mesonlib.File): + src = os.path.join(src.subdir, src.fname) + if isinstance(comp, compilers.Compiler) and isinstance(src, str): lang = comp.get_language() if lang not in sources: parameters = [] @@ -208,7 +210,21 @@ def list_targets(coredata, builddata, installdata): 'source_files': [] } - sources[lang]['source_files'] += [os.path.join(src.subdir, src.fname)] + sources[lang]['source_files'] += [src] + elif comp is None and isinstance(src, str): + if 'unknown' not in sources: + sources['unknown'] = {'compiler': [], 'parameters': [], 'source_files': []} + sources['unknown']['source_files'] += [src] + elif isinstance(target, build.CustomTarget): + source_list_raw = target.sources + target.extra_files + source_list = [] + for i in source_list_raw: + if isinstance(i, mesonlib.File): + source_list += [os.path.join(i.subdir, i.fname)] + elif isinstance(i, str): + source_list += [i] + + sources['unknown'] = {'compiler': [], 'parameters': [], 'source_files': source_list} # Convert the dict to a list and add the language key. # This list approach will also work if the gurantee is removed that all @@ -245,21 +261,6 @@ def list_targets(coredata, builddata, installdata): tlist.append(t) return ('targets', tlist) -<<<<<<< HEAD -def list_target_files(target_name, coredata, builddata): - try: - t = builddata.targets[target_name] - sources = t.sources + t.extra_files - except KeyError: - print("Unknown target %s." % target_name) - sys.exit(1) - out = [] - for i in sources: - if isinstance(i, mesonlib.File): - i = os.path.join(i.subdir, i.fname) - out.append(i) - return ('target_files', out) - class BuildoptionsOptionHelper: # mimic an argparse namespace def __init__(self, cross_file): @@ -406,22 +407,23 @@ def list_buildoptions_from_source(sourcedir, backend): # Reenable logging just in case mlog.enable() list_buildoptions(intr.coredata) -======= + def list_target_files(target_name, targets): - return ('error: TODO implement', []) - #try: - # t = builddata.targets[target_name] - # sources = t.sources + t.extra_files - #except KeyError: - # print("Unknown target %s." % target_name) - # sys.exit(1) - #out = [] - #for i in sources: - # if isinstance(i, mesonlib.File): - # i = os.path.join(i.subdir, i.fname) - # out.append(i) - #return ('target_files', out) ->>>>>>> More refactoring + result = [] + tgt = None + + for i in targets: + if i['id'] == target_name: + tgt = i + break + + if tgt is None: + raise RuntimeError('Target with the ID "{}" could not be found'.format(target_name)) + + for i in tgt['sources']: + result += i['source_files'] + + return ('target_files', result) def list_buildoptions(coredata): optlist = [] -- cgit v1.1 From 74274e23ca42260e9be24c3cfaf7550c6c1505d2 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Wed, 28 Nov 2018 16:43:48 +0100 Subject: Moved the source and compiler generation to the backend --- mesonbuild/mintro.py | 148 ++++++--------------------------------------------- 1 file changed, 15 insertions(+), 133 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index b6c00ec..449220c 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -20,7 +20,7 @@ Currently only works for the Ninja backend. Others use generated project files and don't need this info.""" import json -from . import build, mtest, coredata as cdata +from . import build, coredata as cdata from . import environment from . import mesonlib from . import astinterpreter @@ -34,7 +34,6 @@ from .dependencies import base from .compilers import compilers import sys, os import pathlib -import re INTROSPECTION_OUTPUT_FILE = 'meson-introspection.json' @@ -99,138 +98,16 @@ def list_installed(installdata): res[path] = os.path.join(installdata.prefix, installpath) return ('installed', res) -def include_dirs_to_path(inc_dirs, src_root, build_root): - result = [] - if isinstance(inc_dirs, build.IncludeDirs): - for i in inc_dirs.get_incdirs(): - abs_src = os.path.join(src_root, inc_dirs.get_curdir(), i) - abs_build = os.path.join(build_root, inc_dirs.get_curdir(), i) - - if os.path.isdir(abs_src): - result += [abs_src] - - if os.path.isdir(abs_build): - result += [abs_build] - - return result - -def extract_dependency_infromation(dep): - inc_dirs = [] - args = [] - if isinstance(dep, base.Dependency): - reg = re.compile(r'-I(.*)') - for i in dep.get_compile_args(): - match = reg.match(i) - if match: - inc_dirs += [match.group(1)] - else: - args += [i] - - return inc_dirs, args - -def list_targets(coredata, builddata, installdata): +def list_targets(builddata: build.Build, installdata, backend: backends.Backend): tlist = [] for (idname, target) in builddata.get_targets().items(): if not isinstance(target, build.Target): raise RuntimeError('Something weird happened. File a bug.') - src_root = builddata.environment.get_source_dir() - build_root = builddata.environment.get_build_dir() - - inc_dirs = [] - extra_args = {} - dep_args = [] - sources = {} - - def climb_stack(tgt, inc_dirs, extra_args, dep_args): - if isinstance(tgt, build.BuildTarget): - # The build directory is always in the include directories - absbase_src = os.path.join(src_root, tgt.subdir) - absbase_build = os.path.join(build_root, tgt.subdir) - inc_dirs += [absbase_src, absbase_build] - - for i in tgt.include_dirs: - inc_dirs += include_dirs_to_path(i, src_root, build_root) - - for i in tgt.external_deps: - dep_inc_dirs, args = extract_dependency_infromation(i) - inc_dirs += dep_inc_dirs - dep_args += args - - for i, comp in tgt.compilers.items(): - if isinstance(comp, compilers.Compiler): - if i not in extra_args: - extra_args[i] = [] - - extra_args[i] += tgt.get_extra_args(i) - extra_args[i] += builddata.get_global_args(comp, tgt.is_cross) - extra_args[i] += builddata.get_project_args(comp, tgt.subproject, tgt.is_cross) - - for i in tgt.link_targets: - climb_stack(i, inc_dirs, extra_args, dep_args) - - if isinstance(target, build.BuildTarget): - climb_stack(target, inc_dirs, extra_args, dep_args) - - # Add the dep_args, sort and remove duplicates - for i in extra_args: - extra_args[i] += dep_args - extra_args[i] = list(sorted(list(set(extra_args[i])))) - - # Remove duplicates, sort and make paths pretty - inc_dirs = list(sorted(list(set(inc_dirs)))) - inc_dirs = list(map(lambda x: os.path.realpath(x), inc_dirs)) - - comp_list = target.compilers.values() - source_list = target.sources + target.extra_files - source_list = list(map(lambda x: (mesonlib.get_compiler_for_source(comp_list, x, True), x), source_list)) - - for comp, src in source_list: - if isinstance(src, mesonlib.File): - src = os.path.join(src.subdir, src.fname) - if isinstance(comp, compilers.Compiler) and isinstance(src, str): - lang = comp.get_language() - if lang not in sources: - parameters = [] - - # Generate include directories - # Not all compilers have the get_include_args method - get_include_args = getattr(comp, 'get_include_args', None) - if callable(get_include_args): - for i in inc_dirs: - parameters += comp.get_include_args(i, False) - - # Extra args - if lang in extra_args: - parameters += extra_args[lang] - - sources[lang] = { - 'compiler': comp.get_exelist(), - 'parameters': parameters, - 'source_files': [] - } - - sources[lang]['source_files'] += [src] - elif comp is None and isinstance(src, str): - if 'unknown' not in sources: - sources['unknown'] = {'compiler': [], 'parameters': [], 'source_files': []} - sources['unknown']['source_files'] += [src] - elif isinstance(target, build.CustomTarget): - source_list_raw = target.sources + target.extra_files - source_list = [] - for i in source_list_raw: - if isinstance(i, mesonlib.File): - source_list += [os.path.join(i.subdir, i.fname)] - elif isinstance(i, str): - source_list += [i] - - sources['unknown'] = {'compiler': [], 'parameters': [], 'source_files': source_list} - - # Convert the dict to a list and add the language key. - # This list approach will also work if the gurantee is removed that all - # files in a target are compiled with the same parameters - # see https://github.com/mesonbuild/meson/pull/4547 - sources = list(map(lambda x: {'language': x[0], **x[1]}, sources.items())) + if isinstance(backend, backends.Backend): + sources = backend.get_introspection_data(idname, target) + else: + raise RuntimeError('Parameter backend has an invalid type. This is a bug.') t = {'name': target.get_basename(), 'id': idname, 'sources': sources} fname = target.get_filename() @@ -490,7 +367,7 @@ def find_buildsystem_files_list(src_dir): filelist.append(os.path.relpath(os.path.join(root, f), src_dir)) return filelist -def list_buildsystem_files(builddata): +def list_buildsystem_files(builddata: build.Build): src_dir = builddata.environment.get_source_dir() filelist = find_buildsystem_files_list(src_dir) return ('buildsystem_files', filelist) @@ -531,7 +408,7 @@ def list_tests(testdata): def list_benchmarks(benchdata): return ('benchmarks', get_test_list(benchdata)) -def list_projinfo(builddata): +def list_projinfo(builddata: build.Build): result = {'version': builddata.project_version, 'descriptive_name': builddata.project_name} subprojects = [] @@ -664,7 +541,12 @@ def run(options): print(json.dumps(out, indent=indent)) return 0 -def generate_introspection_file(coredata, builddata, testdata, benchmarkdata, installdata): +def generate_introspection_file(builddata: build.Build, backend: backends.Backend): + coredata = builddata.environment.get_coredata() + benchmarkdata = backend.create_test_serialisation(builddata.get_benchmarks()) + testdata = backend.create_test_serialisation(builddata.get_tests()) + installdata = backend.create_install_data() + intro_info = [ list_benchmarks(benchmarkdata), list_buildoptions(coredata), @@ -672,7 +554,7 @@ def generate_introspection_file(coredata, builddata, testdata, benchmarkdata, in list_deps(coredata), list_installed(installdata), list_projinfo(builddata), - list_targets(coredata, builddata, installdata), + list_targets(builddata, installdata, backend), list_tests(testdata) ] -- cgit v1.1 From a5be893b19daf9e1f08eacc5d7f01389f6e40956 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Wed, 28 Nov 2018 19:40:16 +0100 Subject: Some code cleanup --- mesonbuild/mintro.py | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 449220c..6768070 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -104,37 +104,26 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend) if not isinstance(target, build.Target): raise RuntimeError('Something weird happened. File a bug.') - if isinstance(backend, backends.Backend): - sources = backend.get_introspection_data(idname, target) - else: - raise RuntimeError('Parameter backend has an invalid type. This is a bug.') - - t = {'name': target.get_basename(), 'id': idname, 'sources': sources} fname = target.get_filename() if isinstance(fname, list): fname = [os.path.join(target.subdir, x) for x in fname] else: fname = os.path.join(target.subdir, fname) - t['filename'] = fname - if isinstance(target, build.Executable): - typename = 'executable' - elif isinstance(target, build.SharedLibrary): - typename = 'shared library' - elif isinstance(target, build.StaticLibrary): - typename = 'static library' - elif isinstance(target, build.CustomTarget): - typename = 'custom' - elif isinstance(target, build.RunTarget): - typename = 'run' - else: - typename = 'unknown' - t['type'] = typename + + t = { + 'name': target.get_basename(), + 'id': idname, + 'type': target.get_typename(), + 'filename': fname, + 'build_by_default': target.build_by_default, + 'sources': backend.get_introspection_data(idname, target) + } + if installdata and target.should_install(): t['installed'] = True t['install_filename'] = determine_installed_path(target, installdata) else: t['installed'] = False - t['build_by_default'] = target.build_by_default tlist.append(t) return ('targets', tlist) -- cgit v1.1 From 4addd176dbf3eca01f5b3058e48f502c69268cbd Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Wed, 28 Nov 2018 22:47:53 +0100 Subject: Removed fallback detection logic --- mesonbuild/mintro.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 6768070..97a7c94 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -100,6 +100,13 @@ def list_installed(installdata): def list_targets(builddata: build.Build, installdata, backend: backends.Backend): tlist = [] + + # Fast lookup table for installation files + intall_lookuptable = {} + for i in installdata.targets: + outname = os.path.join(installdata.prefix, i.outdir, os.path.basename(i.fname)) + intall_lookuptable[os.path.basename(i.fname)] = str(pathlib.PurePath(outname)) + for (idname, target) in builddata.get_targets().items(): if not isinstance(target, build.Target): raise RuntimeError('Something weird happened. File a bug.') @@ -121,7 +128,12 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend) if installdata and target.should_install(): t['installed'] = True - t['install_filename'] = determine_installed_path(target, installdata) + t['install_filename'] = [] + + for i in target.outputs: + fname = intall_lookuptable.get(i) + if i is not None: + t['install_filename'] += [fname] else: t['installed'] = False tlist.append(t) -- cgit v1.1 From 24d668bea06b3b953855fa12ef2f5b417d4dd163 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Wed, 28 Nov 2018 23:05:40 +0100 Subject: Removed determine_installed_path since it is no longer needed --- mesonbuild/mintro.py | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 97a7c94..326cd6c 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -66,24 +66,6 @@ def add_arguments(parser): help='Always use the new JSON format for multiple entries (even for 0 and 1 introspection commands)') parser.add_argument('builddir', nargs='?', default='.', help='The build directory') -def determine_installed_path(target, installdata): - install_targets = [] - for i in target.outputs: - for j in installdata.targets: - if os.path.basename(j.fname) == i: # FIXME, might clash due to subprojects. - install_targets += [j] - break - if len(install_targets) == 0: - raise RuntimeError('Something weird happened. File a bug.') - - # Normalize the path by using os.path.sep consistently, etc. - # Does not change the effective path. - install_targets = list(map(lambda x: os.path.join(installdata.prefix, x.outdir, os.path.basename(x.fname)), install_targets)) - install_targets = list(map(lambda x: str(pathlib.PurePath(x)), install_targets)) - - return install_targets - - def list_installed(installdata): res = {} if installdata is not None: @@ -132,7 +114,7 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend) for i in target.outputs: fname = intall_lookuptable.get(i) - if i is not None: + if fname is not None: t['install_filename'] += [fname] else: t['installed'] = False -- cgit v1.1 From b91c5aad854bff3a13c27aa1a6ade85ded216207 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Thu, 29 Nov 2018 14:21:07 +0100 Subject: Update intro dump on meson configure --- mesonbuild/mintro.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 326cd6c..04850c6 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -487,8 +487,7 @@ def run(options): if options.all or options.benchmarks: toextract += ['benchmarks'] if options.all or options.buildoptions: - coredata = cdata.load(options.builddir) - results += [list_buildoptions(coredata)] + toextract += ['buildoptions'] if options.all or options.buildsystem_files: toextract += ['buildsystem_files'] if options.all or options.dependencies: @@ -550,3 +549,20 @@ def generate_introspection_file(builddata: build.Build, backend: backends.Backen with open(outfile, 'w') as fp: json.dump(outdict, fp) + +def update_build_options(coredata, builddir): + outfile = os.path.join(builddir, INTROSPECTION_OUTPUT_FILE) + outfile = os.path.abspath(outfile) + + with open(outfile, 'r') as fp: + outdict = json.load(fp) + + intro_info = [ + list_buildoptions(coredata) + ] + + for i in intro_info: + outdict[i[0]] = i[1] + + with open(outfile, 'w') as fp: + json.dump(outdict, fp) -- cgit v1.1 From b034f52656c19f378fc144abd9087e7526b1e27f Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Thu, 29 Nov 2018 14:53:28 +0100 Subject: Filenames are now lists --- mesonbuild/mintro.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 04850c6..cf1aeff 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -93,11 +93,7 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend) if not isinstance(target, build.Target): raise RuntimeError('Something weird happened. File a bug.') - fname = target.get_filename() - if isinstance(fname, list): - fname = [os.path.join(target.subdir, x) for x in fname] - else: - fname = os.path.join(target.subdir, fname) + fname = [os.path.join(target.subdir, x) for x in target.get_outputs()] t = { 'name': target.get_basename(), -- cgit v1.1 From b11df88395a6543ab1ea9354050f0b885959854a Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Thu, 29 Nov 2018 16:19:01 +0100 Subject: Documentation and unit test update --- mesonbuild/mintro.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index cf1aeff..5643b1a 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -106,12 +106,7 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend) if installdata and target.should_install(): t['installed'] = True - t['install_filename'] = [] - - for i in target.outputs: - fname = intall_lookuptable.get(i) - if fname is not None: - t['install_filename'] += [fname] + t['install_filename'] = [intall_lookuptable.get(x, None) for x in target.get_outputs()] else: t['installed'] = False tlist.append(t) -- cgit v1.1 From d4ac832bf695f3c6b00c976d3706159b3616ec2f Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 2 Dec 2018 18:14:44 +0100 Subject: Split the monolithic introspection file into chunks --- mesonbuild/mintro.py | 58 ++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 34 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 5643b1a..e10b95b 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -276,7 +276,7 @@ def list_target_files(target_name, targets): return ('target_files', result) -def list_buildoptions(coredata): +def list_buildoptions(coredata: cdata.CoreData): optlist = [] dir_option_names = ['bindir', @@ -346,7 +346,7 @@ def list_buildsystem_files(builddata: build.Build): filelist = find_buildsystem_files_list(src_dir) return ('buildsystem_files', filelist) -def list_deps(coredata): +def list_deps(coredata: cdata.CoreData): result = [] for d in coredata.deps.values(): if d.found(): @@ -451,10 +451,10 @@ def list_projinfo_from_source(sourcedir): def run(options): datadir = 'meson-private' - introfile = INTROSPECTION_OUTPUT_FILE + infodir = 'meson-info' if options.builddir is not None: datadir = os.path.join(options.builddir, datadir) - introfile = os.path.join(options.builddir, introfile) + infodir = os.path.join(options.builddir, infodir) if options.builddir.endswith('/meson.build') or options.builddir.endswith('\\meson.build') or options.builddir == 'meson.build': sourcedir = '.' if options.builddir == 'meson.build' else options.builddir[:-11] if options.projectinfo: @@ -463,15 +463,11 @@ def run(options): if options.buildoptions: list_buildoptions_from_source(sourcedir, options.backend) return 0 - if not os.path.isdir(datadir) or not os.path.isfile(introfile): + if not os.path.isdir(datadir) or not os.path.isdir(infodir): print('Current directory is not a build dir. Please specify it or ' 'change the working directory to it.') return 1 - rawdata = {} - with open(introfile, 'r') as fp: - rawdata = json.load(fp) - results = [] toextract = [] @@ -490,14 +486,20 @@ def run(options): if options.all or options.list_targets: toextract += ['targets'] if options.target_files is not None: - results += [list_target_files(options.target_files, rawdata['targets'])] + targets_file = os.path.join(infodir, 'intro-targets.json') + with open(targets_file, 'r') as fp: + targets = json.load(fp) + results += [list_target_files(options.target_files, targets)] if options.all or options.tests: toextract += ['tests'] for i in toextract: - if i not in rawdata: - raise RuntimeError('Key "{}" missing in introspection file. Please report this a bug.'.format(i)) - results += [(i, rawdata[i])] + curr = os.path.join(infodir, 'intro-{}.json'.format(i)) + if not os.path.isfile(curr): + print('Introspection file {} does not exist.'.format(curr)) + return 1 + with open(curr, 'r') as fp: + results += [(i, json.load(fp))] indent = options.indent if options.indent > 0 else None @@ -514,6 +516,12 @@ def run(options): print(json.dumps(out, indent=indent)) return 0 +def write_intro_info(intro_info, info_dir): + for i in intro_info: + out_file = os.path.join(info_dir, 'intro-{}.json'.format(i[0])) + with open(out_file, 'w') as fp: + json.dump(i[1], fp) + def generate_introspection_file(builddata: build.Build, backend: backends.Backend): coredata = builddata.environment.get_coredata() benchmarkdata = backend.create_test_serialisation(builddata.get_benchmarks()) @@ -531,29 +539,11 @@ def generate_introspection_file(builddata: build.Build, backend: backends.Backen list_tests(testdata) ] - outdict = {} - for i in intro_info: - outdict[i[0]] = i[1] - - outfile = os.path.join(builddata.environment.get_build_dir(), INTROSPECTION_OUTPUT_FILE) - outfile = os.path.abspath(outfile) - - with open(outfile, 'w') as fp: - json.dump(outdict, fp) - -def update_build_options(coredata, builddir): - outfile = os.path.join(builddir, INTROSPECTION_OUTPUT_FILE) - outfile = os.path.abspath(outfile) - - with open(outfile, 'r') as fp: - outdict = json.load(fp) + write_intro_info(intro_info, builddata.environment.info_dir) +def update_build_options(coredata: cdata.CoreData, info_dir): intro_info = [ list_buildoptions(coredata) ] - for i in intro_info: - outdict[i[0]] = i[1] - - with open(outfile, 'w') as fp: - json.dump(outdict, fp) + write_intro_info(intro_info, info_dir) -- cgit v1.1 From 7691b0460c53478cfc2e11fca156557add6579bf Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Tue, 11 Dec 2018 17:50:38 +0100 Subject: Ninja backend target introspection --- mesonbuild/mintro.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index e10b95b..9372ed8 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -272,7 +272,7 @@ def list_target_files(target_name, targets): raise RuntimeError('Target with the ID "{}" could not be found'.format(target_name)) for i in tgt['sources']: - result += i['source_files'] + result += i['sources'] + i['generated_sources'] return ('target_files', result) -- cgit v1.1 From 2e81631d0c892d4842412c5244d9374b390f3787 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 30 Dec 2018 10:59:58 +0100 Subject: Keep 'filename' and 'install_filename' as strings --- mesonbuild/mintro.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 9372ed8..4de16ca 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -99,14 +99,15 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend) 'name': target.get_basename(), 'id': idname, 'type': target.get_typename(), - 'filename': fname, + 'filename': fname[0], # TODO Change this to the full list in a seperate PR 'build_by_default': target.build_by_default, 'sources': backend.get_introspection_data(idname, target) } if installdata and target.should_install(): t['installed'] = True - t['install_filename'] = [intall_lookuptable.get(x, None) for x in target.get_outputs()] + # TODO Change this to the full list in a seperate PR + t['install_filename'] = [intall_lookuptable.get(x, None) for x in target.get_outputs()][0] else: t['installed'] = False tlist.append(t) -- cgit v1.1 From 84948ea6cd61c54404d6e0df82594a56e19fe01f Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 30 Dec 2018 11:37:50 +0100 Subject: Renamed `--force-new` to `--force-dict-output` --- mesonbuild/mintro.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 4de16ca..4a20e6b 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -62,7 +62,7 @@ def add_arguments(parser): help='Print all available information.') parser.add_argument('-i', '--indent', dest='indent', type=int, default=0, help='Number of spaces used for indentation.') - parser.add_argument('-f', '--force-new', action='store_true', dest='force_new', default=False, + parser.add_argument('-f', '--force-dict-output', action='store_true', dest='force_dict', default=False, help='Always use the new JSON format for multiple entries (even for 0 and 1 introspection commands)') parser.add_argument('builddir', nargs='?', default='.', help='The build directory') @@ -504,10 +504,10 @@ def run(options): indent = options.indent if options.indent > 0 else None - if len(results) == 0 and not options.force_new: + if len(results) == 0 and not options.force_dict: print('No command specified') return 1 - elif len(results) == 1 and not options.force_new: + elif len(results) == 1 and not options.force_dict: # Make to keep the existing output format for a single option print(json.dumps(results[0][1], indent=indent)) else: -- cgit v1.1 From 35887861388eb7d84998bc27b8b3531ae124c648 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 30 Dec 2018 11:51:32 +0100 Subject: Some small fixes --- mesonbuild/mintro.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 4a20e6b..9444b96 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -84,14 +84,14 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend) tlist = [] # Fast lookup table for installation files - intall_lookuptable = {} + install_lookuptable = {} for i in installdata.targets: outname = os.path.join(installdata.prefix, i.outdir, os.path.basename(i.fname)) - intall_lookuptable[os.path.basename(i.fname)] = str(pathlib.PurePath(outname)) + install_lookuptable[os.path.basename(i.fname)] = str(pathlib.PurePath(outname)) for (idname, target) in builddata.get_targets().items(): if not isinstance(target, build.Target): - raise RuntimeError('Something weird happened. File a bug.') + raise RuntimeError('The target object in `builddata.get_targets()` is not of type `build.Target`. Please file a bug with this error message.') fname = [os.path.join(target.subdir, x) for x in target.get_outputs()] @@ -107,7 +107,7 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend) if installdata and target.should_install(): t['installed'] = True # TODO Change this to the full list in a seperate PR - t['install_filename'] = [intall_lookuptable.get(x, None) for x in target.get_outputs()][0] + t['install_filename'] = [install_lookuptable.get(x, None) for x in target.get_outputs()][0] else: t['installed'] = False tlist.append(t) -- cgit v1.1 From c33df1fd7377ed6f2116c61b19cac1825ae68f86 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 30 Dec 2018 12:25:37 +0100 Subject: Revert to old behavior --- mesonbuild/mintro.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 9444b96..fa92a1a 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -93,13 +93,16 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend) if not isinstance(target, build.Target): raise RuntimeError('The target object in `builddata.get_targets()` is not of type `build.Target`. Please file a bug with this error message.') + # TODO Change this to the full list in a seperate PR fname = [os.path.join(target.subdir, x) for x in target.get_outputs()] + if len(fname) == 1: + fname = fname[0] t = { 'name': target.get_basename(), 'id': idname, 'type': target.get_typename(), - 'filename': fname[0], # TODO Change this to the full list in a seperate PR + 'filename': fname, 'build_by_default': target.build_by_default, 'sources': backend.get_introspection_data(idname, target) } @@ -260,7 +263,7 @@ def list_buildoptions_from_source(sourcedir, backend): mlog.enable() list_buildoptions(intr.coredata) -def list_target_files(target_name, targets): +def list_target_files(target_name, targets, builddata: build.Build): result = [] tgt = None @@ -270,11 +273,15 @@ def list_target_files(target_name, targets): break if tgt is None: - raise RuntimeError('Target with the ID "{}" could not be found'.format(target_name)) + print('Target with the ID "{}" could not be found'.format(target_name)) + sys.exit(1) for i in tgt['sources']: result += i['sources'] + i['generated_sources'] + # TODO Remove this line in a future PR with other breaking changes + result = list(map(lambda x: os.path.relpath(x, builddata.environment.get_source_dir()), result)) + return ('target_files', result) def list_buildoptions(coredata: cdata.CoreData): @@ -490,7 +497,8 @@ def run(options): targets_file = os.path.join(infodir, 'intro-targets.json') with open(targets_file, 'r') as fp: targets = json.load(fp) - results += [list_target_files(options.target_files, targets)] + builddata = build.load(options.builddir) # TODO remove this in a breaking changes PR + results += [list_target_files(options.target_files, targets, builddata)] if options.all or options.tests: toextract += ['tests'] -- cgit v1.1 From 02734cc5c34faabe8ec0685139451f8349469993 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 30 Dec 2018 12:38:55 +0100 Subject: Better documentation --- mesonbuild/mintro.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index fa92a1a..ce9d81e 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -472,8 +472,10 @@ def run(options): list_buildoptions_from_source(sourcedir, options.backend) return 0 if not os.path.isdir(datadir) or not os.path.isdir(infodir): - print('Current directory is not a build dir. Please specify it or ' - 'change the working directory to it.') + print('Current directory is not a meson build directory.' + 'Please specify a valid build dir or change the working directory to it.' + 'It is also possible that the build directory was generated with an old' + 'meson version. Please regenerate it in this case.') return 1 results = [] -- cgit v1.1 From e1719c5d37c82233c27ae733ab9b1ecbb781a27f Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 30 Dec 2018 14:31:04 +0100 Subject: Load coredata --- mesonbuild/mintro.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index ce9d81e..caa6982 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -478,6 +478,10 @@ def run(options): 'meson version. Please regenerate it in this case.') return 1 + # Load build data to make sure that the version matches + # TODO Find a better solution for this + _ = cdata.load(options.builddir) + results = [] toextract = [] -- cgit v1.1 From 63e16fbcc31ed616b713bf83b4b1079ee1b7f617 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 30 Dec 2018 14:34:53 +0100 Subject: Fixed flake8 --- mesonbuild/mintro.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index caa6982..63cf7fb 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -480,7 +480,7 @@ def run(options): # Load build data to make sure that the version matches # TODO Find a better solution for this - _ = cdata.load(options.builddir) + cdata.load(options.builddir) results = [] toextract = [] -- cgit v1.1 From bd8bad46c3fad6e53e259f73408a73eeca920dc7 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 30 Dec 2018 23:04:59 +0100 Subject: Code cleanup and renamed variables --- mesonbuild/mintro.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 63cf7fb..cba10f3 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -35,8 +35,6 @@ from .compilers import compilers import sys, os import pathlib -INTROSPECTION_OUTPUT_FILE = 'meson-introspection.json' - def add_arguments(parser): parser.add_argument('--targets', action='store_true', dest='list_targets', default=False, help='List top level targets.') @@ -62,7 +60,7 @@ def add_arguments(parser): help='Print all available information.') parser.add_argument('-i', '--indent', dest='indent', type=int, default=0, help='Number of spaces used for indentation.') - parser.add_argument('-f', '--force-dict-output', action='store_true', dest='force_dict', default=False, + parser.add_argument('-f', '--force-object-output', action='store_true', dest='force_dict', default=False, help='Always use the new JSON format for multiple entries (even for 0 and 1 introspection commands)') parser.add_argument('builddir', nargs='?', default='.', help='The build directory') @@ -104,7 +102,7 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend) 'type': target.get_typename(), 'filename': fname, 'build_by_default': target.build_by_default, - 'sources': backend.get_introspection_data(idname, target) + 'target_sources': backend.get_introspection_data(idname, target) } if installdata and target.should_install(): @@ -276,7 +274,7 @@ def list_target_files(target_name, targets, builddata: build.Build): print('Target with the ID "{}" could not be found'.format(target_name)) sys.exit(1) - for i in tgt['sources']: + for i in tgt['target_sources']: result += i['sources'] + i['generated_sources'] # TODO Remove this line in a future PR with other breaking changes -- cgit v1.1 From 25618c6a4dd8e2c05d0e19ee19f4e6a5e735ef0c Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Mon, 31 Dec 2018 14:27:20 +0100 Subject: Atomic write --- mesonbuild/mintro.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index cba10f3..e6782cb 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -532,8 +532,11 @@ def run(options): def write_intro_info(intro_info, info_dir): for i in intro_info: out_file = os.path.join(info_dir, 'intro-{}.json'.format(i[0])) - with open(out_file, 'w') as fp: + tmp_file = os.path.join(info_dir, 'tmp_dump.json') + with open(tmp_file, 'w') as fp: json.dump(i[1], fp) + fp.flush() # Not sure if this is needed + os.replace(tmp_file, out_file) def generate_introspection_file(builddata: build.Build, backend: backends.Backend): coredata = builddata.environment.get_coredata() -- cgit v1.1 From 9c214f4a70cc82340257b39b9bbfe45b2f4c0c8f Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Tue, 1 Jan 2019 18:57:07 +0100 Subject: Fixed buildoptions form source --- mesonbuild/mintro.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index e6782cb..6f2cdf6 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -251,7 +251,7 @@ class BuildoptionsInterperter(astinterpreter.AstInterpreter): self.parse_project() self.run() -def list_buildoptions_from_source(sourcedir, backend): +def list_buildoptions_from_source(sourcedir, backend, indent): # Make sure that log entries in other parts of meson don't interfere with the JSON output mlog.disable() backend = backends.get_backend_from_name(backend, None) @@ -259,7 +259,8 @@ def list_buildoptions_from_source(sourcedir, backend): intr.analyze() # Reenable logging just in case mlog.enable() - list_buildoptions(intr.coredata) + buildoptions = list_buildoptions(intr.coredata)[1] + print(json.dumps(buildoptions, indent=indent)) def list_target_files(target_name, targets, builddata: build.Build): result = [] @@ -424,7 +425,7 @@ class ProjectInfoInterperter(astinterpreter.AstInterpreter): self.parse_project() self.run() -def list_projinfo_from_source(sourcedir): +def list_projinfo_from_source(sourcedir, indent): files = find_buildsystem_files_list(sourcedir) result = {'buildsystem_files': []} @@ -453,21 +454,22 @@ def list_projinfo_from_source(sourcedir): subprojects = [obj for name, obj in subprojects.items()] result['subprojects'] = subprojects - print(json.dumps(result)) + print(json.dumps(result, indent=indent)) def run(options): datadir = 'meson-private' infodir = 'meson-info' + indent = options.indent if options.indent > 0 else None if options.builddir is not None: datadir = os.path.join(options.builddir, datadir) infodir = os.path.join(options.builddir, infodir) if options.builddir.endswith('/meson.build') or options.builddir.endswith('\\meson.build') or options.builddir == 'meson.build': sourcedir = '.' if options.builddir == 'meson.build' else options.builddir[:-11] if options.projectinfo: - list_projinfo_from_source(sourcedir) + list_projinfo_from_source(sourcedir, indent) return 0 if options.buildoptions: - list_buildoptions_from_source(sourcedir, options.backend) + list_buildoptions_from_source(sourcedir, options.backend, indent) return 0 if not os.path.isdir(datadir) or not os.path.isdir(infodir): print('Current directory is not a meson build directory.' @@ -514,8 +516,6 @@ def run(options): with open(curr, 'r') as fp: results += [(i, json.load(fp))] - indent = options.indent if options.indent > 0 else None - if len(results) == 0 and not options.force_dict: print('No command specified') return 1 -- cgit v1.1 From aa6e3dc470010ac2586786610f3061aae70547ec Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Tue, 1 Jan 2019 19:16:23 +0100 Subject: Fixed flake8 issues --- mesonbuild/mintro.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 6f2cdf6..c0cefdb 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -29,9 +29,7 @@ from . import mlog from . import compilers from . import optinterpreter from .interpreterbase import InvalidArguments -from .backend import ninjabackend, backends -from .dependencies import base -from .compilers import compilers +from .backend import backends import sys, os import pathlib -- cgit v1.1 From bcb8146280ed89d1fabc3136e2e65a6173b31214 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Wed, 2 Jan 2019 21:58:04 +0100 Subject: Indent flag only toggles --- mesonbuild/mintro.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'mesonbuild/mintro.py') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index c0cefdb..3382e0d 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -56,8 +56,8 @@ def add_arguments(parser): help='The backend to use for the --buildoptions introspection.') parser.add_argument('-a', '--all', action='store_true', dest='all', default=False, help='Print all available information.') - parser.add_argument('-i', '--indent', dest='indent', type=int, default=0, - help='Number of spaces used for indentation.') + parser.add_argument('-i', '--indent', action='store_true', dest='indent', default=False, + help='Enable pretty printed JSON.') parser.add_argument('-f', '--force-object-output', action='store_true', dest='force_dict', default=False, help='Always use the new JSON format for multiple entries (even for 0 and 1 introspection commands)') parser.add_argument('builddir', nargs='?', default='.', help='The build directory') @@ -457,7 +457,7 @@ def list_projinfo_from_source(sourcedir, indent): def run(options): datadir = 'meson-private' infodir = 'meson-info' - indent = options.indent if options.indent > 0 else None + indent = 4 if options.indent else None if options.builddir is not None: datadir = os.path.join(options.builddir, datadir) infodir = os.path.join(options.builddir, infodir) -- cgit v1.1