From 6e7c605279f77ebc66b5da17a296f0741cc326a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Fri, 6 May 2016 16:42:35 +0200 Subject: [PATCH] Tools/px_generate_uorb_topic*: combine the src & header generators into one script --- ...ers.py => px_generate_uorb_topic_files.py} | 83 ++++++-- Tools/px_generate_uorb_topic_sources.py | 199 ------------------ cmake/common/px4_base.cmake | 14 +- cmake/ros-CMakeLists.txt | 4 +- 4 files changed, 71 insertions(+), 229 deletions(-) rename Tools/{px_generate_uorb_topic_headers.py => px_generate_uorb_topic_files.py} (75%) delete mode 100755 Tools/px_generate_uorb_topic_sources.py diff --git a/Tools/px_generate_uorb_topic_headers.py b/Tools/px_generate_uorb_topic_files.py similarity index 75% rename from Tools/px_generate_uorb_topic_headers.py rename to Tools/px_generate_uorb_topic_files.py index 0dba2468f3..7ca22995b5 100755 --- a/Tools/px_generate_uorb_topic_headers.py +++ b/Tools/px_generate_uorb_topic_files.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################# # -# Copyright (C) 2013-2015 PX4 Development Team. All rights reserved. +# Copyright (C) 2013-2016 PX4 Development Team. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -33,8 +33,8 @@ ############################################################################# """ -px_generate_uorb_topic_headers.py -Generates c/cpp header files for uorb topics from .msg (ROS syntax) +px_generate_uorb_topics.py +Generates c/cpp header/source files for uorb topics from .msg (ROS syntax) message files """ from __future__ import print_function @@ -69,14 +69,15 @@ On Windows please run: ''') exit(1) -__author__ = "Thomas Gubler" -__copyright__ = "Copyright (C) 2013-2014 PX4 Development Team." +__author__ = "Sergey Belash, Thomas Gubler, Beat Kueng" +__copyright__ = "Copyright (C) 2013-2016 PX4 Development Team." __license__ = "BSD" __email__ = "thomasgubler@gmail.com" -TEMPLATE_FILE = 'msg.h.template' -OUTPUT_FILE_EXT = '.h' +TEMPLATE_FILE = ['msg.h.template', 'msg.cpp.template'] +TOPICS_LIST_TEMPLATE_FILE = 'uORBTopics.cpp.template' +OUTPUT_FILE_EXT = ['.h', '.cpp'] INCL_DEFAULT = ['std_msgs:./msg/std_msgs'] PACKAGE = 'px4' TOPICS_TOKEN = '# TOPICS ' @@ -97,10 +98,16 @@ def get_multi_topics(filename): ofile.close() return result +def get_msgs_list(msgdir): + """ + Makes list of msg files in the given directory + """ + return [fn for fn in os.listdir(msgdir) if fn.endswith(".msg")] -def generate_header_from_file(filename, outputdir, templatedir, includepath): + +def generate_output_from_file(format_idx, filename, outputdir, templatedir, includepath): """ - Converts a single .msg file to a uorb header file + Converts a single .msg file to an uorb header/source file """ msg_context = genmsg.msg_loader.MsgContext.create_default() full_type_name = genmsg.gentools.compute_full_type_name(PACKAGE, os.path.basename(filename)) @@ -127,28 +134,34 @@ def generate_header_from_file(filename, outputdir, templatedir, includepath): if not os.path.isdir(outputdir): os.makedirs(outputdir) - template_file = os.path.join(templatedir, TEMPLATE_FILE) - output_file = os.path.join(outputdir, spec.short_name + OUTPUT_FILE_EXT) + template_file = os.path.join(templatedir, TEMPLATE_FILE[format_idx]) + output_file = os.path.join(outputdir, spec.short_name + + OUTPUT_FILE_EXT[format_idx]) - if os.path.isfile(output_file): - return False + return generate_by_template(output_file, template_file, em_globals) + +def generate_by_template(output_file, template_file, em_globals): + """ + Invokes empy intepreter to geneate output_file by the + given template_file and predefined em_globals dict + """ ofile = open(output_file, 'w') # todo, reuse interpreter interpreter = em.Interpreter(output=ofile, globals=em_globals, options={em.RAW_OPT:True,em.BUFFERED_OPT:True}) if not os.path.isfile(template_file): ofile.close() os.remove(output_file) - raise RuntimeError("Template file %s not found in template dir %s" % (template_file, templatedir)) + raise RuntimeError("Template file %s not found" % (template_file)) interpreter.file(open(template_file)) #todo try interpreter.shutdown() ofile.close() return True -def convert_dir(inputdir, outputdir, templatedir): +def convert_dir(format_idx, inputdir, outputdir, templatedir): """ - Converts all .msg files in inputdir to uORB header files + Converts all .msg files in inputdir to uORB header/source files """ # Find the most recent modification time in input dir @@ -185,7 +198,7 @@ def convert_dir(inputdir, outputdir, templatedir): if not os.path.isfile(fn): continue - generate_header_from_file(fn, outputdir, templatedir, includepath) + generate_output_from_file(format_idx, fn, outputdir, templatedir, includepath) return True @@ -223,19 +236,32 @@ def copy_changed(inputdir, outputdir, prefix='', quiet=False): print("{0}: unchanged".format(input_file)) -def convert_dir_save(inputdir, outputdir, templatedir, temporarydir, prefix, quiet=False): +def convert_dir_save(format_idx, inputdir, outputdir, templatedir, temporarydir, prefix, quiet=False): """ Converts all .msg files in inputdir to uORB header files Unchanged existing files are not overwritten. """ # Create new headers in temporary output directory - convert_dir(inputdir, temporarydir, templatedir) + convert_dir(format_idx, inputdir, temporarydir, templatedir) + if generate_idx == 1: + generate_topics_list_file(inputdir, temporarydir, templatedir) # Copy changed headers from temporary dir to output dir copy_changed(temporarydir, outputdir, prefix, quiet) +def generate_topics_list_file(msgdir, outputdir, templatedir): + # generate cpp file with topics list + tl_globals = {"msgs" : get_msgs_list(msgdir)} + tl_template_file = os.path.join(templatedir, TOPICS_LIST_TEMPLATE_FILE) + tl_out_file = os.path.join(outputdir, TOPICS_LIST_TEMPLATE_FILE.replace(".template", "")) + generate_by_template(tl_out_file, tl_template_file, tl_globals) + if __name__ == "__main__": parser = argparse.ArgumentParser( - description='Convert msg files to uorb headers') + description='Convert msg files to uorb headers/sources') + parser.add_argument('--headers', help='Generate header files', + action='store_true') + parser.add_argument('--sources', help='Generate source files', + action='store_true') parser.add_argument('-d', dest='dir', help='directory with msg files') parser.add_argument('-f', dest='file', help="files to convert (use only without -d)", @@ -254,11 +280,22 @@ if __name__ == "__main__": ' name when converting directories') args = parser.parse_args() + if args.headers: + generate_idx = 0 + elif args.sources: + generate_idx = 1 + else: + print('Error: either --headers or --sources must be specified') + exit(-1) + if args.file is not None: - for f in args.file: - generate_header_from_file(f, args.outputdir, args.templatedir, INCL_DEFAULT) + for f in args.file: + generate_output_from_file(generate_idx, f, args.outputdir, args.templatedir, INCL_DEFAULT) + if generate_idx == 1: + generate_topics_list_file(args.dir, args.outputdir, args.templatedir) elif args.dir is not None: - convert_dir_save( + convert_dir_save( + generate_idx, args.dir, args.outputdir, args.templatedir, diff --git a/Tools/px_generate_uorb_topic_sources.py b/Tools/px_generate_uorb_topic_sources.py deleted file mode 100755 index b3071832c3..0000000000 --- a/Tools/px_generate_uorb_topic_sources.py +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/env python -############################################################################# -# -# Copyright (C) 2013-2015 PX4 Development Team. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name PX4 nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################# - -""" -px_generate_uorb_topic_sources.py -Generates cpp source files for uorb topics from .msg (ROS syntax) -message files -""" -from __future__ import print_function -import os -import shutil -import filecmp -import argparse - -import sys -px4_tools_dir = os.path.dirname(os.path.abspath(__file__)) -sys.path.append(px4_tools_dir + "/genmsg/src") -sys.path.append(px4_tools_dir + "/gencpp/src") - -try: - import em - import genmsg.template_tools -except ImportError as e: - print("python import error: ", e) - print(''' -Required python packages not installed. - -On a Debian/Ubuntu system please run: - - sudo apt-get install python-empy - sudo pip install catkin_pkg - -On MacOS please run: - sudo pip install empy catkin_pkg - -On Windows please run: - easy_install empy catkin_pkg -''') - exit(1) - -__author__ = "Sergey Belash, Thomas Gubler" -__copyright__ = "Copyright (C) 2013-2014 PX4 Development Team." -__license__ = "BSD" -__email__ = "againagainst@gmail.com, thomasgubler@gmail.com" - -TOPIC_TEMPLATE_FILE = 'msg.cpp.template' -TOPICS_LIST_TEMPLATE_FILE = 'uORBTopics.cpp.template' -OUTPUT_FILE_EXT = '.cpp' -INCL_DEFAULT = ['std_msgs:./msg/std_msgs'] -PACKAGE = 'px4' -TOPICS_TOKEN = '# TOPICS ' - - -def get_multi_topics(filename): - """ - Get TOPICS names from a "# TOPICS" line - """ - ofile = open(filename, 'r') - text = ofile.read() - result = [] - for each_line in text.split('\n'): - if each_line.startswith (TOPICS_TOKEN): - topic_names_str = each_line.strip() - topic_names_str = topic_names_str.replace(TOPICS_TOKEN, "") - result.extend(topic_names_str.split(" ")) - ofile.close() - return result - - -def get_msgs_list(msgdir): - """ - Makes list of msg files in the given directory - """ - return [fn for fn in os.listdir(msgdir) if fn.endswith(".msg")] - - -def generate_source_from_file(filename, outputdir, template_file, includepath, quiet=False): - """ - Converts a single .msg file to a uorb source file - """ - # print("Generating sources from {0}".format(filename)) - msg_context = genmsg.msg_loader.MsgContext.create_default() - full_type_name = genmsg.gentools.compute_full_type_name(PACKAGE, os.path.basename(filename)) - spec = genmsg.msg_loader.load_msg_from_file(msg_context, filename, full_type_name) - topics = get_multi_topics(filename) - if includepath: - search_path = genmsg.command_line.includepath_to_dict(includepath) - else: - search_path = {} - if len(topics) == 0: - topics.append(spec.short_name) - em_globals = { - "file_name_in": filename, - "search_path": search_path, - "spec": spec, - "topics": topics - } - - output_file = os.path.join(outputdir, spec.short_name + OUTPUT_FILE_EXT) - if os.path.isfile(output_file): - return False - generate_by_template(output_file, template_file, em_globals) - if not quiet: - print("{0}: new source file".format(output_file)) - return True - - -def generate_by_template(output_file, template_file, em_globals): - """ - Invokes empy intepreter to geneate output_file by the - given template_file and predefined em_globals dict - """ - ofile = open(output_file, 'w') - # todo, reuse interpreter - interpreter = em.Interpreter(output=ofile, globals=em_globals, options={em.RAW_OPT:True,em.BUFFERED_OPT:True}) - if not os.path.isfile(template_file): - ofile.close() - os.remove(output_file) - raise RuntimeError("Template file %s not found" % (template_file)) - interpreter.file(open(template_file)) #todo try - interpreter.shutdown() - ofile.close() - - -def convert_dir(msgdir, outputdir, templatedir, quiet=False): - """ - Converts all .msg files in msgdir to uORB sources - """ - # Make sure output directory exists: - if not os.path.isdir(outputdir): - os.makedirs(outputdir) - template_file = os.path.join(templatedir, TOPIC_TEMPLATE_FILE) - - includepath = INCL_DEFAULT + [':'.join([PACKAGE, msgdir])] - for f in os.listdir(msgdir): - # Ignore hidden files - if f.startswith("."): - continue - fn = os.path.join(msgdir, f) - # Only look at actual files - if not os.path.isfile(fn): - continue - generate_source_from_file(fn, outputdir, template_file, includepath, quiet) - - # generate cpp file with topics list - tl_globals = {"msgs" : get_msgs_list(msgdir)} - tl_template_file = os.path.join(templatedir, TOPICS_LIST_TEMPLATE_FILE) - tl_out_file = os.path.join(outputdir, TOPICS_LIST_TEMPLATE_FILE.replace(".template", "")) - generate_by_template(tl_out_file, tl_template_file, tl_globals) - return True - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Convert msg files to uorb sources') - parser.add_argument('-d', dest='dir', help='directory with msg files') - parser.add_argument('-f', dest='file', help="files to convert (use only without -d)", nargs="+") - parser.add_argument('-e', dest='templatedir', help='directory with template files',) - parser.add_argument('-o', dest='outputdir', help='output directory for source files') - parser.add_argument('-q', dest='quiet', default=False, action='store_true', - help='string added as prefix to the output file ' - ' name when converting directories') - args = parser.parse_args() - - if args.file is not None: - for f in args.file: - generate_source_from_file(f, args.outputdir, args.templatedir, args.quiet) - elif args.dir is not None: - convert_dir(args.dir, args.outputdir, args.templatedir, args.quiet) diff --git a/cmake/common/px4_base.cmake b/cmake/common/px4_base.cmake index 41de8a94c4..84383fc670 100644 --- a/cmake/common/px4_base.cmake +++ b/cmake/common/px4_base.cmake @@ -380,12 +380,13 @@ function(px4_generate_messages) endforeach() add_custom_command(OUTPUT ${msg_files_out} COMMAND ${PYTHON_EXECUTABLE} - Tools/px_generate_uorb_topic_headers.py + Tools/px_generate_uorb_topic_files.py + --headers ${QUIET} -d msg -o ${msg_out_path} -e msg/templates/uorb - -t ${CMAKE_BINARY_DIR}/topics_temporary + -t ${CMAKE_BINARY_DIR}/topics_temporary_header DEPENDS ${DEPENDS} ${MSG_FILES} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMENT "Generating uORB topic headers" @@ -400,11 +401,13 @@ function(px4_generate_messages) endforeach() add_custom_command(OUTPUT ${msg_source_files_out} COMMAND ${PYTHON_EXECUTABLE} - Tools/px_generate_uorb_topic_sources.py + Tools/px_generate_uorb_topic_files.py + --sources ${QUIET} -d msg - -e msg/templates/uorb -o ${msg_source_out_path} + -e msg/templates/uorb + -t ${CMAKE_BINARY_DIR}/topics_temporary_sources DEPENDS ${DEPENDS} ${MSG_FILES} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMENT "Generating uORB topic sources" @@ -421,7 +424,8 @@ function(px4_generate_messages) endforeach() add_custom_command(OUTPUT ${msg_multi_files_out} COMMAND ${PYTHON_EXECUTABLE} - Tools/px_generate_uorb_topic_headers.py + Tools/px_generate_uorb_topic_files.py + --headers ${QUIET} -d msg -o ${msg_multi_out_path} diff --git a/cmake/ros-CMakeLists.txt b/cmake/ros-CMakeLists.txt index 10cb673bfe..67870b1e2c 100644 --- a/cmake/ros-CMakeLists.txt +++ b/cmake/ros-CMakeLists.txt @@ -147,8 +147,8 @@ set(MULTIPLATFORM_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/platforms/ros/px4_m set(MULTIPLATFORM_TEMPLATE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/msg/templates/px4/ros) set(TOPICHEADER_TEMP_DIR ${CMAKE_BINARY_DIR}/topics_temporary) set(MULTIPLATFORM_PREFIX px4_) -add_custom_target(multiplatform_message_headers ALL ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Tools/px_generate_uorb_topic_headers.py - -d ${CMAKE_CURRENT_SOURCE_DIR}/msg -o ${MULTIPLATFORM_HEADER_DIR} -e ${MULTIPLATFORM_TEMPLATE_DIR} +add_custom_target(multiplatform_message_headers ALL ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Tools/px_generate_uorb_topic_files.py + --headers -d ${CMAKE_CURRENT_SOURCE_DIR}/msg -o ${MULTIPLATFORM_HEADER_DIR} -e ${MULTIPLATFORM_TEMPLATE_DIR} -t ${TOPICHEADER_TEMP_DIR} -p ${MULTIPLATFORM_PREFIX}) ## Declare a cpp library