diff --git a/JsonGenerator/source/config.py b/JsonGenerator/source/config.py index 34360fb6..28414a0b 100644 --- a/JsonGenerator/source/config.py +++ b/JsonGenerator/source/config.py @@ -16,6 +16,7 @@ # limitations under the License. import os +import sys import posixpath import argparse from enum import Enum @@ -29,6 +30,7 @@ ENUM_SUFFIX = "Type" # Configurables +PROJECT_DIRECTORY = None CLASSNAME_FROM_REF = True DEFAULT_INT_SIZE = 32 DEFAULT_DEFINITIONS_FILE = "../../ProxyStubGenerator/default.h" @@ -101,6 +103,7 @@ def __call__(self, parser, namespace, values, option_string): def Parse(cmdline): + global PROJECT_DIRECTORY global FRAMEWORK_NAMESPACE global DEFAULT_DEFINITIONS_FILE global INTERFACE_NAMESPACES @@ -140,32 +143,49 @@ def Parse(cmdline): argparser.add_argument('path', nargs="*", help="JSON file(s) and/or C++ header files, wildcards are allowed") - argparser.add_argument("-d", - "--docs", + argparser.add_argument("-d", "--docs", dest="docs", action="store_true", default=False, help="generate documentation") - argparser.add_argument("-c", - "--code", + argparser.add_argument("-c", "--code", dest="code", action="store_true", default=False, help="generate C++ code building JSON classes and complete JSON-RPC functionality (the latter only if applicable)") - argparser.add_argument("-o", - "--output", + argparser.add_argument("-o", "--output-dir", dest="output_dir", metavar="PATH", action="store", default=None, help="output directory, absolute path or directory relative to output file (default: output in the same directory as the source file)") + argparser.add_argument("--output", + dest="output_dir", + metavar="PATH", + action="store", + default=None, + help=argparse.SUPPRESS) # deprecated argparser.add_argument( - "--cpp-output", + "--cpp-output-dir", dest="cpp_output_dir", metavar="PATH", action="store", default=None, help="output directory for cpp files, absolute path or directory relative to output file") + argparser.add_argument( + "--cpp-output", + dest="cpp_output_dir", + metavar="PATH", + action="store", + default=None, + help=argparse.SUPPRESS) # deprecated + argparser.add_argument( + "--project-dir", + dest="project_dir", + metavar="PATH", + action="store", + default=None, + help="project directory (where to look for Ids.h and Module.h, default: same location as the source file)") argparser.add_argument( "--force", dest="force", @@ -413,6 +433,12 @@ def Parse(cmdline): EMIT_OPTIONAL_CHECKS = args.optional_checks STRICT_VALIDATION = args.strict_validation + if args.project_dir: + if not os.path.isdir(args.project_dir): + sys.exit("ERROR: Project path '%s' is not a valid directory" % args.project_dir) + else: + PROJECT_DIRECTORY = args.project_dir + # index validation follows parameter validation setting unless it's explicitly set STRICT_INDEX_VALIDATION = args.strict_validation if args.strict_index_validation is None else args.strict_index_validation diff --git a/JsonGenerator/source/header_loader.py b/JsonGenerator/source/header_loader.py index fbcbdc40..5bf7bc98 100644 --- a/JsonGenerator/source/header_loader.py +++ b/JsonGenerator/source/header_loader.py @@ -1623,8 +1623,14 @@ def LoadInterface(file, log, all, include_paths): files = [] files.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), posixpath.normpath(config.DEFAULT_DEFINITIONS_FILE))) - files.append("@" + os.path.join(source_path, MODULE_FILE)) - files.append("@" + os.path.join(source_path, IDS_FILE)) + + if config.PROJECT_DIRECTORY: + files.append("@" + os.path.join(config.PROJECT_DIRECTORY, MODULE_FILE)) + files.append("@" + os.path.join(config.PROJECT_DIRECTORY, IDS_FILE)) + else: + files.append("@" + os.path.join(source_path, MODULE_FILE)) + files.append("@" + os.path.join(source_path, IDS_FILE)) + files.append(file) tree = CppParser.ParseFiles(files, config.FRAMEWORK_NAMESPACE, include_paths, log) diff --git a/ProxyStubGenerator/StubGenerator.py b/ProxyStubGenerator/StubGenerator.py index 2cb9bdff..76aaf119 100755 --- a/ProxyStubGenerator/StubGenerator.py +++ b/ProxyStubGenerator/StubGenerator.py @@ -65,6 +65,8 @@ MODULE_FILE = "Module.h" IDS_FILE = "Ids.h" +PROJECT_DIRECTORY = None + log = Log.Log(NAME, BE_VERBOSE, SHOW_WARNINGS) @@ -2712,8 +2714,12 @@ def EmitRegistration(announce_list): emit.Line() - if os.path.isfile(os.path.join(os.path.dirname(source_file), "Module.h")): - emit.Line('#include "Module.h"') + if PROJECT_DIRECTORY: + if os.path.isfile(os.path.join(PROJECT_DIRECTORY, MODULE_FILE)): + emit.Line('#include "%s"' % MODULE_FILE) + else: + if os.path.isfile(os.path.join(os.path.dirname(source_file), MODULE_FILE)): + emit.Line('#include "%s"' % MODULE_FILE) if os.path.isfile(os.path.join(os.path.dirname(source_file), interface_header_name)): emit.Line('#include "%s"' % interface_header_name) @@ -2818,12 +2824,18 @@ def EmitRegistration(announce_list): action="store", default=FRAMEWORK_NAMESPACE, help="set framework namespace (default: %s)" % FRAMEWORK_NAMESPACE) - argparser.add_argument("--outdir", - dest="outdir", + argparser.add_argument("-o", "--output-dir", + dest="output_directory", metavar="DIR", action="store", - default="", + default=None, help="specify output directory (default: generate files in the same directory as source)") + argparser.add_argument("--outdir", + dest="output_directory", + metavar="DIR", + action="store", + default=None, + help=argparse.SUPPRESS) # deprecated argparser.add_argument("--no-warnings", dest="no_warnings", action="store_true", @@ -2849,13 +2861,30 @@ def EmitRegistration(announce_list): action="store_true", default=ENABLE_ITERATOR_OPTIMIZATION, help="pass collated iterator data in one go (default: pass interface)") + argparser.add_argument("--project-dir", + dest="project_directory", + metavar="PATH", + type=str, + default=None, + help="project directory (where to look for Ids.h and Module.h, default: same location as the source file)") + argparser.add_argument("--projectdir", + dest="project_directory", + metavar="PATH", + type=str, + default=None, + help=argparse.SUPPRESS) # deprecated argparser.add_argument("-i", dest="extra_includes", metavar="FILE", action='append', default=[], help="include an additional C++ header file, can be used multiple times") - argparser.add_argument('-I', dest="includePaths", metavar="INCLUDE_DIR", action='append', default=[], type=str, + argparser.add_argument('-I', + dest="includePaths", + metavar="PATH", + action='append', + default=[], + type=str, help='add an include search path, can be used multiple times') args = argparser.parse_args(sys.argv[1:]) @@ -2869,11 +2898,17 @@ def EmitRegistration(announce_list): ENABLE_ITERATOR_OPTIMIZATION = args.collated_iterators log.show_infos = BE_VERBOSE log.show_warnings = SHOW_WARNINGS - OUTDIR = args.outdir + OUTPUT_DIRECTORY = args.output_directory EMIT_TRACES = args.traces scan_only = False keep_incomplete = args.keep_incomplete + if args.project_directory: + if not os.path.isdir(args.project_directory): + sys.exit("ERROR: Project path '%s' is not a valid directory" % args.project_directory) + else: + PROJECT_DIRECTORY = args.project_directory + if args.framework_namespace: FRAMEWORK_NAMESPACE = args.framework_namespace STUB_NAMESPACE = "::%s::ProxyStubs" % FRAMEWORK_NAMESPACE @@ -2994,7 +3029,12 @@ def EmitRegistration(announce_list): if interface_files: if args.lua_code: name = "protocol-thunder-comrpc.data" - output_file = ("." if not OUTDIR else OUTDIR) + os.sep + name + output_file = os.path.join(("." if not OUTPUT_DIRECTORY else OUTPUT_DIRECTORY), name) + + out_dir = os.path.dirname(output_file) + if not os.path.exists(out_dir): + os.makedirs(out_dir) + lua_file = open(output_file, "w") emit = Emitter(lua_file, INDENT_SIZE) lua_interfaces = dict() @@ -3005,8 +3045,15 @@ def EmitRegistration(announce_list): source_path = os.path.dirname(source_file) extra_includes = [] - extra_includes.append("@" + os.path.join(source_path, MODULE_FILE)) - extra_includes.append("@" + os.path.join(source_path, IDS_FILE)) + + if PROJECT_DIRECTORY: + extra_includes.append("@" + os.path.join(PROJECT_DIRECTORY, MODULE_FILE)) + extra_includes.append("@" + os.path.join(PROJECT_DIRECTORY, IDS_FILE)) + else: + extra_includes.append("@" + os.path.join(source_path, MODULE_FILE)) + extra_includes.append("@" + os.path.join(source_path, IDS_FILE)) + + extra_includes.extend(args.extra_includes) definition_file = "@" + os.path.join(os.path.dirname(os.path.realpath(__file__)), DEFAULT_DEFINITIONS_FILE) @@ -3016,7 +3063,7 @@ def EmitRegistration(announce_list): if args.code: log.Header(source_file) - output_file = os.path.join(os.path.dirname(source_file) if not OUTDIR else OUTDIR, + output_file = os.path.join(os.path.dirname(source_file) if not OUTPUT_DIRECTORY else OUTPUT_DIRECTORY, PROXYSTUB_CPP_NAME % CreateName(os.path.basename(source_file)).split(".", 1)[0]) out_dir = os.path.dirname(output_file) diff --git a/cmake/FindJsonGenerator.cmake.in b/cmake/FindJsonGenerator.cmake.in index 188c6ea8..a09c06c2 100644 --- a/cmake/FindJsonGenerator.cmake.in +++ b/cmake/FindJsonGenerator.cmake.in @@ -36,7 +36,7 @@ function(JsonGenerator) set(optionsArgs ${optionsArgs} AUTO_PREFIX NO_AUTO_PREFIX COPY_CTOR NO_COPY_CTOR DUPLICATE_OBJ_WARNINGS NO_DUPLICATE_OBJ_WARNINGS STATS NO_STATS) set(optionsArgs ${optionsArgs} STRICT_VALIDATION NO_STRICT_VALIDATION STRICT_INDEX_VALIDATION NO_STRICT_INDEX_VALIDATION) set(optionsArgs ${optionsArgs} OPTIONAL_CHECKS NO_OPTIONAL_CHECKS RESTRICT_CHECKS NO_RESTRICT_CHECKS) - set(oneValueArgs OUTPUT CPP_OUTPUT INDENT DEF_INT_SIZE FORMAT CPP_INTERFACE_PATH JSON_INTERFACE_PATH FRAMEWORK_NAMESPACE CASE_CONVENTION) + set(oneValueArgs OUTPUT OUTPUT_DIR CPP_OUTPUT CPP_OUTPUT_DIR PROJECT_DIR INDENT DEF_INT_SIZE FORMAT CPP_INTERFACE_PATH JSON_INTERFACE_PATH FRAMEWORK_NAMESPACE CASE_CONVENTION) set(multiValueArgs INPUT IFDIR CPPIFDIR INCLUDE_PATH NAMESPACE) cmake_parse_arguments(Argument "${optionsArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) @@ -185,14 +185,29 @@ function(JsonGenerator) list(APPEND _execute_command "-j" "${_include_path}") endforeach(_include_path) - if (Argument_OUTPUT) + if (Argument_OUTPUT_DIR) + file(MAKE_DIRECTORY "${Argument_OUTPUT_DIR}") + list(APPEND _execute_command "--output-dir" "${Argument_OUTPUT_DIR}") + elseif (Argument_OUTPUT) + # deprecated file(MAKE_DIRECTORY "${Argument_OUTPUT}") - list(APPEND _execute_command "--output" "${Argument_OUTPUT}") + list(APPEND _execute_command "--output-dir" "${Argument_OUTPUT}") endif() - if (Argument_CPP_OUTPUT) + if (Argument_CPP_OUTPUT_DIR) + file(MAKE_DIRECTORY "${Argument_CPP_OUTPUT_DIR}") + list(APPEND _execute_command "--cpp-output-dir" "${Argument_CPP_OUTPUT_DIR}") + elseif(Argument_CPP_OUTPUT) + # deprecated file(MAKE_DIRECTORY "${Argument_CPP_OUTPUT}") - list(APPEND _execute_command "--cpp-output" "${Argument_CPP_OUTPUT}") + list(APPEND _execute_command "--cpp-output-dir" "${Argument_CPP_OUTPUT}") + endif() + + if (Argument_PROJECT_DIR) + if(NOT IS_DIRECTORY "${Argument_PROJECT_DIR}") + message(FATAL_ERROR "JsonGenerator PROJECT_DIR '${Argument_PROJECT_DIR}' is not a directory.") + endif() + list(APPEND _execute_command "--project-dir" "${Argument_PROJECT_DIR}") endif() if (Argument_INDENT) diff --git a/cmake/FindProxyStubGenerator.cmake.in b/cmake/FindProxyStubGenerator.cmake.in index ea35844c..5ccd1ab9 100644 --- a/cmake/FindProxyStubGenerator.cmake.in +++ b/cmake/FindProxyStubGenerator.cmake.in @@ -33,7 +33,7 @@ function(ProxyStubGenerator) endif() set(optionsArgs SECURE COHERENT TRACES VERBOSE NO_WARNINGS KEEP FORCE_GENERATE COLLATED_ITERATORS) - set(oneValueArgs OUTDIR FRAMEWORK_NAMESPACE) + set(oneValueArgs OUTDIR OUTPUT_DIR PROJECT_DIR FRAMEWORK_NAMESPACE) set(multiValueArgs INPUT INCLUDE INCLUDE_PATH NAMESPACE) cmake_parse_arguments(Argument "${optionsArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) @@ -82,9 +82,20 @@ function(ProxyStubGenerator) list(APPEND _execute_command "--framework-namespace" "${Argument_FRAMEWORK_NAMESPACE}") endif() - if(Argument_OUTDIR) + if(Argument_OUTPUT_DIR) + file(MAKE_DIRECTORY "${Argument_OUTPUT_DIR}") + list(APPEND _execute_command "--output-dir" "${Argument_OUTPUT_DIR}") + elseif(Argument_OUTDIR) + # deprecated file(MAKE_DIRECTORY "${Argument_OUTDIR}") - list(APPEND _execute_command "--outdir" "${Argument_OUTDIR}") + list(APPEND _execute_command "--output-dir" "${Argument_OUTDIR}") + endif() + + if(Argument_PROJECT_DIR) + if(NOT IS_DIRECTORY "${Argument_PROJECT_DIR}") + message(FATAL_ERROR "ProxyStubGenerator PROJECT_DIR '${Argument_PROJECT_DIR}' is not a directory.") + endif() + list(APPEND _execute_command "--project-dir" "${Argument_PROJECT_DIR}") endif() foreach(_namespace ${Argument_NAMESPACE})