|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
# Copyright 2017 Niklas Claesson
|
|
|
|
|
|
|
|
# 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 two implementations for how to get module names from the boost
|
|
|
|
sources. One relies on json metadata files in the sources, the other relies on
|
|
|
|
the folder names.
|
|
|
|
|
|
|
|
Run the tool in the boost directory and append the stdout to the misc.py:
|
|
|
|
|
|
|
|
boost/$ path/to/meson/tools/boost_names.py >> path/to/meson/dependencies/misc.py
|
|
|
|
"""
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
import collections
|
|
|
|
import pprint
|
|
|
|
import json
|
|
|
|
import re
|
|
|
|
|
|
|
|
Module = collections.namedtuple('Module', ['dirname', 'name', 'libnames'])
|
|
|
|
Module.__repr__ = lambda self: str((self.dirname, self.name, self.libnames)) # type: ignore
|
|
|
|
|
|
|
|
LIBS = 'libs'
|
|
|
|
|
|
|
|
manual_map = {
|
|
|
|
'callable_traits': 'Call Traits',
|
|
|
|
'crc': 'CRC',
|
|
|
|
'dll': 'DLL',
|
|
|
|
'gil': 'GIL',
|
|
|
|
'graph_parallel': 'GraphParallel',
|
|
|
|
'icl': 'ICL',
|
|
|
|
'io': 'IO State Savers',
|
|
|
|
'msm': 'Meta State Machine',
|
|
|
|
'mpi': 'MPI',
|
|
|
|
'mpl': 'MPL',
|
|
|
|
'multi_array': 'Multi-Array',
|
|
|
|
'multi_index': 'Multi-Index',
|
|
|
|
'numeric': 'Numeric Conversion',
|
|
|
|
'ptr_container': 'Pointer Container',
|
|
|
|
'poly_collection': 'PolyCollection',
|
|
|
|
'qvm': 'QVM',
|
|
|
|
'throw_exception': 'ThrowException',
|
|
|
|
'tti': 'TTI',
|
|
|
|
'vmd': 'VMD',
|
|
|
|
}
|
|
|
|
|
|
|
|
extra = [
|
|
|
|
Module('utility', 'Compressed Pair', []),
|
|
|
|
Module('core', 'Enable If', []),
|
|
|
|
Module('functional', 'Functional/Factory', []),
|
|
|
|
Module('functional', 'Functional/Forward', []),
|
|
|
|
Module('functional', 'Functional/Hash', []),
|
|
|
|
Module('functional', 'Functional/Overloaded Function', []),
|
|
|
|
Module('utility', 'Identity Type', []),
|
|
|
|
Module('utility', 'In Place Factory, Typed In Place Factory', []),
|
|
|
|
Module('numeric', 'Interval', []),
|
|
|
|
Module('math', 'Math Common Factor', []),
|
|
|
|
Module('math', 'Math Octonion', []),
|
|
|
|
Module('math', 'Math Quaternion', []),
|
|
|
|
Module('math', 'Math/Special Functions', []),
|
|
|
|
Module('math', 'Math/Statistical Distributions', []),
|
|
|
|
Module('bind', 'Member Function', []),
|
|
|
|
Module('algorithm', 'Min-Max', []),
|
|
|
|
Module('numeric', 'Odeint', []),
|
|
|
|
Module('utility', 'Operators', []),
|
|
|
|
Module('core', 'Ref', []),
|
|
|
|
Module('utility', 'Result Of', []),
|
|
|
|
Module('algorithm', 'String Algo', []),
|
|
|
|
Module('core', 'Swap', []),
|
|
|
|
Module('', 'Tribool', []),
|
|
|
|
Module('numeric', 'uBLAS', []),
|
|
|
|
Module('utility', 'Value Initialized', []),
|
|
|
|
]
|
|
|
|
|
|
|
|
# Cannot find the following modules in the documentation of boost
|
|
|
|
not_modules = ['beast', 'logic', 'mp11', 'winapi']
|
|
|
|
|
|
|
|
def eprint(message):
|
|
|
|
print(message, file=sys.stderr)
|
|
|
|
|
|
|
|
def get_library_names(jamfile):
|
|
|
|
libs = []
|
|
|
|
with open(jamfile) as jamfh:
|
|
|
|
jam = jamfh.read()
|
|
|
|
res = re.finditer(r'^lib[\s]+([A-Za-z0-9_]+)([^;]*);', jam, re.MULTILINE | re.DOTALL)
|
|
|
|
for matches in res:
|
|
|
|
if ':' in matches.group(2):
|
|
|
|
libs.append(matches.group(1))
|
|
|
|
res = re.finditer(r'^boost-lib[\s]+([A-Za-z0-9_]+)([^;]*);', jam, re.MULTILINE | re.DOTALL)
|
|
|
|
for matches in res:
|
|
|
|
if ':' in matches.group(2):
|
|
|
|
libs.append('boost_{}'.format(matches.group(1)))
|
|
|
|
return libs
|
|
|
|
|
|
|
|
def exists(modules, module):
|
|
|
|
return len([x for x in modules if x.dirname == module.dirname]) != 0
|
|
|
|
|
|
|
|
def get_modules(init=extra):
|
|
|
|
modules = init
|
|
|
|
for directory in os.listdir(LIBS):
|
|
|
|
if not os.path.isdir(os.path.join(LIBS, directory)):
|
|
|
|
continue
|
|
|
|
if directory in not_modules:
|
|
|
|
continue
|
|
|
|
jamfile = os.path.join(LIBS, directory, 'build', 'Jamfile.v2')
|
|
|
|
if os.path.isfile(jamfile):
|
|
|
|
libs = get_library_names(jamfile)
|
|
|
|
else:
|
|
|
|
libs = []
|
|
|
|
if directory in manual_map.keys():
|
|
|
|
modname = manual_map[directory]
|
|
|
|
else:
|
|
|
|
modname = directory.replace('_', ' ').title()
|
|
|
|
modules.append(Module(directory, modname, libs))
|
|
|
|
return modules
|
|
|
|
|
|
|
|
def get_modules_2():
|
|
|
|
modules = []
|
|
|
|
# The python module uses an older build system format and is not easily parseable.
|
|
|
|
# We add the python module libraries manually.
|
|
|
|
modules.append(Module('python', 'Python', ['boost_python', 'boost_python3', 'boost_numpy', 'boost_numpy3']))
|
|
|
|
for (root, _, files) in os.walk(LIBS):
|
|
|
|
for f in files:
|
|
|
|
if f == "libraries.json":
|
|
|
|
projectdir = os.path.dirname(root)
|
|
|
|
|
|
|
|
jamfile = os.path.join(projectdir, 'build', 'Jamfile.v2')
|
|
|
|
if os.path.isfile(jamfile):
|
|
|
|
libs = get_library_names(jamfile)
|
|
|
|
else:
|
|
|
|
libs = []
|
|
|
|
|
|
|
|
# Get metadata for module
|
|
|
|
jsonfile = os.path.join(root, f)
|
|
|
|
with open(jsonfile) as jsonfh:
|
|
|
|
boost_modules = json.loads(jsonfh.read())
|
|
|
|
if(isinstance(boost_modules, dict)):
|
|
|
|
boost_modules = [boost_modules]
|
|
|
|
for boost_module in boost_modules:
|
|
|
|
modules.append(Module(boost_module['key'], boost_module['name'], libs))
|
|
|
|
|
|
|
|
# Some subprojects do not have meta directory with json file. Find those
|
|
|
|
jsonless_modules = [x for x in get_modules([]) if not exists(modules, x)]
|
|
|
|
for module in jsonless_modules:
|
|
|
|
eprint("WARNING: {} does not have meta/libraries.json. Will guess pretty name '{}'".format(module.dirname, module.name))
|
|
|
|
modules.extend(jsonless_modules)
|
|
|
|
|
|
|
|
return modules
|
|
|
|
|
|
|
|
def main(args):
|
|
|
|
if not os.path.isdir(LIBS):
|
|
|
|
eprint("ERROR: script must be run in boost source directory")
|
|
|
|
|
|
|
|
# It will pick jsonless algorithm if 1 is given as argument
|
|
|
|
impl = 0
|
|
|
|
if len(args) > 1:
|
|
|
|
if args[1] == '1':
|
|
|
|
impl = 1
|
|
|
|
|
|
|
|
if impl == 1:
|
|
|
|
modules = get_modules()
|
|
|
|
else:
|
|
|
|
modules = get_modules_2()
|
|
|
|
|
|
|
|
sorted_modules = sorted(modules, key=lambda module: module.name.lower())
|
|
|
|
sorted_modules = [x[2] for x in sorted_modules if x[2]]
|
|
|
|
sorted_modules = sum(sorted_modules, [])
|
|
|
|
sorted_modules = [x for x in sorted_modules if x.startswith('boost')]
|
|
|
|
|
|
|
|
pp = pprint.PrettyPrinter()
|
|
|
|
pp.pprint(sorted_modules)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main(sys.argv)
|