Project

General

Profile

#!/usr/bin/env python3

# Copyright 2014-2015 Open Source Robotics Foundation, Inc.
#
# 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.

import argparse
from collections import OrderedDict
import sys

from catkin_pkg.package import parse_package_string


def main(argv=sys.argv[1:]):
"""
Extract the information from package.xml and make them accessible to CMake.

Parse the given package.xml file and
print CMake code defining several variables containing the content.
"""
parser = argparse.ArgumentParser(
description='Parse package.xml file and print CMake code defining '
'several variables',
)
parser.add_argument(
'package_xml',
type=argparse.FileType('r', encoding='utf-8'),
help='The path to a package.xml file',
)
parser.add_argument(
'outfile',
nargs='?',
help='The filename where the output should be written to',
)
args = parser.parse_args(argv)

try:
package = parse_package_string(
args.package_xml.read(), filename=args.package_xml.name)
except Exception as e:
print("Error parsing '%s':" % args.package_xml.name, file=sys.stderr)
raise e
finally:
args.package_xml.close()

lines = generate_cmake_code(package)
if args.outfile:
with open(args.outfile, 'w', encoding='utf-8') as f:
for line in lines:
f.write('%s\n' % line)
else:
for line in lines:
print(line)


def get_dependency_values(key, depends):
dependencies = []
dependencies.append((key, ' '.join(['"%s"' % str(d) for d in depends])))
for d in depends:
comparisons = [
'version_lt',
'version_lte',
'version_eq',
'version_gte',
'version_gt']
for comp in comparisons:
value = getattr(d, comp, None)
if value is not None:
dependencies.append(('%s_%s_%s' % (key, str(d), comp.upper()),
'"%s"' % value))
return dependencies


def generate_cmake_code(package):
"""
Return a list of CMake set() commands containing the manifest information.

:param package: catkin_pkg.package.Package
:returns: list of str
"""
variables = []
variables.append(('VERSION', '"%s"' % package.version))

variables.append((
'MAINTAINER',
'"%s"' % (', '.join([str(m) for m in package.maintainers]))))

variables.extend(get_dependency_values('BUILD_DEPENDS',
package.build_depends))
variables.extend(get_dependency_values('BUILDTOOL_DEPENDS',
package.buildtool_depends))
variables.extend(get_dependency_values('BUILD_EXPORT_DEPENDS',
package.build_export_depends))
variables.extend(get_dependency_values('BUILDTOOL_EXPORT_DEPENDS',
package.buildtool_export_depends))
variables.extend(get_dependency_values('EXEC_DEPENDS',
package.exec_depends))
variables.extend(get_dependency_values('TEST_DEPENDS',
package.test_depends))
variables.extend(get_dependency_values('GROUP_DEPENDS',
package.group_depends))
variables.extend(get_dependency_values('MEMBER_OF_GROUPS',
package.member_of_groups))

deprecated = [e.content for e in package.exports
if e.tagname == 'deprecated']
variables.append(('DEPRECATED',
'"%s"' % ((deprecated[0] if deprecated[0] else 'TRUE')
if deprecated
else '')))

lines = []
lines.append('set(_AMENT_PACKAGE_NAME "%s")' % package.name)
for (k, v) in variables:
lines.append('set(%s_%s %s)' % (package.name, k, v))

lines.append('set(%s_EXPORT_TAGS)' % package.name)
replaces = OrderedDict()
replaces['${prefix}/'] = ''
replaces['\\'] = '\\\\' # escape backslashes
replaces['"'] = '\\"' # prevent double quotes to end the CMake string
replaces[';'] = '\\;' # prevent semicolons to be interpreted as list separators
for export in package.exports:
export = str(export)
for k, v in replaces.items():
export = export.replace(k, v)
lines.append('list(APPEND %s_EXPORT_TAGS "%s")' % (package.name, export))

return lines


if __name__ == '__main__':
main()
(13-13/19)