From 0c8dd096c45eef0a71ff113d59e1cc3d1b60c835 Mon Sep 17 00:00:00 2001 From: Matteo De Carlo Date: Sun, 2 Feb 2020 20:47:45 +0100 Subject: [PATCH] Fix cmake source file generation --- CMakeLists.txt | 34 +++++++++++++++---- binding_generator.py | 81 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 91 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 773cbf0..e0e3b7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,23 +141,45 @@ else() endif() message(STATUS "Generating Bindings") -execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "import binding_generator; binding_generator.generate_bindings(\"${GODOT_CUSTOM_API_FILE}\", ${GENERATE_BINDING_PARAMETERS})" +execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "import binding_generator; binding_generator.print_file_list(\"${GODOT_CUSTOM_API_FILE}\", \"${CMAKE_CURRENT_BINARY_DIR}\", headers=True)" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - RESULT_VARIABLE GENERATION_RESULT - OUTPUT_VARIABLE GENERATION_OUTPUT) -message(STATUS ${GENERATION_RESULT} ${GENERATION_OUTPUT}) + RESULT_VARIABLE HEADERS_FILE_LIST_RESULT + OUTPUT_VARIABLE HEADERS_FILE_LIST +) +set(HEADERS_FILE_LIST ${HEADERS_FILE_LIST}) + +execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "import binding_generator; binding_generator.print_file_list(\"${GODOT_CUSTOM_API_FILE}\", \"${CMAKE_CURRENT_BINARY_DIR}\", sources=True)" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + RESULT_VARIABLE SOURCES_FILE_LIST_RESULT + OUTPUT_VARIABLE SOURCES_FILE_LIST +) +set(SOURCES_FILE_LIST ${SOURCES_FILE_LIST}) + +add_custom_command(OUTPUT ${HEADERS_FILE_LIST} ${SOURCES_FILE_LIST} + COMMAND "${PYTHON_EXECUTABLE}" "-c" "import binding_generator; binding_generator.generate_bindings(\"${GODOT_CUSTOM_API_FILE}\", \"${GENERATE_BINDING_PARAMETERS}\", \"${CMAKE_CURRENT_BINARY_DIR}\")" + VERBATIM + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + MAIN_DEPENDENCY ${GODOT_CUSTOM_API_FILE} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/binding_generator.py + COMMENT Generating Bindings +) # Get Sources file(GLOB_RECURSE SOURCES src/*.c**) file(GLOB_RECURSE HEADERS include/*.h**) # Define our godot-cpp library -add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS}) +add_library(${PROJECT_NAME} + ${SOURCES} + ${SOURCES_FILE_LIST} + ${HEADERS} + ${HEADERS_FILE_LIST} +) target_include_directories(${PROJECT_NAME} PUBLIC include include/core - include/gen + ${CMAKE_CURRENT_BINARY_DIR}/include/gen/ ) # Put godot headers as SYSTEM PUBLIC to exclude warnings from irrelevant headers diff --git a/binding_generator.py b/binding_generator.py index 410f8ff..491acbe 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -1,8 +1,8 @@ #!/usr/bin/env python - +from __future__ import print_function import json - -# comment. +import os +import errno # Convenience function for using template get_node def correct_method_name(method_list): @@ -13,15 +13,56 @@ def correct_method_name(method_list): classes = [] -def generate_bindings(path, use_template_get_node): +def print_file_list(api_filepath, output_dir, headers=False, sources=False): global classes - classes = json.load(open(path)) + end = ';' + with open(api_filepath) as api_file: + classes = json.load(api_file) + include_gen_folder = os.path.join(output_dir, 'include', 'gen') + source_gen_folder = os.path.join(output_dir, 'src', 'gen') + for _class in classes: + header_filename = os.path.join(include_gen_folder, strip_name(_class["name"]) + ".hpp") + source_filename = os.path.join(source_gen_folder, strip_name(_class["name"]) + ".cpp") + if headers: + print(header_filename, end=end) + if sources: + print(source_filename, end=end) + icall_header_filename = os.path.join(include_gen_folder, '__icalls.hpp') + register_types_filename = os.path.join(source_gen_folder, '__register_types.cpp') + init_method_bindings_filename = os.path.join(source_gen_folder, '__init_method_bindings.cpp') + if headers: + print(icall_header_filename, end=end) + if sources: + print(register_types_filename, end=end) + print(init_method_bindings_filename, end=end) + + +def generate_bindings(api_filepath, use_template_get_node, output_dir="."): + global classes + with open(api_filepath) as api_file: + classes = json.load(api_file) icalls = set() + include_gen_folder = os.path.join(output_dir, 'include', 'gen') + source_gen_folder = os.path.join(output_dir, 'src', 'gen') + try: + os.makedirs(include_gen_folder) + except os.error as e: + if e.errno == errno.EEXIST: + print(include_gen_folder + ": " + os.strerror(e.errno)) + else: + exit(1) + try: + os.makedirs(source_gen_folder) + except os.error as e: + if e.errno == errno.EEXIST: + print(source_gen_folder + ": " + os.strerror(e.errno)) + else: + exit(1) for c in classes: - # print c['name'] + # print(c['name']) used_classes = get_used_classes(c) if use_template_get_node and c["name"] == "Node": correct_method_name(c["methods"]) @@ -30,21 +71,25 @@ def generate_bindings(path, use_template_get_node): impl = generate_class_implementation(icalls, used_classes, c, use_template_get_node) - header_file = open("include/gen/" + strip_name(c["name"]) + ".hpp", "w+") - header_file.write(header) + header_filename = os.path.join(include_gen_folder, strip_name(c["name"]) + ".hpp") + with open(header_filename, "w+") as header_file: + header_file.write(header) - source_file = open("src/gen/" + strip_name(c["name"]) + ".cpp", "w+") - source_file.write(impl) + source_filename = os.path.join(source_gen_folder, strip_name(c["name"]) + ".cpp") + with open(source_filename, "w+") as source_file: + source_file.write(impl) + icall_header_filename = os.path.join(include_gen_folder, '__icalls.hpp') + with open(icall_header_filename, "w+") as icall_header_file: + icall_header_file.write(generate_icall_header(icalls)) - icall_header_file = open("include/gen/__icalls.hpp", "w+") - icall_header_file.write(generate_icall_header(icalls)) + register_types_filename = os.path.join(source_gen_folder, '__register_types.cpp') + with open(register_types_filename, "w+") as register_types_file: + register_types_file.write(generate_type_registry(classes)) - register_types_file = open("src/gen/__register_types.cpp", "w+") - register_types_file.write(generate_type_registry(classes)) - - init_method_bindings_file = open("src/gen/__init_method_bindings.cpp", "w+") - init_method_bindings_file.write(generate_init_method_bindings(classes)) + init_method_bindings_filename = os.path.join(source_gen_folder, '__init_method_bindings.cpp') + with open(init_method_bindings_filename, "w+") as init_method_bindings_file: + init_method_bindings_file.write(generate_init_method_bindings(classes)) def is_reference_type(t): @@ -80,7 +125,7 @@ def generate_class_header(used_classes, c, use_template_get_node): source.append("") source.append("#include ") - source.append("#include ") + source.append("#include ") source.append("")