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}
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})
add_custom_target(xml_gen
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 re
import codecs
import sys
class SourceScanner(object):
"""
@@ -8,24 +9,25 @@ class SourceScanner(object):
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
parser.Parse method.
"""
extensions1 = tuple([".h"])
extensions2 = tuple([".cpp", ".c"])
for dirname, dirnames, filenames in os.walk(srcdir):
for filename in filenames:
if filename.endswith(extensions1):
path = os.path.join(dirname, filename)
if not self.ScanFile(path, parser):
return False
for filename in filenames:
if filename.endswith(extensions2):
path = os.path.join(dirname, filename)
if not self.ScanFile(path, parser):
return False
for srcdir in srcdirs:
for dirname, dirnames, filenames in os.walk(srcdir):
for filename in filenames:
if filename.endswith(extensions1):
path = os.path.join(dirname, filename)
if not self.ScanFile(path, parser):
return False
for filename in filenames:
if filename.endswith(extensions2):
path = os.path.join(dirname, filename)
if not self.ScanFile(path, parser):
return False
return True
def ScanFile(self, path, parser):

View File

@@ -3,87 +3,23 @@ import xml.etree.ElementTree as ET
import os
import re
import codecs
import sys
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
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
from px4params import scope, cmakeparser
if len(os.sys.argv) < 2:
print("Error in %s" % os.sys.argv[0])
print("Usage: %s <parameters.xml> [cmake-file-scoping] " % os.sys.argv[0])
raise SystemExit
print("Error in %s" % os.sys.argv[0])
print("Usage: %s <parameters.xml> [cmake-file-scoping] " % os.sys.argv[0])
raise SystemExit
scope = Scope()
cmake_scope = scope.Scope()
if len(os.sys.argv) == 3:
with codecs.open(os.sys.argv[2], 'r', 'utf-8') as f:
try:
contents = f.read()
f.close()
parser = CMakeParser()
parser.Parse(scope, contents)
parser = cmakeparser.CMakeParser()
parser.Parse(cmake_scope, contents)
except:
contents = ''
print('Failed reading file: %s, skipping scoping.' % os.sys.argv[2])
@@ -110,7 +46,9 @@ struct px4_parameters_t {
start_name = ""
end_name = ""
sys.stderr.write("cmake_scope: " + str(cmake_scope) + "\n")
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:
section = """
/*****************************************************************
@@ -118,7 +56,7 @@ for group in root:
****************************************************************/""" % group.attrib["name"]
for param in group:
scope_ = param.find('scope').text
if not scope.Has(scope_):
if not cmake_scope.Has(scope_):
continue
if not start_name:
start_name = param.attrib["name"]
@@ -156,7 +94,7 @@ for group in root:
****************************************************************/""" % group.attrib["name"]
for param in group:
scope_ = param.find('scope').text
if not scope.Has(scope_):
if not cmake_scope.Has(scope_):
continue
if not start_name:
start_name = param.attrib["name"]

View File

@@ -50,7 +50,10 @@ from __future__ import print_function
import sys
import os
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():
# Parse command line arguments
@@ -108,6 +111,8 @@ def main():
default="Automagically updated parameter documentation from code.",
help="DokuWiki page edit summary")
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()
# Check for valid command
@@ -122,8 +127,28 @@ def main():
# Scan directories, and parse the files
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():
sys.exit(1)
param_groups = parser.GetParamGroups()

View File

@@ -1014,7 +1014,7 @@ endfunction()
function(px4_generate_parameters_xml)
px4_parse_function_args(
NAME px4_generate_parameters_xml
ONE_VALUE OUT BOARD
ONE_VALUE OUT BOARD SCOPE
REQUIRED OUT BOARD
ARGN ${ARGN})
set(path ${PX4_SOURCE_DIR}/src)
@@ -1023,7 +1023,7 @@ function(px4_generate_parameters_xml)
)
add_custom_command(OUTPUT ${OUT}
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}
)
set(${OUT} ${${OUT}} PARENT_SCOPE)

View File

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