[Scons] Use builder to track bindings regeneration.
Using a scons Builder we now regenerate the bindings automatically when the Godot API json or header has changed. The option to force bindings regeneration (generate_bindings=yes) is retained.pull/748/head
parent
1ad24f1d5d
commit
fa698ddd12
42
SConstruct
42
SConstruct
|
@ -3,6 +3,7 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from binding_generator import scons_generate_bindings, scons_emit_files
|
||||||
|
|
||||||
if sys.version_info < (3,):
|
if sys.version_info < (3,):
|
||||||
|
|
||||||
|
@ -112,13 +113,7 @@ opts.Add(
|
||||||
)
|
)
|
||||||
opts.Add(PathVariable("custom_api_file", "Path to a custom JSON API file", None, PathVariable.PathIsFile))
|
opts.Add(PathVariable("custom_api_file", "Path to a custom JSON API file", None, PathVariable.PathIsFile))
|
||||||
opts.Add(
|
opts.Add(
|
||||||
EnumVariable(
|
BoolVariable("generate_bindings", "Force GDExtension API bindings generation. Auto-detected by default.", False)
|
||||||
"generate_bindings",
|
|
||||||
"Generate GDNative API bindings",
|
|
||||||
"auto",
|
|
||||||
allowed_values=["yes", "no", "auto", "true"],
|
|
||||||
ignorecase=2,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
opts.Add(EnumVariable("android_arch", "Target Android architecture", "armv7", ["armv7", "arm64v8", "x86", "x86_64"]))
|
opts.Add(EnumVariable("android_arch", "Target Android architecture", "armv7", ["armv7", "arm64v8", "x86", "x86_64"]))
|
||||||
opts.Add("macos_deployment_target", "macOS deployment target", "default")
|
opts.Add("macos_deployment_target", "macOS deployment target", "default")
|
||||||
|
@ -442,16 +437,8 @@ elif env["platform"] == "javascript":
|
||||||
elif env["target"] == "release":
|
elif env["target"] == "release":
|
||||||
env.Append(CCFLAGS=["-O3"])
|
env.Append(CCFLAGS=["-O3"])
|
||||||
|
|
||||||
env.Append(
|
# Generate bindings
|
||||||
CPPPATH=[
|
env.Append(BUILDERS={"GenerateBindings": Builder(action=scons_generate_bindings, emitter=scons_emit_files)})
|
||||||
".",
|
|
||||||
env["headers_dir"],
|
|
||||||
"#include",
|
|
||||||
"#gen/include",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Generate bindings?
|
|
||||||
json_api_file = ""
|
json_api_file = ""
|
||||||
|
|
||||||
if "custom_api_file" in env:
|
if "custom_api_file" in env:
|
||||||
|
@ -459,17 +446,16 @@ if "custom_api_file" in env:
|
||||||
else:
|
else:
|
||||||
json_api_file = os.path.join(os.getcwd(), env["headers_dir"], "extension_api.json")
|
json_api_file = os.path.join(os.getcwd(), env["headers_dir"], "extension_api.json")
|
||||||
|
|
||||||
if env["generate_bindings"] == "auto":
|
bindings = env.GenerateBindings(
|
||||||
# Check if generated files exist
|
env.Dir("."), [json_api_file, os.path.join(env["headers_dir"], "godot", "gdnative_interface.h")]
|
||||||
should_generate_bindings = not os.path.isfile(os.path.join(os.getcwd(), "gen", "src", "classes", "object.cpp"))
|
)
|
||||||
else:
|
|
||||||
should_generate_bindings = env["generate_bindings"] in ["yes", "true"]
|
|
||||||
|
|
||||||
if should_generate_bindings:
|
# Forces bindings regeneration.
|
||||||
# Actually create the bindings here
|
if env["generate_bindings"]:
|
||||||
import binding_generator
|
AlwaysBuild(bindings)
|
||||||
|
|
||||||
binding_generator.generate_bindings(json_api_file, env["generate_template_get_node"])
|
# Includes
|
||||||
|
env.Append(CPPPATH=[[env.Dir(d) for d in [env["headers_dir"], "include", os.path.join("gen", "include")]]])
|
||||||
|
|
||||||
# Sources to compile
|
# Sources to compile
|
||||||
sources = []
|
sources = []
|
||||||
|
@ -477,8 +463,7 @@ add_sources(sources, "src", "cpp")
|
||||||
add_sources(sources, "src/classes", "cpp")
|
add_sources(sources, "src/classes", "cpp")
|
||||||
add_sources(sources, "src/core", "cpp")
|
add_sources(sources, "src/core", "cpp")
|
||||||
add_sources(sources, "src/variant", "cpp")
|
add_sources(sources, "src/variant", "cpp")
|
||||||
add_sources(sources, "gen/src/variant", "cpp")
|
sources.extend([f for f in bindings if str(f).endswith(".cpp")])
|
||||||
add_sources(sources, "gen/src/classes", "cpp")
|
|
||||||
|
|
||||||
env["arch_suffix"] = env["bits"]
|
env["arch_suffix"] = env["bits"]
|
||||||
if env["platform"] == "android":
|
if env["platform"] == "android":
|
||||||
|
@ -500,7 +485,6 @@ if env["build_library"]:
|
||||||
library = env.StaticLibrary(target=env.File("bin/%s" % library_name), source=sources)
|
library = env.StaticLibrary(target=env.File("bin/%s" % library_name), source=sources)
|
||||||
Default(library)
|
Default(library)
|
||||||
|
|
||||||
env.Append(CPPPATH=[env.Dir(f) for f in ["gen/include", "include", "godot-headers"]])
|
|
||||||
env.Append(LIBPATH=[env.Dir("bin")])
|
env.Append(LIBPATH=[env.Dir("bin")])
|
||||||
env.Append(LIBS=library_name)
|
env.Append(LIBS=library_name)
|
||||||
Return("env")
|
Return("env")
|
||||||
|
|
|
@ -6,9 +6,9 @@ import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
def print_file_list(api_filepath, output_dir, headers=False, sources=False):
|
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||||
api = {}
|
api = {}
|
||||||
end = ";"
|
files = []
|
||||||
with open(api_filepath) as api_file:
|
with open(api_filepath) as api_file:
|
||||||
api = json.load(api_file)
|
api = json.load(api_file)
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@ def print_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||||
header_filename = include_gen_folder / "variant" / (camel_to_snake(builtin_class["name"]) + ".hpp")
|
header_filename = include_gen_folder / "variant" / (camel_to_snake(builtin_class["name"]) + ".hpp")
|
||||||
source_filename = source_gen_folder / "variant" / (camel_to_snake(builtin_class["name"]) + ".cpp")
|
source_filename = source_gen_folder / "variant" / (camel_to_snake(builtin_class["name"]) + ".cpp")
|
||||||
if headers:
|
if headers:
|
||||||
print(str(header_filename.as_posix()), end=end)
|
files.append(str(header_filename.as_posix()))
|
||||||
if sources:
|
if sources:
|
||||||
print(str(source_filename.as_posix()), end=end)
|
files.append(str(source_filename.as_posix()))
|
||||||
|
|
||||||
for engine_class in api["classes"]:
|
for engine_class in api["classes"]:
|
||||||
# TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
|
# TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
|
||||||
|
@ -36,18 +36,36 @@ def print_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||||
header_filename = include_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".hpp")
|
header_filename = include_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".hpp")
|
||||||
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
|
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
|
||||||
if headers:
|
if headers:
|
||||||
print(str(header_filename.as_posix()), end=end)
|
files.append(str(header_filename.as_posix()))
|
||||||
if sources:
|
if sources:
|
||||||
print(str(source_filename.as_posix()), end=end)
|
files.append(str(source_filename.as_posix()))
|
||||||
|
|
||||||
utility_functions_header_path = include_gen_folder / "variant" / "utility_functions.hpp"
|
utility_functions_header_path = include_gen_folder / "variant" / "utility_functions.hpp"
|
||||||
utility_functions_source_path = source_gen_folder / "variant" / "utility_functions.cpp"
|
utility_functions_source_path = source_gen_folder / "variant" / "utility_functions.cpp"
|
||||||
global_constants_header_path = include_gen_folder / "classes" / "global_constants.hpp"
|
global_constants_header_path = include_gen_folder / "classes" / "global_constants.hpp"
|
||||||
if headers:
|
if headers:
|
||||||
print(str(utility_functions_header_path.as_posix()), end=end)
|
files.append(str(utility_functions_header_path.as_posix()))
|
||||||
print(str(global_constants_header_path.as_posix()), end=end)
|
files.append(str(global_constants_header_path.as_posix()))
|
||||||
if sources:
|
if sources:
|
||||||
print(str(utility_functions_source_path.as_posix()), end=end)
|
files.append(str(utility_functions_source_path.as_posix()))
|
||||||
|
return files
|
||||||
|
|
||||||
|
|
||||||
|
def print_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||||
|
end = ";"
|
||||||
|
for f in get_file_list(api_filepath, output_dir, headers, sources):
|
||||||
|
print(f, end=end)
|
||||||
|
|
||||||
|
|
||||||
|
def scons_emit_files(target, source, env):
|
||||||
|
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)]
|
||||||
|
env.Clean(files, target)
|
||||||
|
return [target[0]] + files, source
|
||||||
|
|
||||||
|
|
||||||
|
def scons_generate_bindings(target, source, env):
|
||||||
|
generate_bindings(str(source[0]), env["generate_template_get_node"], target[0].abspath)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def generate_bindings(api_filepath, use_template_get_node, output_dir="."):
|
def generate_bindings(api_filepath, use_template_get_node, output_dir="."):
|
||||||
|
|
Loading…
Reference in New Issue