Skip to content

Commit

Permalink
Make godot-cpp installable via ScCons
Browse files Browse the repository at this point in the history
This aims to have feature parity with the installation via cmake
  • Loading branch information
ytnuf committed Nov 14, 2024
1 parent c09f7a7 commit 6f3e9ab
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 0 deletions.
2 changes: 2 additions & 0 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ if scons_cache_path is not None:
cpp_tool.generate(env)
library = env.GodotCPP()

env.InstallableGodotCPP(library)

Return("env")
95 changes: 95 additions & 0 deletions tools/godotcpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,42 @@ def options(opts, env):
opts.Add(BoolVariable("dev_build", "Developer build with dev-only debugging code (DEV_ENABLED)", False))
opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))


# Scons lack a default install prefix, so use CMake's as a default for feature parity
# https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html
opts.Add(
PathVariable(
"install_prefix_dir",
"The directory to install to",
"C:/Program Files/godot-cpp" if default_platform == "windows" else "/usr/local",
PathVariable.PathAccept,
)
)
opts.Add(
PathVariable(
"install_lib_dir",
"The directory to install the library (relative from the prefix)",
"lib",
PathVariable.PathAccept,
)
)
opts.Add(
PathVariable(
"install_include_dir",
"The directory to install the headers (relative from the prefix)",
"include",
PathVariable.PathAccept,
)
)
opts.Add(
PathVariable(
"install_data_dir",
"The directory to install misc files (relative from the prefix)",
"share/godot-cpp",
PathVariable.PathAccept,
)
)

# Add platform options (custom tools can override platforms)
for pl in sorted(set(platforms + custom_platforms)):
tool = Tool(pl, toolpath=get_platform_tools_paths(env))
Expand Down Expand Up @@ -526,6 +562,7 @@ def generate(env):
}
)
env.AddMethod(_godot_cpp, "GodotCPP")
env.AddMethod(_installable, "InstallableGodotCPP")


def _godot_cpp(env):
Expand Down Expand Up @@ -571,3 +608,61 @@ def _godot_cpp(env):

env.AppendUnique(LIBS=[env.File("bin/%s" % library_name)])
return library


def _installable(env, library):
import itertools
import json

install_lib_dir = os.path.join(env["install_prefix_dir"], env["install_lib_dir"])
install_pkgconfig_dir = os.path.join(install_lib_dir, "pkgconfig")
install_include_dir = os.path.join(env["install_prefix_dir"], env["install_include_dir"])
install_data_dir = os.path.join(env["install_prefix_dir"], env["install_data_dir"])

# Obtain the gdextension version
extension_dir = normalize_path(env.get("gdextension_dir", env.Dir("gdextension").abspath), env)
api_filename = normalize_path(
env.get("custom_api_file", env.File(extension_dir + "/extension_api.json").abspath),
env,
)
with open(api_filename, "r") as api_json_file:
api_data = json.load(api_json_file)
version_major = api_data["header"]["version_major"]
version_minor = api_data["header"]["version_minor"]
version_patch = api_data["header"]["version_patch"]
gd_version = f"{version_major}.{version_minor}.{version_patch}"
api_data = None

# Configure and install the pkgconfig file
libname = str(library[0])
pkgconfig = env.Substfile(
target="gen/godot-cpp.pc",
source="cmake/godot-cpp.pc.in",
SUBST_DICT={
"@PROJECT_NAME@": "godot-cpp",
"@CMAKE_INSTALL_LIBDIR@": install_lib_dir,
"@CMAKE_INSTALL_INCLUDEDIR@" : install_include_dir,
"@GODOT_API_VERSION@": gd_version,
"@GODOTCPP_OUTPUT_NAME@": libname,
},
)
env.Install(install_pkgconfig_dir, pkgconfig)

# Install the headers
headers_from = []
headers_to = []
for dir_from, _, file_lst in itertools.chain(os.walk("include/godot_cpp"), os.walk("gen/include/godot_cpp")):
headers_from += [os.path.join(dir_from, filename) for filename in file_lst]
dir_to = os.path.join(install_include_dir, dir_from[dir_from.find("/godot_cpp") + 1 :])
headers_to += [os.path.join(dir_to, filename) for filename in file_lst]
env.InstallAs(headers_to, headers_from)

# Install the gdextension files
interface_header = os.path.join(extension_dir, "gdextension_interface.h")
env.Install(install_include_dir, interface_header)
env.Install(install_data_dir, api_filename)

# Install the static library
env.Install(install_lib_dir, library)

env.Alias("install", env["install_prefix_dir"])

0 comments on commit 6f3e9ab

Please sign in to comment.