Kaynağa Gözat

Fix cmake source file generation

Matteo De Carlo 5 yıl önce
ebeveyn
işleme
0c8dd096c4
2 değiştirilmiş dosya ile 91 ekleme ve 24 silme
  1. 28 6
      CMakeLists.txt
  2. 63 18
      binding_generator.py

+ 28 - 6
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

+ 63 - 18
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)
-
-        source_file = open("src/gen/" + strip_name(c["name"]) + ".cpp", "w+")
-        source_file.write(impl)
+        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_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_file = open("include/gen/__icalls.hpp", "w+")
-    icall_header_file.write(generate_icall_header(icalls))
+    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))
 
-    register_types_file = open("src/gen/__register_types.cpp", "w+")
-    register_types_file.write(generate_type_registry(classes))
+    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))
 
-    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 <gdnative_api_struct.gen.h>")
-    source.append("#include <stdint.h>")
+    source.append("#include <cstdint>")
     source.append("")