-
Notifications
You must be signed in to change notification settings - Fork 8
/
SConstruct
128 lines (100 loc) · 4.55 KB
/
SConstruct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python
import os
import pathlib
import sys
from pathlib import Path
from SCons.Variables.BoolVariable import _text2bool
from methods import print_error, print_warning
if not (os.path.isdir("godot-cpp") and os.listdir("godot-cpp")):
print_error("""godot-cpp is not available within this folder, as Git submodules haven"t been initialized.
Run the following command to download godot-cpp:
git submodule update --init --recursive""")
sys.exit(1)
# ============================= Project Setup =============================
libname = "numdot"
# Load variables from custom.py, in case someone wants to store their own arguments.
# See https://scons.org/doc/production/HTML/scons-user.html#app-tools // search custom.py
customs = ["custom.py"]
customs = [os.path.abspath(path) for path in customs]
opts = Variables(customs, ARGUMENTS)
opts.Add(
PathVariable(
key="install_dir",
help="Target location for the addon. It will be appended with addons/numdot/ automatically.",
default="build",
)
)
numdot_tool = Tool("numdot")
numdot_tool.options(opts)
# Only used to evaluate our own options, lol
options_env = Environment(tools=["default"], PLATFORM="")
opts.Update(options_env)
Help(opts.GenerateHelpText(options_env))
# Remove our custom options to avoid passing to godot-cpp; godot-cpp has its own check for unknown options.
for opt in opts.options:
ARGUMENTS.pop(opt.key, None)
# ============================= Change defaults of godot-cpp =============================
if ARGUMENTS.get("platform", None) == "web":
ARGUMENTS.setdefault("threads", "no")
if _text2bool(ARGUMENTS.get("threads", "yes")):
# TODO Figure out why that is. Does godot default to no threads exports?
raise ValueError("NumDot does not currently support compiling web with threads.")
# To read up on why exceptions should be enabled, read further below.
if ARGUMENTS.get("disable_exceptions", None):
raise ValueError("NumDot does not currently support compiling without exceptions.")
ARGUMENTS["disable_exceptions"] = False
# Clarification: template_debug and template_release are, from our perspective, both releases.
# template_debug is just for in-editor
is_release = not _text2bool(ARGUMENTS.get("dev_build", "no"))
if ARGUMENTS.get("optimize", None) is None and is_release:
# The default godot-cpp optimizes for speed for release builds.
if ARGUMENTS.get("platform", None) == "web" and ARGUMENTS.get("target", "template_debug") == "template_release":
# For web, optimize binary size, can shrink by ~30%.
ARGUMENTS["optimize"] = "size"
# Load godot-cpp
godot_cpp_env = SConscript("godot-cpp/SConstruct", {"customs": customs})
env = godot_cpp_env.Clone()
for opt in opts.options:
if opt.key in options_env:
env[opt.key] = options_env[opt.key]
is_msvc = "is_msvc" in env and env["is_msvc"]
# ============================= Actual source and lib setup =============================
# TODO Can replace when https://github.com/godotengine/godot-cpp/pull/1601 is merged.
if is_release:
# Enable link-time optimization.
# This further lets the compiler optimize, reduce binary size (~.5mb) or inline functions (possibly improving speeds).
if is_msvc:
env.Append(CCFLAGS=["/GL"])
env.Append(LINKFLAGS=["/LTCG"])
else:
env.Append(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto"])
sources = []
targets = []
numdot_tool.generate(env, godot_cpp_env, sources)
# .dev doesn't inhibit compatibility, so we don't need to key it.
# .universal just means "compatible with all relevant arches" so we don't need to key it.
suffix = env['suffix'].replace(".dev", "").replace(".universal", "")
addon_dir = f"{env['install_dir']}/addons/{libname}/{env['platform']}"
if env["platform"] == "macos" or env["platform"] == "ios":
# The above defaults to creating a .dylib.
# These are not supported on the iOS app store.
# To make it consistent, we'll just use frameworks on both macOS and iOS.
framework_tool = Tool("macos-framework")
lib_filename = f"{libname}{suffix}"
library_targets = framework_tool.generate(
f"{addon_dir}/{lib_filename}.framework",
env=env,
source=sources,
bundle_identifier=f"de.ivorius.{lib_filename}"
)
else:
lib_filename = f"{env.subst('$SHLIBPREFIX')}{libname}{suffix}{env.subst('$SHLIBSUFFIX')}"
library_targets = env.SharedLibrary(
f"{addon_dir}/{lib_filename}",
source=sources,
)
targets.extend(library_targets)
# Don't remove the file while building.
env.Precious(library_targets)
Default(targets)