diff --git a/lib/recipetool/README.md b/lib/recipetool/README.md
deleted file mode 100644
index b13f911..0000000
--- a/lib/recipetool/README.md
+++ /dev/null
@@ -1,51 +0,0 @@
-Extension to recipetool to enable automatic creation of
-BitBake recipe files for ROS packages.
-
-## REQUIREMENTS ##
-
-Two changes to the recipetool are required to use this plugin:
-
-Requires either:
- From OE-Core rev: 1df60b09f7a60427795ec828c9c7180e4e52f98c
- From OE-Core rev: 3bb979c13463705c4db6c59034661c4cd8100756
-or
- From poky rev: b1f237ebd0d4180c5d23a0ecd9aaf7193c63a48a
- From poky rev: a7baa47c876c7895499909731aaa451c6009610a
-
-These changes are currently in the master branch as of 2017-Aug-24.
-
-
-## USAGE ##
-
- Initialize the build environment:
-
- source oe-init-build-env
-
- Currently the plugin only allow for processing a single
- ROS package in a repository. If a repository contains more than
- one package, or the package is not in the root of the repository,
- then use the `--src-subdir=
` option.
-
- ROS repositories generally do not use `master` as their default
- branch, so be sure to include the correct branch for the desired
- distribution as part of the URI: `;branch=indigo-devel`
-
-## EXAMPLES ##
-Build the Vector Nav package
-```
-devtool add https://github.com/dawonn/vectornav
-```
-
-Use the XBox Kinect Camera
-```
-devtool add --src-subdir=freenect_stack "https://github.com/ros-drivers/freenect_stack.git"
-devtool add --src-subdir=freenect_launch "https://github.com/ros-drivers/freenect_stack.git"
-devtool add --src-subdir=freenect_camera "https://github.com/ros-drivers/freenect_stack.git"
-```
-
-## TO DO ##
-
- * Wrapper to generate recipes for each package in a repository.
- * Add support for ament for ROS2 packages.
- * Wrapper for using rosdistro data to generate recipes for various ROS distributions.
-
diff --git a/lib/recipetool/__init__.py b/lib/recipetool/__init__.py
deleted file mode 100644
index 8eda927..0000000
--- a/lib/recipetool/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Enable other layers to have modules in the same named directory
-from pkgutil import extend_path
-__path__ = extend_path(__path__, __name__)
diff --git a/lib/recipetool/create_catkin.py b/lib/recipetool/create_catkin.py
deleted file mode 100644
index f95140c..0000000
--- a/lib/recipetool/create_catkin.py
+++ /dev/null
@@ -1,429 +0,0 @@
-#!/usr/bin/python3
-"""Recipe creation tool - catkin support plugin."""
-
-# Copyright (C) 2017 Intel Corporation
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import re
-import logging
-
-from html.parser import HTMLParser
-from lxml import etree
-
-import hashlib
-
-from recipetool.create import RecipeHandler
-from recipetool.create_buildsys import CmakeExtensionHandler
-
-LOGGER = logging.getLogger('recipetool')
-
-
-class RosHTMLParser(HTMLParser):
- """ROS HTML Parser class.
-
- Primarily for removing any XHTML from the tag.
- See: http://www.ros.org/reps/rep-0127.html#description (Format 1)
- See: http://www.ros.org/reps/rep-0140.html#description (Format 2)
- """
-
- basic_text = ""
-
- def handle_data(self, data):
- """Override HTMLParser handle_data method."""
- if len(self.basic_text) > 0:
- self.basic_text = self.basic_text + " "
- self.basic_text = self.basic_text + data.strip()
-
-
-class RosXmlParser:
- """ROS package.xml Parser class.
-
- Uses the etree class from lxml to parse the ROS package.xml file.
- This file is main source for information for constructing the BitBake
- recipe for the ROS package.
-
- See: http://www.ros.org/reps/rep-0127.html (Format 1)
- See: http://www.ros.org/reps/rep-0140.html (Format 2)
- """
-
- package_format = 0
-
- def __init__(self, xml_path):
- """Initialize the class by finding the package format version."""
- # Default to ROS package format 1
- # http://wiki.ros.org/catkin/package.xml#Format_1_.28Legacy.29
- self.package_format = 1
-
- self.xml_path = xml_path
- self.tree = etree.parse(self.xml_path)
- # Check the ROS package format
- # http://wiki.ros.org/catkin/package.xml#Format_1_.28Legacy.29
- # or
- # http://wiki.ros.org/catkin/package.xml#Format_2_.28Recommended.29
- package_format_list = self.tree.xpath("/package[@format]")
- for pkg_format in package_format_list:
- self.package_format = int(pkg_format.get('format',
- self.package_format))
- if self.package_format > 2:
- self.package_format = 2
- LOGGER.warning("FORCING ROS Package Format to version " +
- str(self.package_format))
- elif self.package_format < 1:
- self.package_format = 1
- LOGGER.warning("FORCING ROS Package Format to version " +
- str(self.package_format))
-
- LOGGER.debug("ROS Package Format version " + str(self.package_format))
-
- def get_format(self):
- """Return the package.xml format version."""
- return str(self.package_format)
-
- def clean_string(self, raw_string):
- """Remove white space and sanitize the string.
-
- Replace double quotes with single quotes as bitbake
- recipes variables will be set with double quotes.
- """
- return re.sub(r'\s+', ' ', raw_string.strip().replace('"', "'"))
-
- def get_single(self, xpath, required=True):
- """Return a single string value for the given xpath."""
- xpath_list = self.tree.xpath(xpath)
- if len(xpath_list) < 1:
- if required:
- LOGGER.error("ROS package.xml missing element " + str(xpath))
- return None
- elif len(xpath_list) > 1:
- LOGGER.warning("ROS package.xml has more than 1 match for " +
- str(xpath))
-
- return self.clean_string(xpath_list[0].text)
-
- def get_multiple_with_type(self, xpath, required=False):
- """Return dict of type attributes and the matching urls from xpath."""
- items = {}
- xpath_list = self.tree.xpath(xpath)
- if len(xpath_list) < 1:
- if required:
- LOGGER.error("ROS package.xml missing element " + str(xpath))
- for item in xpath_list:
- url_string = self.clean_string(item.text)
- url_type = self.clean_string(item.get('type', '')).lower()
- items[url_type] = url_string
-
- return items
-
- def get_multiple_with_email(self, xpath, required=True):
- """Return list of string values and email attrib for given xpath."""
- items = []
- xpath_list = self.tree.xpath(xpath)
- if len(xpath_list) < 1:
- if required:
- LOGGER.error("ROS package.xml missing element " + str(xpath))
- for item in xpath_list:
- fullstring = self.clean_string(item.text)
- email = self.clean_string(item.get('email', ''))
- if len(email) > 0:
- fullstring = fullstring + " <" + email + ">"
- items.append(fullstring)
-
- return items
-
- def get_multiple_with_version(self, xpath, required=False):
- """Return list of dependencies and version attribs for given xpath."""
- def catkin_to_bitbake(version_type):
- """Map the Catkin version modifier to BitBake."""
- mapper = {
- "version_lt": "<",
- "version_lte": "<=",
- "version_eq": "=",
- "version_gte": ">=",
- "version_gt": ">",
- }
- return mapper.get(version_type, "UNDEFINED")
-
- items = []
- xpath_list = self.tree.xpath(xpath)
- if len(xpath_list) < 1:
- if required:
- LOGGER.error("ROS package.xml missing element " + str(xpath))
- for item in xpath_list:
- fullstring = self.clean_string(item.text)
- if len(item.attrib) > 1:
- LOGGER.error("ROS package.xml element " + str(xpath) +
- " has too many attributes!")
- for version_type in item.attrib:
- c_version_type = catkin_to_bitbake(version_type)
- c_value = self.clean_string(item.attrib[version_type])
- if len(c_value) > 1:
- c_version_type = c_version_type + " " + c_value
- if len(c_version_type) > 1:
- fullstring = fullstring + " (" + c_version_type + ")"
- items.append(fullstring)
-
- return items
-
- def get_multiple_with_linenumber(self, xpath, required=False):
- """Return dict of string and their line numbers for given xpath."""
- items = {}
- xpath_list = self.tree.xpath(xpath)
- if len(xpath_list) < 1:
- if required:
- LOGGER.error("ROS package.xml missing element " + str(xpath))
- for item in xpath_list:
- c_string = self.clean_string(item.text)
- items[c_string] = item.sourceline
-
- return items
-
- def get_name(self):
- """Return the Name of the ROS package."""
- return self.get_single("/package/name")
-
- def get_version(self):
- """Return the Version of the ROS package."""
- return self.get_single("/package/version")
-
- def get_description(self):
- """Return the Description of the ROS package.
-
- Remove the XHTML information, if present, and only return
- a simple text string description for the package.
- """
- parser = RosHTMLParser()
- parser.feed(self.get_single("/package/description"))
- return self.clean_string(parser.basic_text)
-
- def get_authors(self):
- """Return list of Authors of the ROS package."""
- return self.get_multiple_with_email("/package/author", required=False)
-
- def get_maintainers(self):
- """Return list of Maintainers of the ROS package."""
- return self.get_multiple_with_email("/package/maintainer")
-
- def get_urls(self):
- """Return list of Website URLs for the ROS package."""
- return self.get_multiple_with_type("/package/url", required=False)
-
- def get_licenses(self):
- """Return list of Licenses of the ROS package."""
- return self.get_multiple_with_linenumber("/package/license")
-
- def get_build_dependencies(self):
- """Return list of package Build Dependencies of the ROS package."""
- dependencies = []
-
- # build_depend is both format 1 & 2
- for dependency in self.get_multiple_with_version(
- "/package/build_depend"):
- dependencies.append(dependency.replace("_", "-"))
- if self.package_format > 1:
- for dependency in self.get_multiple_with_version(
- "/package/depend"):
- dependencies.append(dependency.replace("_", "-"))
-
- # remove any duplicates
- dependencies = list(set(dependencies))
-
- return dependencies
-
- def get_runtime_dependencies(self):
- """Return list of package Run Dependencies of the ROS package."""
- dependencies = []
-
- # run_depend is format 1 only
- if self.package_format == 1:
- for dependency in self.get_multiple_with_version(
- "/package/run_depend"):
- dependencies.append(dependency.replace("_", "-"))
- if self.package_format == 2:
- for dependency in self.get_multiple_with_version(
- "/package/exec_depend"):
- dependencies.append(dependency.replace("_", "-"))
- for dependency in self.get_multiple_with_version(
- "/package/depend"):
- dependencies.append(dependency.replace("_", "-"))
-
- # remove any duplicates
- dependencies = list(set(dependencies))
-
- return dependencies
-
-
-class CatkinRecipeHandler(RecipeHandler):
- """Catkin handler extension for recipetool."""
-
- def process_license(self,
- srctree, classes, lines_before,
- lines_after, handled, extravalues,
- licenses, license_file):
- """Generate the Catkin license data.
-
- licenses: a dictionary of license:line_number
- license_file: the name of the license file
- """
- all_lines = []
- license_keys = list(licenses.keys())
-
- def get_license_checksum(license):
- """Output the license details."""
- line_number = licenses[license]
-
- m = hashlib.md5()
- try:
- lic_line = all_lines[line_number - 1]
- m.update(lic_line.encode('utf-8'))
- md5val = m.hexdigest()
- except UnicodeEncodeError:
- md5val = None
-
- LOGGER.debug("License: '" + license + "' on line " +
- str(line_number) + " with md5 " + md5val)
-
- checksum = "file://" + os.path.basename(license_file) + \
- ";" + "beginline=" + str(line_number) + ";endline=" + \
- str(line_number) + ";md5=" + md5val
- return checksum
-
- try:
- lic_file = open(license_file)
- all_lines = lic_file.readlines()
- lic_file.close()
- except:
- LOGGER.error("License file '" + license_file + "'not readable!")
- return False
-
- checksum_files = []
- if len(license_keys) > 0:
- checksum_files.append(get_license_checksum(license_keys[0]))
- del license_keys[0]
-
- for license in license_keys:
- checksum_files.append(get_license_checksum(license))
-
- # Commas are not valid in BitBake License name
- clean_keys = [re.sub(r',', '', lic) for lic in licenses.keys()]
-
- extravalues['LICENSE'] = " & ".join(clean_keys)
- extravalues['LIC_FILES_CHKSUM'] = " ".join(checksum_files)
-
- handled.append('license')
-
- def process(self, srctree, classes, lines_before, lines_after, handled,
- extravalues):
- """Process the Catkin recipe.
-
- Read the key tags from the package.xml ROS file and generate
- the corresponding recipe variables for the recipe file.
- """
- package_list = RecipeHandler.checkfiles(srctree, ['package.xml'],
- recursive=False)
- if len(package_list) > 0:
- handled.append('buildsystem')
-
- for package_file in package_list:
- LOGGER.info("Found package_file: " + package_file)
- xml = RosXmlParser(package_file)
-
- classes.append('catkin')
-
- extravalues['PN'] = xml.get_name() # Ignored if set
- extravalues['PV'] = xml.get_version()
-
- licenses = xml.get_licenses()
- if len(licenses) < 1:
- LOGGER.error("package.xml missing required LICENSE field!")
- else:
- self.process_license(srctree, classes, lines_before,
- lines_after, handled, extravalues,
- licenses, package_file)
-
- lines_after.append('# This is a Catkin (ROS) based recipe')
- lines_after.append('# ROS package.xml format version ' +
- xml.get_format())
- lines_after.append('')
-
- lines_after.append("SUMMARY = \"" +
- "ROS package " + xml.get_name() + "\"")
- lines_after.append("DESCRIPTION = \"" +
- xml.get_description() + "\"")
-
- # Map the Catkin URLs to BitBake
- urls = xml.get_urls()
- if 'website' in urls:
- lines_after.append("HOMEPAGE = \"" +
- urls['website'] + "\"")
- else:
- if '' in urls:
- lines_after.append("HOMEPAGE = \"" +
- urls[''] + "\"")
- if 'bugtracker' in urls:
- lines_after.append("# ROS_BUGTRACKER = \"" +
- urls['bugtracker'] + "\"")
-
- if 'repository' in urls:
- lines_after.append("# SRC_URI = \"" +
- urls['repository'] + "\"")
-
- authors = xml.get_authors()
- if len(authors) > 0:
- lines_after.append("# ROS_AUTHOR = \"" +
- authors[0] + "\"")
- del authors[0]
- for author in authors:
- lines_after.append("# ROS_AUTHOR += \"" +
- author + "\"")
-
- maintainers = xml.get_maintainers()
- if len(maintainers) > 0:
- lines_after.append("# ROS_MAINTAINER = \"" +
- maintainers[0] + "\"")
- del maintainers[0]
- for maintainer in maintainers:
- lines_after.append("# ROS_MAINTAINER += \"" +
- maintainer + "\"")
-
- lines_after.append("SECTION = \"devel\"")
-
- dependencies = xml.get_build_dependencies()
- if len(dependencies) > 0:
- lines_after.append("DEPENDS = \"" +
- dependencies[0] + "\"")
- del dependencies[0]
- for dependency in dependencies:
- lines_after.append("DEPENDS += \"" +
- dependency + "\"")
-
- dependencies = xml.get_runtime_dependencies()
- if len(dependencies) > 0:
- lines_after.append("RDEPENDS_${PN}-dev = \"" +
- dependencies[0] + "\"")
- del dependencies[0]
- for dependency in dependencies:
- lines_after.append("RDEPENDS_${PN}-dev += \"" +
- dependency + "\"")
- return True
-
- return False
-
-
-def register_recipe_handlers(handlers):
- """Register our recipe handler in front of default cmake handler.
-
- Catkin needs to be a higher priority than CMake (50).
- """
- handlers.append((CatkinRecipeHandler(), 90))