Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Scons] Use dependency to track bindings generation. #748

Merged
merged 1 commit into from
May 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 13 additions & 29 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import sys
import subprocess
from binding_generator import scons_generate_bindings, scons_emit_files

if sys.version_info < (3,):

Expand Down Expand Up @@ -112,13 +113,7 @@ opts.Add(
)
opts.Add(PathVariable("custom_api_file", "Path to a custom JSON API file", None, PathVariable.PathIsFile))
opts.Add(
EnumVariable(
"generate_bindings",
"Generate GDNative API bindings",
"auto",
allowed_values=["yes", "no", "auto", "true"],
ignorecase=2,
)
BoolVariable("generate_bindings", "Force GDExtension API bindings generation. Auto-detected by default.", False)
)
opts.Add(EnumVariable("android_arch", "Target Android architecture", "armv7", ["armv7", "arm64v8", "x86", "x86_64"]))
opts.Add("macos_deployment_target", "macOS deployment target", "default")
Expand Down Expand Up @@ -442,43 +437,33 @@ elif env["platform"] == "javascript":
elif env["target"] == "release":
env.Append(CCFLAGS=["-O3"])

env.Append(
CPPPATH=[
".",
env["headers_dir"],
"#include",
"#gen/include",
]
)

# Generate bindings?
# Generate bindings
env.Append(BUILDERS={"GenerateBindings": Builder(action=scons_generate_bindings, emitter=scons_emit_files)})
json_api_file = ""

if "custom_api_file" in env:
json_api_file = env["custom_api_file"]
else:
json_api_file = os.path.join(os.getcwd(), env["headers_dir"], "extension_api.json")

if env["generate_bindings"] == "auto":
# Check if generated files exist
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"]
bindings = env.GenerateBindings(
env.Dir("."), [json_api_file, os.path.join(env["headers_dir"], "godot", "gdnative_interface.h")]
)

if should_generate_bindings:
# Actually create the bindings here
import binding_generator
# Forces bindings regeneration.
if env["generate_bindings"]:
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 = []
add_sources(sources, "src", "cpp")
add_sources(sources, "src/classes", "cpp")
add_sources(sources, "src/core", "cpp")
add_sources(sources, "src/variant", "cpp")
add_sources(sources, "gen/src/variant", "cpp")
add_sources(sources, "gen/src/classes", "cpp")
sources.extend([f for f in bindings if str(f).endswith(".cpp")])

env["arch_suffix"] = env["bits"]
if env["platform"] == "android":
Expand All @@ -500,7 +485,6 @@ if env["build_library"]:
library = env.StaticLibrary(target=env.File("bin/%s" % library_name), source=sources)
Default(library)

env.Append(CPPPATH=[env.Dir(f) for f in ["gen/include", "include", "godot-headers"]])
env.Append(LIBPATH=[env.Dir("bin")])
env.Append(LIBS=library_name)
Return("env")
36 changes: 27 additions & 9 deletions binding_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from pathlib import Path


akien-mga marked this conversation as resolved.
Show resolved Hide resolved
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 = {}
end = ";"
files = []
with open(api_filepath) as api_file:
api = json.load(api_file)

Expand All @@ -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")
source_filename = source_gen_folder / "variant" / (camel_to_snake(builtin_class["name"]) + ".cpp")
if headers:
print(str(header_filename.as_posix()), end=end)
files.append(str(header_filename.as_posix()))
if sources:
print(str(source_filename.as_posix()), end=end)
files.append(str(source_filename.as_posix()))

for engine_class in api["classes"]:
# TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
Expand All @@ -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")
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
if headers:
print(str(header_filename.as_posix()), end=end)
files.append(str(header_filename.as_posix()))
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_source_path = source_gen_folder / "variant" / "utility_functions.cpp"
global_constants_header_path = include_gen_folder / "classes" / "global_constants.hpp"
if headers:
print(str(utility_functions_header_path.as_posix()), end=end)
print(str(global_constants_header_path.as_posix()), end=end)
files.append(str(utility_functions_header_path.as_posix()))
files.append(str(global_constants_header_path.as_posix()))
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="."):
Expand Down