Library SCons boilerplate to build projects.

Works by executing project `SConstruct`s file in a cloned env (a bit
like Godot does for modules) so you don't have to worry about platform
and toolchain setup.

Convert the project test file to work as submodule, add it to CI

Run with:

```
scons build_projects=test,/path/to/other/project
```
pull/636/head
Fabio Alessandrelli 2021-09-30 04:29:42 +02:00
parent cf3fcab6b4
commit dcc52f4321
3 changed files with 32 additions and 154 deletions

View File

@ -152,6 +152,10 @@ jobs:
# cd test # cd test
# scons target=release use_mingw=yes -j $env:NUMBER_OF_PROCESSORS # scons target=release use_mingw=yes -j $env:NUMBER_OF_PROCESSORS
- name: Build test
run: |
scons platform=${{ matrix.platform }} target=release ${{ matrix.flags }} -j2 build_projects=test
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:

View File

@ -144,6 +144,9 @@ opts.Add(
) )
opts.Add(BoolVariable("generate_template_get_node", "Generate a template version of the Node class's get_node.", True)) opts.Add(BoolVariable("generate_template_get_node", "Generate a template version of the Node class's get_node.", True))
opts.Add(BoolVariable("build_library", "Build the godot-cpp library.", True))
opts.Add("build_projects", "List of projects to build (comma-separated list of paths).", "")
opts.Update(env) opts.Update(env)
Help(opts.GenerateHelpText(env)) Help(opts.GenerateHelpText(env))
@ -250,14 +253,13 @@ elif env["platform"] == "ios":
env["CXX"] = compiler_path + "clang++" env["CXX"] = compiler_path + "clang++"
env["AR"] = compiler_path + "ar" env["AR"] = compiler_path + "ar"
env["RANLIB"] = compiler_path + "ranlib" env["RANLIB"] = compiler_path + "ranlib"
env["SHLIBSUFFIX"] = ".dylib"
env.Append(CCFLAGS=["-arch", env["ios_arch"], "-isysroot", sdk_path]) env.Append(CCFLAGS=["-arch", env["ios_arch"], "-isysroot", sdk_path])
env.Append( env.Append(
LINKFLAGS=[ LINKFLAGS=[
"-arch", "-arch",
env["ios_arch"], env["ios_arch"],
"-framework",
"Cocoa",
"-Wl,-undefined,dynamic_lookup", "-Wl,-undefined,dynamic_lookup",
"-isysroot", "-isysroot",
sdk_path, sdk_path,
@ -300,8 +302,13 @@ elif env["platform"] == "windows":
# Still need to use C++17. # Still need to use C++17.
env.Append(CCFLAGS=["-std=c++17"]) env.Append(CCFLAGS=["-std=c++17"])
# Don't want lib prefixes
env["IMPLIBPREFIX"] = ""
env["SHLIBPREFIX"] = ""
# Long line hack. Use custom spawn, quick AR append (to avoid files with the same names to override each other).
env["SPAWN"] = mySpawn env["SPAWN"] = mySpawn
env.Replace(ARFLAGS=["q"])
# Native or cross-compilation using MinGW # Native or cross-compilation using MinGW
if host_platform == "linux" or host_platform == "freebsd" or host_platform == "osx" or env["use_mingw"]: if host_platform == "linux" or host_platform == "freebsd" or host_platform == "osx" or env["use_mingw"]:
@ -321,9 +328,10 @@ elif env["platform"] == "android":
# Don't Clone the environment. Because otherwise, SCons will pick up msvc stuff. # Don't Clone the environment. Because otherwise, SCons will pick up msvc stuff.
env = Environment(ENV=os.environ, tools=["mingw"]) env = Environment(ENV=os.environ, tools=["mingw"])
opts.Update(env) opts.Update(env)
# env = env.Clone(tools=['mingw'])
# Long line hack. Use custom spawn, quick AR append (to avoid files with the same names to override each other).
env["SPAWN"] = mySpawn env["SPAWN"] = mySpawn
env.Replace(ARFLAGS=["q"])
# Verify NDK root # Verify NDK root
if not "ANDROID_NDK_ROOT" in env: if not "ANDROID_NDK_ROOT" in env:
@ -389,11 +397,13 @@ elif env["platform"] == "android":
env["CC"] = toolchain + "/bin/clang" env["CC"] = toolchain + "/bin/clang"
env["CXX"] = toolchain + "/bin/clang++" env["CXX"] = toolchain + "/bin/clang++"
env["AR"] = toolchain + "/bin/" + arch_info["tool_path"] + "-ar" env["AR"] = toolchain + "/bin/" + arch_info["tool_path"] + "-ar"
env["SHLIBSUFFIX"] = ".so"
env.Append( env.Append(
CCFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"], "-fPIC"] CCFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"], "-fPIC"]
) # , '-fPIE', '-fno-addrsig', '-Oz']) ) # , '-fPIE', '-fno-addrsig', '-Oz'])
env.Append(CCFLAGS=arch_info["ccflags"]) env.Append(CCFLAGS=arch_info["ccflags"])
env.Append(LINKFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"]])
if env["target"] == "debug": if env["target"] == "debug":
env.Append(CCFLAGS=["-Og", "-g"]) env.Append(CCFLAGS=["-Og", "-g"])
@ -481,8 +491,16 @@ elif env["platform"] == "javascript":
elif env["platform"] == "osx": elif env["platform"] == "osx":
arch_suffix = env["macos_arch"] arch_suffix = env["macos_arch"]
library = env.StaticLibrary( library = None
target="bin/" + "libgodot-cpp.{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["LIBSUFFIX"]), env["OBJSUFFIX"] = ".{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["OBJSUFFIX"])
source=sources, library_name = "libgodot-cpp.{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["LIBSUFFIX"])
)
if env["build_library"]:
library = env.StaticLibrary(target=env.File("bin/%s" % library_name), source=sources)
Default(library) Default(library)
env["SHLIBSUFFIX"] = "{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["SHLIBSUFFIX"])
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")

View File

@ -2,79 +2,7 @@
import os import os
import sys import sys
# default values, adapt them to your setup env = SConscript("../SConstruct")
default_library_name = "libgdexample"
default_target_path = "demo/bin/"
# Local dependency paths, adapt them to your setup
cpp_bindings_path = "../"
# cpp_bindings_path = "godot-cpp/"
godot_headers_path = cpp_bindings_path + "godot-headers/"
cpp_library = "libgodot-cpp"
# Try to detect the host platform automatically.
# This is used if no `platform` argument is passed
if sys.platform.startswith("linux"):
host_platform = "linux"
elif sys.platform.startswith("freebsd"):
host_platform = "freebsd"
elif sys.platform == "darwin":
host_platform = "osx"
elif sys.platform == "win32" or sys.platform == "msys":
host_platform = "windows"
else:
raise ValueError("Could not detect platform automatically, please specify with " "platform=<platform>")
env = Environment(ENV=os.environ)
opts = Variables([], ARGUMENTS)
# Define our options
opts.Add(EnumVariable("target", "Compilation target", "debug", allowed_values=("debug", "release"), ignorecase=2))
opts.Add(
EnumVariable(
"platform",
"Compilation platform",
host_platform,
# We'll need to support these in due times
# allowed_values=("linux", "freebsd", "osx", "windows", "android", "ios", "javascript"),
allowed_values=("linux", "windows", "osx"),
ignorecase=2,
)
)
opts.Add(EnumVariable("bits", "Target platform bits", "64", ("32", "64")))
opts.Add(BoolVariable("use_llvm", "Use the LLVM / Clang compiler", "no"))
opts.Add(EnumVariable("macos_arch", "Target macOS architecture", "universal", ["universal", "x86_64", "arm64"]))
opts.Add(PathVariable("target_path", "The path where the lib is installed.", default_target_path, PathVariable.PathAccept))
opts.Add(PathVariable("target_name", "The library name.", default_library_name, PathVariable.PathAccept))
# only support 64 at this time..
bits = 64
# Updates the environment with the option variables.
opts.Update(env)
# Generates help for the -h scons option.
Help(opts.GenerateHelpText(env))
# This makes sure to keep the session environment variables on Windows.
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find
# all the required tools
if host_platform == "windows" and env["platform"] != "android":
if env["bits"] == "64":
env = Environment(TARGET_ARCH="amd64")
elif env["bits"] == "32":
env = Environment(TARGET_ARCH="x86")
opts.Update(env)
# Process some arguments
if env["use_llvm"]:
env["CC"] = "clang"
env["CXX"] = "clang++"
if env["platform"] == "":
print("No valid target platform selected.")
quit()
# For the reference: # For the reference:
# - CCFLAGS are compilation flags shared between C and C++ # - CCFLAGS are compilation flags shared between C and C++
@ -84,82 +12,10 @@ if env["platform"] == "":
# - CPPDEFINES are for pre-processor defines # - CPPDEFINES are for pre-processor defines
# - LINKFLAGS are for linking flags # - LINKFLAGS are for linking flags
if env["target"] == "debug":
env.Append(CPPDEFINES=["DEBUG_ENABLED", "DEBUG_METHODS_ENABLED"])
# Check our platform specifics
if env["platform"] == "osx":
env["target_path"] += "{}.{}.framework/".format(env["target_name"], env["target"])
cpp_library += ".osx"
if env["bits"] == "32":
raise ValueError("Only 64-bit builds are supported for the macOS target.")
if env["macos_arch"] == "universal":
env.Append(LINKFLAGS=["-arch", "x86_64", "-arch", "arm64"])
env.Append(CCFLAGS=["-arch", "x86_64", "-arch", "arm64"])
else:
env.Append(LINKFLAGS=["-arch", env["macos_arch"]])
env.Append(CCFLAGS=["-arch", env["macos_arch"]])
env.Append(CXXFLAGS=["-std=c++17"])
if env["target"] == "debug":
env.Append(CCFLAGS=["-g", "-O2"])
else:
env.Append(CCFLAGS=["-g", "-O3"])
arch_suffix = env["macos_arch"]
elif env["platform"] in ("x11", "linux"):
cpp_library += ".linux"
env.Append(CCFLAGS=["-fPIC"])
env.Append(CXXFLAGS=["-std=c++17"])
if env["target"] == "debug":
env.Append(CCFLAGS=["-g3", "-Og"])
else:
env.Append(CCFLAGS=["-g", "-O3"])
arch_suffix = str(bits)
elif env["platform"] == "windows":
cpp_library += ".windows"
# This makes sure to keep the session environment variables on windows,
# that way you can run scons in a vs 2017 prompt and it will find all the required tools
env.Append(ENV=os.environ)
env.Append(CPPDEFINES=["WIN32", "_WIN32", "_WINDOWS", "_CRT_SECURE_NO_WARNINGS"])
env.Append(CCFLAGS=["-W3", "-GR"])
env.Append(CXXFLAGS=["-std:c++17"])
if env["target"] == "debug":
env.Append(CPPDEFINES=["_DEBUG"])
env.Append(CCFLAGS=["-EHsc", "-MDd", "-ZI", "-FS"])
env.Append(LINKFLAGS=["-DEBUG"])
else:
env.Append(CPPDEFINES=["NDEBUG"])
env.Append(CCFLAGS=["-O2", "-EHsc", "-MD"])
if not(env["use_llvm"]):
env.Append(CPPDEFINES=["TYPED_METHOD_BIND"])
arch_suffix = str(bits)
# suffix our godot-cpp library
cpp_library += "." + env["target"] + "." + arch_suffix
# make sure our binding library is properly includes
env.Append(CPPPATH=[".", godot_headers_path, cpp_bindings_path + "include/", cpp_bindings_path + "gen/include/"])
env.Append(LIBPATH=[cpp_bindings_path + "bin/"])
env.Append(LIBS=[cpp_library])
# tweak this if you want to use different folders, or more folders, to store your source code in. # tweak this if you want to use different folders, or more folders, to store your source code in.
env.Append(CPPPATH=["src/"]) env.Append(CPPPATH=["src/"])
sources = Glob("src/*.cpp") sources = Glob("src/*.cpp")
if env["platform"] == "osx": library = env.SharedLibrary("demo/bin/libgdexample" + env["SHLIBSUFFIX"], source=sources)
target_name = "{}.{}".format(env["target_name"], env["target"])
else:
target_name = "{}.{}.{}.{}".format(env["target_name"], env["platform"], env["target"], arch_suffix)
print(target_name)
library = env.SharedLibrary(target=env["target_path"] + target_name, source=sources)
Default(library) Default(library)