| #!/usr/bin/env python3 |
| |
| # Copyright 2014 Jussi Pakkanen |
| |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """This is a helper script for IDE developers. It allows you to |
| extract information such as list of targets, files, compiler flags, |
| tests and so on. All output is in JSON for simple parsing. |
| |
| Currently only works for the Ninja backend. Others use generated |
| project files and don't need this info.""" |
| |
| import json, pickle |
| import coredata, build, optinterpreter |
| from optparse import OptionParser |
| import sys, os |
| |
| parser = OptionParser() |
| parser.add_option('--targets', action='store_true', dest='list_targets', default=False, |
| help='List top level targets.') |
| parser.add_option('--target-files', action='store', dest='target_files', default=None, |
| help='List source files for a given target.') |
| parser.add_option('--buildsystem-files', action='store_true', dest='buildsystem_files', default=False, |
| help='List files that make up the build system.') |
| parser.add_option('--buildoptions', action='store_true', dest='buildoptions', default=False, |
| help='List all build options.') |
| parser.add_option('--tests', action='store_true', dest='tests', default=False, |
| help='List all unit tests.') |
| |
| def list_targets(coredata, builddata): |
| tlist = [] |
| for target in builddata.get_targets().values(): |
| t = {} |
| t['name'] = target.get_basename() |
| t['filename'] = os.path.join(target.subdir, target.get_filename()) |
| 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 |
| if target.should_install(): |
| t['installed'] = True |
| else: |
| t['installed'] = False |
| tlist.append(t) |
| print(json.dumps(tlist)) |
| |
| def list_target_files(target_name, coredata, builddata): |
| try: |
| t = builddata.targets[target_name] |
| sources = t.sources + t.extra_files |
| subdir = t.subdir |
| except KeyError: |
| print("Unknown target %s." % target_name) |
| sys.exit(1) |
| sources = [os.path.join(subdir, i) for i in sources] |
| print(json.dumps(sources)) |
| |
| def list_buildoptions(coredata, builddata): |
| buildtype= {'choices': ['plain', 'debug', 'debugoptimized', 'release'], |
| 'type' : 'combo', |
| 'value' : coredata.buildtype, |
| 'description' : 'Build type', |
| 'name' : 'type'} |
| strip = {'value' : coredata.strip, |
| 'type' : 'boolean', |
| 'description' : 'Strip on install', |
| 'name' : 'strip'} |
| coverage = {'value': coredata.coverage, |
| 'type' : 'boolean', |
| 'description' : 'Enable coverage', |
| 'name' : 'coverage'} |
| pch = {'value' : coredata.use_pch, |
| 'type' : 'boolean', |
| 'description' : 'Use precompiled headers', |
| 'name' : 'pch'} |
| unity = {'value' : coredata.unity, |
| 'type' : 'boolean', |
| 'description' : 'Unity build', |
| 'name' : 'unity'} |
| optlist = [buildtype, strip, coverage, pch, unity] |
| options = coredata.user_options |
| keys = list(options.keys()) |
| keys.sort() |
| for key in keys: |
| opt = options[key] |
| optdict = {} |
| optdict['name'] = key |
| optdict['value'] = opt.value |
| if isinstance(opt, optinterpreter.UserStringOption): |
| typestr = 'string' |
| elif isinstance(opt, optinterpreter.UserBooleanOption): |
| typestr = 'boolean' |
| elif isinstance(opt, optinterpreter.UserComboOption): |
| optdict['choices'] = opt.choices |
| typestr = 'combo' |
| else: |
| raise RuntimeError("Unknown option type") |
| optdict['type'] = typestr |
| optdict['description'] = opt.description |
| optlist.append(optdict) |
| print(json.dumps(optlist)) |
| |
| def list_buildsystem_files(coredata, builddata): |
| src_dir = builddata.environment.get_source_dir() |
| # I feel dirty about this. But only slightly. |
| filelist = [] |
| for root, _, files in os.walk(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)) |
| print(json.dumps(filelist)) |
| |
| def list_tests(testdata): |
| result = [] |
| for t in testdata: |
| to = {} |
| to['cmd'] = [t.fname] + t.cmd_args |
| to['env'] = t.env |
| to['name'] = t.name |
| result.append(to) |
| print(json.dumps(result)) |
| |
| if __name__ == '__main__': |
| (options, args) = parser.parse_args() |
| if len(args) > 1: |
| print('Too many arguments') |
| sys.exit(1) |
| elif len(args) == 1: |
| bdir = args[0] |
| else: |
| bdir = '' |
| corefile = os.path.join(bdir, 'meson-private/coredata.dat') |
| buildfile = os.path.join(bdir, 'meson-private/build.dat') |
| testfile = os.path.join(bdir, 'meson-private/meson_test_setup.dat') |
| coredata = pickle.load(open(corefile, 'rb')) |
| builddata = pickle.load(open(buildfile, 'rb')) |
| testdata = pickle.load(open(testfile, 'rb')) |
| if options.list_targets: |
| list_targets(coredata, builddata) |
| elif options.target_files is not None: |
| list_target_files(options.target_files, coredata, builddata) |
| elif options.buildsystem_files: |
| list_buildsystem_files(coredata, builddata) |
| elif options.buildoptions: |
| list_buildoptions(coredata, builddata) |
| elif options.tests: |
| list_tests(testdata) |
| else: |
| print('No command specified') |
| sys.exit(1) |