Browse Source

[SCons] Refactor targets, symbols, optimizations.

Now matches Godot `master` target names and supports the same flags with
the following notable exceptions:
- The default target is "template_debug", since it's compatible with
  editor builds (and TOOLS_ENABLED is never used internally).
- separate_debug_symbols is still not supported, and will be done in a
  separate commit.
Fabio Alessandrelli 2 years ago
parent
commit
64b2c9be0b

+ 11 - 11
.github/workflows/ci.yml

@@ -21,14 +21,14 @@ jobs:
             os: ubuntu-18.04
             platform: linux
             artifact-name: godot-cpp-linux-glibc2.27-x86_64-release
-            artifact-path: bin/libgodot-cpp.linux.release.x86_64.a
+            artifact-path: bin/libgodot-cpp.linux.template_release.x86_64.a
             cache-name: linux-x86_64
 
           - name: 🐧 Linux (GCC, Double Precision)
             os: ubuntu-18.04
             platform: linux
             artifact-name: godot-cpp-linux-glibc2.27-x86_64-double-release
-            artifact-path: bin/libgodot-cpp.linux.release.x86_64.a
+            artifact-path: bin/libgodot-cpp.linux.template_release.double.x86_64.a
             flags: float=64
             cache-name: linux-x86_64-f64
 
@@ -36,14 +36,14 @@ jobs:
             os: windows-2019
             platform: windows
             artifact-name: godot-cpp-windows-msvc2019-x86_64-release
-            artifact-path: bin/libgodot-cpp.windows.release.x86_64.lib
+            artifact-path: bin/libgodot-cpp.windows.template_release.x86_64.lib
             cache-name: windows-x86_64-msvc
 
           - name: 🏁 Windows (x86_64, MinGW)
             os: windows-2019
             platform: windows
             artifact-name: godot-cpp-linux-mingw-x86_64-release
-            artifact-path: bin/libgodot-cpp.windows.release.x86_64.a
+            artifact-path: bin/libgodot-cpp.windows.template_release.x86_64.a
             flags: use_mingw=yes
             cache-name: windows-x86_64-mingw
 
@@ -51,7 +51,7 @@ jobs:
             os: macos-11
             platform: macos
             artifact-name: godot-cpp-macos-universal-release
-            artifact-path: bin/libgodot-cpp.macos.release.universal.a
+            artifact-path: bin/libgodot-cpp.macos.template_release.universal.a
             flags: arch=universal
             cache-name: macos-universal
 
@@ -59,7 +59,7 @@ jobs:
             os: ubuntu-18.04
             platform: android
             artifact-name: godot-cpp-android-arm64-release
-            artifact-path: bin/libgodot-cpp.android.release.arm64.a
+            artifact-path: bin/libgodot-cpp.android.template_release.arm64.a
             flags: ANDROID_NDK_ROOT=$ANDROID_NDK_LATEST_HOME arch=arm64
             cache-name: android-arm64
 
@@ -67,7 +67,7 @@ jobs:
             os: macos-11
             platform: ios
             artifact-name: godot-cpp-ios-arm64-release
-            artifact-path: bin/libgodot-cpp.ios.release.arm64.a
+            artifact-path: bin/libgodot-cpp.ios.template_release.arm64.a
             flags: arch=arm64
             cache-name: ios-arm64
 
@@ -107,17 +107,17 @@ jobs:
 
       - name: Build godot-cpp (debug)
         run: |
-          scons platform=${{ matrix.platform }} target=debug ${{ matrix.flags }}
+          scons platform=${{ matrix.platform }} target=template_debug ${{ matrix.flags }}
 
       - name: Build test without rebuilding godot-cpp (debug)
         run: |
           cd test
-          scons platform=${{ matrix.platform }} target=debug ${{ matrix.flags }} build_library=no
+          scons platform=${{ matrix.platform }} target=template_debug ${{ matrix.flags }} build_library=no
 
-      - name: Build test and godot-cpp (release, with debug symbols)
+      - name: Build test and godot-cpp (release)
         run: |
           cd test
-          scons platform=${{ matrix.platform }} target=release debug_symbols=yes ${{ matrix.flags }}
+          scons platform=${{ matrix.platform }} target=template_release ${{ matrix.flags }}
 
       - name: Upload artifact
         uses: actions/upload-artifact@v3

+ 3 - 0
.gitignore

@@ -8,6 +8,9 @@
 include/gen
 src/gen
 
+# Build configuarion.
+/custom.py
+
 # Misc
 logs/*
 *.log

+ 28 - 11
SConstruct

@@ -48,8 +48,17 @@ if env.GetOption("num_jobs") == altered_num_jobs:
         )
         env.SetOption("num_jobs", safer_cpu_count)
 
+# Custom options and profile flags.
+customs = ["custom.py"]
+profile = ARGUMENTS.get("profile", "")
+if profile:
+    if os.path.isfile(profile):
+        customs.append(profile)
+    elif os.path.isfile(profile + ".py"):
+        customs.append(profile + ".py")
+opts = Variables(customs, ARGUMENTS)
+
 platforms = ("linux", "macos", "windows", "android", "ios", "javascript")
-opts = Variables([], ARGUMENTS)
 opts.Add(
     EnumVariable(
         "platform",
@@ -60,8 +69,12 @@ opts.Add(
     )
 )
 
-# Must be the same setting as used for cpp_bindings
-opts.Add(EnumVariable("target", "Compilation target", "debug", allowed_values=("debug", "release"), ignorecase=2))
+# Editor and template_debug are compatible (i.e. you can use the same binary for Godot editor builds and Godot debug templates).
+# Godot release templates are only compatible with "template_release" builds.
+# For this reason, we default to template_debug builds, unlike Godot which defaults to editor builds.
+opts.Add(
+    EnumVariable("target", "Compilation target", "template_debug", ("editor", "template_release", "template_debug"))
+)
 opts.Add(
     PathVariable(
         "headers_dir", "Path to the directory containing Godot headers", "godot-headers", PathVariable.PathIsDir
@@ -156,13 +169,9 @@ if env.get("is_msvc", False):
 else:
     env.Append(CXXFLAGS=["-std=c++17"])
 
-if env["target"] == "debug":
-    env.Append(CPPDEFINES=["DEBUG_ENABLED", "DEBUG_METHODS_ENABLED"])
-
 if env["float"] == "64":
     env.Append(CPPDEFINES=["REAL_T_IS_DOUBLE"])
 
-
 # Generate bindings
 env.Append(BUILDERS={"GenerateBindings": Builder(action=scons_generate_bindings, emitter=scons_emit_files)})
 json_api_file = ""
@@ -198,13 +207,21 @@ add_sources(sources, "src/core", "cpp")
 add_sources(sources, "src/variant", "cpp")
 sources.extend([f for f in bindings if str(f).endswith(".cpp")])
 
-env["arch_suffix"] = env["arch"]
+suffix = ".{}.{}".format(env["platform"], env["target"])
+if env.dev_build:
+    suffix += ".dev"
+if env["float"] == "64":
+    suffix += ".double"
+suffix += "." + env["arch"]
 if env["ios_simulator"]:
-    env["arch_suffix"] += ".simulator"
+    suffix += ".simulator"
+
+# Expose it when included from another project
+env["suffix"] = suffix
 
 library = None
-env["OBJSUFFIX"] = ".{}.{}.{}{}".format(env["platform"], env["target"], env["arch_suffix"], env["OBJSUFFIX"])
-library_name = "libgodot-cpp.{}.{}.{}{}".format(env["platform"], env["target"], env["arch_suffix"], env["LIBSUFFIX"])
+env["OBJSUFFIX"] = suffix + env["OBJSUFFIX"]
+library_name = "libgodot-cpp{}{}".format(suffix, env["LIBSUFFIX"])
 
 if env["build_library"]:
     library = env.StaticLibrary(target=env.File("bin/%s" % library_name), source=sources)

+ 1 - 3
test/SConstruct

@@ -25,9 +25,7 @@ if env["platform"] == "macos":
     )
 else:
     library = env.SharedLibrary(
-        "demo/bin/libgdexample.{}.{}.{}{}".format(
-            env["platform"], env["target"], env["arch_suffix"], env["SHLIBSUFFIX"]
-        ),
+        "demo/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
         source=sources,
     )
 

+ 2 - 2
test/demo/bin/libgdexample.osx.debug.framework/Resources/Info.plist → test/demo/bin/libgdexample.osx.template_debug.framework/Resources/Info.plist

@@ -3,13 +3,13 @@
 <plist version="1.0">
 <dict>
 	<key>CFBundleExecutable</key>
-	<string>libgdexample.debug</string>
+	<string>libgdexample.template_debug</string>
 	<key>CFBundleIdentifier</key>
 	<string>org.godotengine.libgdexample</string>
 	<key>CFBundleInfoDictionaryVersion</key>
 	<string>6.0</string>
 	<key>CFBundleName</key>
-	<string>libgdexample.osx.debug</string>
+	<string>libgdexample.macos.template_debug</string>
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<key>CFBundleShortVersionString</key>

+ 2 - 2
test/demo/bin/libgdexample.osx.release.framework/Resources/Info.plist → test/demo/bin/libgdexample.osx.template_release.framework/Resources/Info.plist

@@ -3,13 +3,13 @@
 <plist version="1.0">
 <dict>
 	<key>CFBundleExecutable</key>
-	<string>libgdexample.release</string>
+	<string>libgdexample.template_release</string>
 	<key>CFBundleIdentifier</key>
 	<string>org.godotengine.libgdexample</string>
 	<key>CFBundleInfoDictionaryVersion</key>
 	<string>6.0</string>
 	<key>CFBundleName</key>
-	<string>libgdexample.osx.release</string>
+	<string>libgdexample.macos.template_release</string>
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<key>CFBundleShortVersionString</key>

+ 12 - 12
test/demo/example.gdextension

@@ -4,15 +4,15 @@ entry_symbol = "example_library_init"
 
 [libraries]
 
-macos.debug = "res://bin/libgdexample.macos.debug.framework"
-macos.release = "res://bin/libgdexample.macos.release.framework"
-windows.debug.x86_32 = "res://bin/libgdexample.windows.debug.x86_32.dll"
-windows.release.x86_32 = "res://bin/libgdexample.windows.release.x86_32.dll"
-windows.debug.x86_64 = "res://bin/libgdexample.windows.debug.x86_64.dll"
-windows.release.x86_64 = "res://bin/libgdexample.windows.release.x86_64.dll"
-linux.debug.x86_64 = "res://bin/libgdexample.linux.debug.x86_64.so"
-linux.release.x86_64 = "res://bin/libgdexample.linux.release.x86_64.so"
-linux.debug.arm64 = "res://bin/libgdexample.linux.debug.arm64.so"
-linux.release.arm64 = "res://bin/libgdexample.linux.release.arm64.so"
-linux.debug.rv64 = "res://bin/libgdexample.linux.debug.rv64.so"
-linux.release.rv64 = "res://bin/libgdexample.linux.release.rv64.so"
+macos.debug = "res://bin/libgdexample.macos.template_debug.framework"
+macos.release = "res://bin/libgdexample.macos.template_release.framework"
+windows.debug.x86_32 = "res://bin/libgdexample.windows.template_debug.x86_32.dll"
+windows.release.x86_32 = "res://bin/libgdexample.windows.template_release.x86_32.dll"
+windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll"
+windows.release.x86_64 = "res://bin/libgdexample.windows.template_release.x86_64.dll"
+linux.debug.x86_64 = "res://bin/libgdexample.linux.template_debug.x86_64.so"
+linux.release.x86_64 = "res://bin/libgdexample.linux.template_release.x86_64.so"
+linux.debug.arm64 = "res://bin/libgdexample.linux.template_debug.arm64.so"
+linux.release.arm64 = "res://bin/libgdexample.linux.template_release.arm64.so"
+linux.debug.rv64 = "res://bin/libgdexample.linux.template_debug.rv64.so"
+linux.release.rv64 = "res://bin/libgdexample.linux.template_release.rv64.so"

+ 50 - 19
tools/targets.py

@@ -1,6 +1,19 @@
 import os
 import sys
+from SCons.Script import ARGUMENTS
 from SCons.Variables import *
+from SCons.Variables.BoolVariable import _text2bool
+
+
+def get_cmdline_bool(option, default):
+    """We use `ARGUMENTS.get()` to check if options were manually overridden on the command line,
+    and SCons' _text2bool helper to convert them to booleans, otherwise they're handled as strings.
+    """
+    cmdline_val = ARGUMENTS.get(option)
+    if cmdline_val is not None:
+        return _text2bool(cmdline_val)
+    else:
+        return default
 
 
 def options(opts):
@@ -8,11 +21,12 @@ def options(opts):
         EnumVariable(
             "optimize",
             "The desired optimization flags",
-            "auto",
-            ("auto", "none", "debug", "speed", "size", "0", "1", "2", "3"),
+            "speed_trace",
+            ("none", "custom", "debug", "speed", "speed_trace", "size"),
         )
     )
-    opts.Add(BoolVariable("debug_symbols", "Add debugging symbols to release builds", False))
+    opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", True))
+    opts.Add(BoolVariable("dev_build", "Developer build with dev-only debugging code (DEV_ENABLED)", False))
 
 
 def exists(env):
@@ -20,38 +34,55 @@ def exists(env):
 
 
 def generate(env):
-    if env["optimize"] == "auto":
-        env["optimize"] = "speed" if env["target"] == "release" else "debug"
-    env["debug_symbols"] = env["debug_symbols"] or env["target"] == "debug"
+    env.dev_build = env["dev_build"]
+    env.debug_features = env["target"] in ["editor", "template_debug"]
+    env.editor_build = env["target"] == "editor"
+
+    if env.editor_build:
+        env.AppendUnique(CPPDEFINES=["TOOLS_ENABLED"])
+
+    if env.debug_features:
+        env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED", "DEBUG_METHODS_ENABLED"])
+
+    if env.dev_build:
+        opt_level = "none"
+        env.AppendUnique(CPPDEFINES=["DEV_ENABLED"])
+    elif env.debug_features:
+        opt_level = "speed_trace"
+    else:  # Release
+        opt_level = "speed"
+
+    env["optimize"] = ARGUMENTS.get("optimize", opt_level)
+    env["debug_symbols"] = get_cmdline_bool("debug_symbols", env.dev_build)
 
     if "is_msvc" in env and env["is_msvc"]:
         if env["debug_symbols"]:
-            env.Append(CCFLAGS=["/Z7", "/D_DEBUG"])
+            env.Append(CCFLAGS=["/Zi", "/FS"])
             env.Append(LINKFLAGS=["/DEBUG:FULL"])
-        else:
-            env.Append(CCFLAGS=["/Z7", "/DNDEBUG"])
 
-        if env["optimize"] == "speed":
+        if env["optimize"] == "speed" or env["optimize"] == "speed_trace":
             env.Append(CCFLAGS=["/O2"])
+            env.Append(LINKFLAGS=["/OPT:REF"])
         elif env["optimize"] == "size":
-            env.Append(CCFLAGS=["/Os"])
-        elif env["optimize"] == "debug":
-            env.Append(CCFLAGS=["/Od"])
-        elif env["optimize"] == "none":
+            env.Append(CCFLAGS=["/O1"])
+            env.Append(LINKFLAGS=["/OPT:REF"])
+        elif env["optimize"] == "debug" or env["optimize"] == "none":
             env.Append(CCFLAGS=["/Od"])
-        else:
-            env.Append(CCFLAGS=["/O%s" % env["optimize"]])
     else:
         if env["debug_symbols"]:
-            env.Append(CCFLAGS=["-g"])
+            if env.dev_build:
+                env.Append(CCFLAGS=["-g3"])
+            else:
+                env.Append(CCFLAGS=["-g2"])
 
         if env["optimize"] == "speed":
             env.Append(CCFLAGS=["-O3"])
+        # `-O2` is friendlier to debuggers than `-O3`, leading to better crash backtraces.
+        elif env["optimize"] == "speed_trace":
+            env.Append(CCFLAGS=["-O2"])
         elif env["optimize"] == "size":
             env.Append(CCFLAGS=["-Os"])
         elif env["optimize"] == "debug":
             env.Append(CCFLAGS=["-Og"])
         elif env["optimize"] == "none":
             env.Append(CCFLAGS=["-O0"])
-        else:
-            env.Append(CCFLAGS=["-O%s" % env["optimize"]])