From 8a0a94041e3912750a3b1a7d4c8ca9821d8481a2 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Tue, 13 Oct 2020 10:09:28 -0500 Subject: [PATCH] BUG: snake case functions are erased When re-running cmake, the dependancies required to append the `snake_case_functions` to the `ITK*Config.py` files was incorrect. Resolves #515 --- Wrapping/Generators/Python/CMakeLists.txt | 10 ++++- Wrapping/Generators/Python/itkBase.py | 7 ++++ .../Generators/SwigInterface/CMakeLists.txt | 8 +++- .../Generators/SwigInterface/igenerator.py | 41 +++++++++++-------- 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/Wrapping/Generators/Python/CMakeLists.txt b/Wrapping/Generators/Python/CMakeLists.txt index 5e8382b7c92..8e4533a0b15 100644 --- a/Wrapping/Generators/Python/CMakeLists.txt +++ b/Wrapping/Generators/Python/CMakeLists.txt @@ -362,16 +362,22 @@ macro(itk_end_wrap_module_python) if(NOT "${WRAPPER_LIBRARY_NAME}" STREQUAL "ITKPyBase") set(ITK_WRAP_PYTHON_CONFIGURATION_DEPENDS "'ITKPyBase', ${ITK_WRAP_PYTHON_CONFIGURATION_DEPENDS}") set(ITK_WRAP_PYTHON_LIBRARY_IMPORTS "import itk.ITKPyBasePython\n${ITK_WRAP_PYTHON_LIBRARY_IMPORTS}") + set(ITK_WRAP_PYTHON_SNAKE_CASE "${ITK_WRAP_PYTHON_BINARY_DIR}/Configuration/${WRAPPER_LIBRARY_NAME}_snake_case.py") + else() + unset(ITK_WRAP_PYTHON_SNAKE_CASE) endif() + set(ITK_WRAP_PYTHON_LIBRARY_CONFIG_FILE "${ITK_WRAP_PYTHON_BINARY_DIR}/Configuration/${WRAPPER_LIBRARY_NAME}Config.py") # and create the file, with the var ITK_WRAP_PYTHON_CONFIGURATION_TEMPLATES and # ITK_WRAP_PYTHON_CONFIGURATION_DEPENDS created earlier configure_file("${ITK_WRAP_PYTHON_SOURCE_DIR}/ModuleConfig.py.in" - "${ITK_WRAP_PYTHON_BINARY_DIR}/Configuration/${WRAPPER_LIBRARY_NAME}Config.py" + "${ITK_WRAP_PYTHON_LIBRARY_CONFIG_FILE}" @ONLY) + WRAP_ITK_PYTHON_BINDINGS_INSTALL(/itk/Configuration "${WRAPPER_LIBRARY_NAME}" - "${ITK_WRAP_PYTHON_BINARY_DIR}/Configuration/${WRAPPER_LIBRARY_NAME}Config.py" + "${ITK_WRAP_PYTHON_LIBRARY_CONFIG_FILE}" + "${ITK_WRAP_PYTHON_SNAKE_CASE}" ) set(ITK_WRAP_PYTHON_GLOBAL_TIMESTAMP_DECLS ) diff --git a/Wrapping/Generators/Python/itkBase.py b/Wrapping/Generators/Python/itkBase.py index 9ace7dce29b..8ffa649fa9f 100644 --- a/Wrapping/Generators/Python/itkBase.py +++ b/Wrapping/Generators/Python/itkBase.py @@ -246,4 +246,11 @@ def cleanup(self): path = os.path.join(d + os.sep + "Configuration", conf) with open(path, "rb") as modulefile: exec(modulefile.read(), data) + snake_data = {} + snake_conf = module + '_snake_case.py' + snake_path = os.path.join(d + os.sep + "Configuration", snake_conf) + if os.path.exists(snake_path): + with open(snake_path, "rb") as snake_modulefile: + exec(snake_modulefile.read(), snake_data) + data.update(snake_data) module_data[module] = data diff --git a/Wrapping/Generators/SwigInterface/CMakeLists.txt b/Wrapping/Generators/SwigInterface/CMakeLists.txt index 87456fdf902..61459d63a33 100644 --- a/Wrapping/Generators/SwigInterface/CMakeLists.txt +++ b/Wrapping/Generators/SwigInterface/CMakeLists.txt @@ -334,6 +334,7 @@ macro(itk_end_wrap_module_swig_interface) set(deps_imports ) list(APPEND mdx_opts --mdx "${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/${WRAPPER_LIBRARY_NAME}.mdx") + foreach(dep ${WRAPPER_LIBRARY_DEPENDS}) list(APPEND mdx_opts --mdx "${WRAP_ITK_TYPEDEFS_DIRECTORY}/${dep}.mdx") list(APPEND deps_imports "%import ${dep}.i\n") @@ -348,8 +349,12 @@ macro(itk_end_wrap_module_swig_interface) list(LENGTH i_files number_interface_files) if(number_interface_files GREATER 0) + # NOTE: snake_case_config_file is both an input and an output to this command. + # the ${IGENERATOR} script appends to this file. + set(snake_case_config_file + "${WRAPPER_LIBRARY_OUTPUT_DIR}/Generators/Python/Configuration/${WRAPPER_LIBRARY_NAME}_snake_case.py") add_custom_command( - OUTPUT ${i_files} ${typedef_files} ${idx_files} + OUTPUT ${i_files} ${typedef_files} ${idx_files} ${snake_case_config_file} COMMAND ${Python3_EXECUTABLE} ${IGENERATOR} ${mdx_opts} ${swig_libs} @@ -357,6 +362,7 @@ macro(itk_end_wrap_module_swig_interface) -A protected -A private -p ${PYGCCXML_DIR} -g ${CASTXML_EXECUTABLE} + --snake-case-file "${snake_case_config_file}" --interface-output-dir "${WRAPPER_MASTER_INDEX_OUTPUT_DIR}" --library-output-dir "${WRAPPER_LIBRARY_OUTPUT_DIR}" --submodule-order "${WRAPPER_SUBMODULE_ORDER}" diff --git a/Wrapping/Generators/SwigInterface/igenerator.py b/Wrapping/Generators/SwigInterface/igenerator.py index d96bb624562..40efb75c911 100755 --- a/Wrapping/Generators/SwigInterface/igenerator.py +++ b/Wrapping/Generators/SwigInterface/igenerator.py @@ -1146,6 +1146,13 @@ def create_interfacefile(self, interfaceFile, idxFile, wrappersNamespace): dest="submodule_order", help="List of submodules that must be wrapped in the given order", ) + argParser.add_argument( + "-a", + "--snake-case-file", + action="store", + dest="snake_case_file", + help="The configuration file to be appended to if snake_case_functions are found", + ) options = argParser.parse_args() sys.path.insert(1, options.pygccxml_path) @@ -1234,20 +1241,22 @@ def generate_swig_input(moduleName): for moduleName in moduleNames: generate_swig_input(moduleName) - config_file = os.path.join( - options.library_output_dir, - "Generators", - "Python", - "Configuration", - os.path.basename(options.mdx[0])[:-4] + "Config.py", - ) - with open(config_file, "a") as ff: - ff.write("snake_case_functions = (") - # Ensure that the functions are sorted alphabetically to ensure consistency - # in the generated file structure. - sorted_snake_case_process_object_functions = sorted( - snake_case_process_object_functions + snake_case_file = options.snake_case_file + main_config_file = snake_case_file.replace("_snake_case.py","Config.py") + if not os.path.exists(main_config_file): + print( + f"ERROR: required {main_config_file} file does not exist\n" + f"can not append to {snake_case_file}\n" ) - for function in sorted_snake_case_process_object_functions: - ff.write("'" + function + "', ") - ff.write(")\n") + sys.exit(-1) + else: + with open(snake_case_file, "a") as ff: + ff.write("snake_case_functions = (") + # Ensure that the functions are sorted alphabetically to ensure consistency + # in the generated file structure. + sorted_snake_case_process_object_functions = sorted( + snake_case_process_object_functions + ) + for function in sorted_snake_case_process_object_functions: + ff.write("'" + function + "', ") + ff.write(")\n")