use CmakeLists scope to generate te XML file

- the only difference really is, that scope (the configuration.cmake) is already passed
  to px_process_params via the argument --scope. The Paths in --scope are evaluated w.r.t
  the path to src provided via the -s /--src-path argument.
- if no --scope is proveided. the Old scheme by simply walking the full --src-path directory
  is applied
This commit is contained in:
mazahner
2016-12-22 14:16:23 +01:00
committed by Lorenz Meier
parent c72de874d6
commit 6fe9b8e543
9 changed files with 130 additions and 94 deletions

View File

@@ -364,7 +364,9 @@ px4_generate_messages(TARGET msg_gen
OS ${OS} OS ${OS}
DEPENDS git_genmsg git_gencpp prebuild_targets DEPENDS git_genmsg git_gencpp prebuild_targets
) )
px4_generate_parameters_xml(OUT parameters.xml BOARD ${BOARD}) px4_generate_parameters_xml(OUT parameters.xml
BOARD ${BOARD}
SCOPE ${PX4_SOURCE_DIR}/cmake/configs/${OS}_${BOARD}_${LABEL}.cmake)
px4_generate_airframes_xml(OUT airframes.xml BOARD ${BOARD}) px4_generate_airframes_xml(OUT airframes.xml BOARD ${BOARD})
add_custom_target(xml_gen add_custom_target(xml_gen
DEPENDS parameters.xml airframes.xml) DEPENDS parameters.xml airframes.xml)

View File

@@ -1 +1 @@
__all__ = ["srcscanner", "srcparser", "xmlout", "dokuwikiout", "dokuwikirpc"] __all__ = ["srcscanner", "srcparser", "xmlout", "dokuwikiout", "dokuwikirpc", "cmakeparser", "scope"]

View File

@@ -0,0 +1,37 @@
import re
import codecs
import sys
class CMakeParser(object):
"""
Parses provided data and stores all found paths in scope.
"""
re_split_lines = re.compile(r'[\r\n]+')
re_comment = re.compile(r'^\#')
re_start = re.compile(r'set\s*\(\s*config_module_list')
re_end = re.compile(r'\)\s*')
def Parse(self, scope, contents):
"""
Incrementally parse cmake file contents and append all found path scope
to scope.
"""
# This code is essentially a comment-parsing grammar. "state"
# represents parser state. It contains human-readable state
# names.
state = None
for line in self.re_split_lines.split(contents):
line = line.strip()
# Ignore empty lines
if line == "":
continue
if self.re_comment.match(line):
continue
elif self.re_start.match(line):
state = "gather"
continue
elif state is not None and state == "gather":
if self.re_end.match(line):
return True
scope.Add(line)
return False

32
Tools/px4params/scope.py Normal file
View File

@@ -0,0 +1,32 @@
import os
import re
class Scope(object):
"""
Single parameter group
"""
re_deep_lines = re.compile(r'.*\/.*\/')
def __init__(self,):
self.scope = set()
def __str__(self):
return self.scope.__str__()
def Add(self, scope):
"""
Add Scope to set
"""
self.scope.add(scope)
def Has(self, scope):
"""
Check for existance
"""
if len(self.scope) == 0:
return True
# Anything in the form xxxxx/yyyyy/zzzzz....
# is treated as xxxxx/yyyyy
while (self.re_deep_lines.match(scope)):
scope = os.path.dirname(scope)
return scope in self.scope

View File

@@ -1,6 +1,7 @@
import os import os
import re import re
import codecs import codecs
import sys
class SourceScanner(object): class SourceScanner(object):
""" """
@@ -8,24 +9,25 @@ class SourceScanner(object):
to the Parser. to the Parser.
""" """
def ScanDir(self, srcdir, parser): def ScanDir(self, srcdirs, parser):
""" """
Scans provided path and passes all found contents to the parser using Scans provided path and passes all found contents to the parser using
parser.Parse method. parser.Parse method.
""" """
extensions1 = tuple([".h"]) extensions1 = tuple([".h"])
extensions2 = tuple([".cpp", ".c"]) extensions2 = tuple([".cpp", ".c"])
for dirname, dirnames, filenames in os.walk(srcdir): for srcdir in srcdirs:
for filename in filenames: for dirname, dirnames, filenames in os.walk(srcdir):
if filename.endswith(extensions1): for filename in filenames:
path = os.path.join(dirname, filename) if filename.endswith(extensions1):
if not self.ScanFile(path, parser): path = os.path.join(dirname, filename)
return False if not self.ScanFile(path, parser):
for filename in filenames: return False
if filename.endswith(extensions2): for filename in filenames:
path = os.path.join(dirname, filename) if filename.endswith(extensions2):
if not self.ScanFile(path, parser): path = os.path.join(dirname, filename)
return False if not self.ScanFile(path, parser):
return False
return True return True
def ScanFile(self, path, parser): def ScanFile(self, path, parser):

View File

@@ -3,87 +3,23 @@ import xml.etree.ElementTree as ET
import os import os
import re import re
import codecs import codecs
import sys
class Scope(object): from px4params import scope, cmakeparser
"""
Single parameter group
"""
re_deep_lines = re.compile(r'.*\/.*\/')
def __init__(self, ):
self.scope = set()
def __str__(self):
return self.scope.__str__()
def Add(self, scope):
"""
Add Scope to set
"""
self.scope.add(scope)
def Has(self, scope):
"""
Check for existance
"""
if len(self.scope) == 0:
return True
# Anything in the form xxxxx/yyyyy/zzzzz....
# is treated as xxxxx/yyyyy
while (self.re_deep_lines.match(scope)):
scope = os.path.dirname(scope)
return scope in self.scope
class CMakeParser(object):
"""
Parses provided data and stores all found paths in scope.
"""
re_split_lines = re.compile(r'[\r\n]+')
re_comment = re.compile(r'^\#')
re_start = re.compile(r'set\s*\(\s*config_module_list')
re_end = re.compile(r'\)\s*')
def Parse(self, scope, contents):
"""
Incrementally parse cmake file contents and append all found path scope
to scope.
"""
# This code is essentially a comment-parsing grammar. "state"
# represents parser state. It contains human-readable state
# names.
state = None
for line in self.re_split_lines.split(contents):
line = line.strip()
# Ignore empty lines
if line == "":
continue
if self.re_comment.match(line):
continue
elif self.re_start.match(line):
state = "gather"
continue
elif state is not None and state == "gather":
if self.re_end.match(line):
return True
scope.Add(line)
return False
if len(os.sys.argv) < 2: if len(os.sys.argv) < 2:
print("Error in %s" % os.sys.argv[0]) print("Error in %s" % os.sys.argv[0])
print("Usage: %s <parameters.xml> [cmake-file-scoping] " % os.sys.argv[0]) print("Usage: %s <parameters.xml> [cmake-file-scoping] " % os.sys.argv[0])
raise SystemExit raise SystemExit
cmake_scope = scope.Scope()
scope = Scope()
if len(os.sys.argv) == 3: if len(os.sys.argv) == 3:
with codecs.open(os.sys.argv[2], 'r', 'utf-8') as f: with codecs.open(os.sys.argv[2], 'r', 'utf-8') as f:
try: try:
contents = f.read() contents = f.read()
f.close() f.close()
parser = CMakeParser() parser = cmakeparser.CMakeParser()
parser.Parse(scope, contents) parser.Parse(cmake_scope, contents)
except: except:
contents = '' contents = ''
print('Failed reading file: %s, skipping scoping.' % os.sys.argv[2]) print('Failed reading file: %s, skipping scoping.' % os.sys.argv[2])
@@ -110,7 +46,9 @@ struct px4_parameters_t {
start_name = "" start_name = ""
end_name = "" end_name = ""
sys.stderr.write("cmake_scope: " + str(cmake_scope) + "\n")
for group in root: for group in root:
sys.stderr.write(str(group.attrib) + group.tag + "\n")
if group.tag == "group" and "no_code_generation" not in group.attrib: if group.tag == "group" and "no_code_generation" not in group.attrib:
section = """ section = """
/***************************************************************** /*****************************************************************
@@ -118,7 +56,7 @@ for group in root:
****************************************************************/""" % group.attrib["name"] ****************************************************************/""" % group.attrib["name"]
for param in group: for param in group:
scope_ = param.find('scope').text scope_ = param.find('scope').text
if not scope.Has(scope_): if not cmake_scope.Has(scope_):
continue continue
if not start_name: if not start_name:
start_name = param.attrib["name"] start_name = param.attrib["name"]
@@ -156,7 +94,7 @@ for group in root:
****************************************************************/""" % group.attrib["name"] ****************************************************************/""" % group.attrib["name"]
for param in group: for param in group:
scope_ = param.find('scope').text scope_ = param.find('scope').text
if not scope.Has(scope_): if not cmake_scope.Has(scope_):
continue continue
if not start_name: if not start_name:
start_name = param.attrib["name"] start_name = param.attrib["name"]

View File

@@ -50,7 +50,10 @@ from __future__ import print_function
import sys import sys
import os import os
import argparse import argparse
from px4params import srcscanner, srcparser, xmlout, dokuwikiout, dokuwikirpc from px4params import srcscanner, srcparser, xmlout, dokuwikiout, dokuwikirpc, scope, cmakeparser
import re
import codecs
def main(): def main():
# Parse command line arguments # Parse command line arguments
@@ -108,6 +111,8 @@ def main():
default="Automagically updated parameter documentation from code.", default="Automagically updated parameter documentation from code.",
help="DokuWiki page edit summary") help="DokuWiki page edit summary")
parser.add_argument('-v', '--verbose', action='store_true', help="verbose output") parser.add_argument('-v', '--verbose', action='store_true', help="verbose output")
parser.add_argument('--scope', default=None, action='store', help="pass the scope (list of compiled modules)")
args = parser.parse_args() args = parser.parse_args()
# Check for valid command # Check for valid command
@@ -122,8 +127,28 @@ def main():
# Scan directories, and parse the files # Scan directories, and parse the files
if (args.verbose): print("Scanning source path " + args.src_path) if (args.verbose): print("Scanning source path " + args.src_path)
if not scanner.ScanDir(args.src_path, parser):
sys.exit(1) use_scope = False
cmake_scope = scope.Scope();
if args.scope:
with codecs.open(args.scope, 'r', 'utf-8') as f:
try:
contents = f.read()
f.close()
cmake_parser = cmakeparser.CMakeParser()
cmake_parser.Parse(cmake_scope, contents)
use_scope = True
except:
use_scope = False
pass
if use_scope:
print(cmake_scope.scope)
if not scanner.ScanDir([os.path.join(args.src_path, p) for p in cmake_scope.scope], parser):
sys.exit(1)
else:
if not scanner.ScanDir([args.src_path], parser):
sys.exit(1)
if not parser.Validate(): if not parser.Validate():
sys.exit(1) sys.exit(1)
param_groups = parser.GetParamGroups() param_groups = parser.GetParamGroups()

View File

@@ -1014,7 +1014,7 @@ endfunction()
function(px4_generate_parameters_xml) function(px4_generate_parameters_xml)
px4_parse_function_args( px4_parse_function_args(
NAME px4_generate_parameters_xml NAME px4_generate_parameters_xml
ONE_VALUE OUT BOARD ONE_VALUE OUT BOARD SCOPE
REQUIRED OUT BOARD REQUIRED OUT BOARD
ARGN ${ARGN}) ARGN ${ARGN})
set(path ${PX4_SOURCE_DIR}/src) set(path ${PX4_SOURCE_DIR}/src)
@@ -1023,7 +1023,7 @@ function(px4_generate_parameters_xml)
) )
add_custom_command(OUTPUT ${OUT} add_custom_command(OUTPUT ${OUT}
COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/px_process_params.py COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/px_process_params.py
-s ${path} --board CONFIG_ARCH_${BOARD} --xml --inject-xml -s ${path} --board CONFIG_ARCH_${BOARD} --xml --inject-xml --scope ${SCOPE}
DEPENDS ${param_src_files} DEPENDS ${param_src_files}
) )
set(${OUT} ${${OUT}} PARENT_SCOPE) set(${OUT} ${${OUT}} PARENT_SCOPE)

View File

@@ -435,7 +435,7 @@ function(px4_nuttx_add_romfs)
--obj romfs.o --obj romfs.o
--var romfs_img --var romfs_img
--bin romfs.bin --bin romfs.bin
DEPENDS ${romfs_src_files} ${extras} DEPENDS ${romfs_src_files} ${extras} ${optional_files}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
) )
add_library(${OUT} STATIC romfs.o) add_library(${OUT} STATIC romfs.o)