Skip to content

Commit dcc52f4

Browse files
committed
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 ```
1 parent cf3fcab commit dcc52f4

File tree

3 files changed

+32
-154
lines changed

3 files changed

+32
-154
lines changed

.github/workflows/ci.yml

+4
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ jobs:
152152
# cd test
153153
# scons target=release use_mingw=yes -j $env:NUMBER_OF_PROCESSORS
154154

155+
- name: Build test
156+
run: |
157+
scons platform=${{ matrix.platform }} target=release ${{ matrix.flags }} -j2 build_projects=test
158+
155159
- name: Upload artifact
156160
uses: actions/upload-artifact@v2
157161
with:

SConstruct

+26-8
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ opts.Add(
144144
)
145145
opts.Add(BoolVariable("generate_template_get_node", "Generate a template version of the Node class's get_node.", True))
146146

147+
opts.Add(BoolVariable("build_library", "Build the godot-cpp library.", True))
148+
opts.Add("build_projects", "List of projects to build (comma-separated list of paths).", "")
149+
147150
opts.Update(env)
148151
Help(opts.GenerateHelpText(env))
149152

@@ -250,14 +253,13 @@ elif env["platform"] == "ios":
250253
env["CXX"] = compiler_path + "clang++"
251254
env["AR"] = compiler_path + "ar"
252255
env["RANLIB"] = compiler_path + "ranlib"
256+
env["SHLIBSUFFIX"] = ".dylib"
253257

254258
env.Append(CCFLAGS=["-arch", env["ios_arch"], "-isysroot", sdk_path])
255259
env.Append(
256260
LINKFLAGS=[
257261
"-arch",
258262
env["ios_arch"],
259-
"-framework",
260-
"Cocoa",
261263
"-Wl,-undefined,dynamic_lookup",
262264
"-isysroot",
263265
sdk_path,
@@ -300,8 +302,13 @@ elif env["platform"] == "windows":
300302

301303
# Still need to use C++17.
302304
env.Append(CCFLAGS=["-std=c++17"])
305+
# Don't want lib prefixes
306+
env["IMPLIBPREFIX"] = ""
307+
env["SHLIBPREFIX"] = ""
303308

309+
# Long line hack. Use custom spawn, quick AR append (to avoid files with the same names to override each other).
304310
env["SPAWN"] = mySpawn
311+
env.Replace(ARFLAGS=["q"])
305312

306313
# Native or cross-compilation using MinGW
307314
if host_platform == "linux" or host_platform == "freebsd" or host_platform == "osx" or env["use_mingw"]:
@@ -321,9 +328,10 @@ elif env["platform"] == "android":
321328
# Don't Clone the environment. Because otherwise, SCons will pick up msvc stuff.
322329
env = Environment(ENV=os.environ, tools=["mingw"])
323330
opts.Update(env)
324-
# env = env.Clone(tools=['mingw'])
325331

332+
# Long line hack. Use custom spawn, quick AR append (to avoid files with the same names to override each other).
326333
env["SPAWN"] = mySpawn
334+
env.Replace(ARFLAGS=["q"])
327335

328336
# Verify NDK root
329337
if not "ANDROID_NDK_ROOT" in env:
@@ -389,11 +397,13 @@ elif env["platform"] == "android":
389397
env["CC"] = toolchain + "/bin/clang"
390398
env["CXX"] = toolchain + "/bin/clang++"
391399
env["AR"] = toolchain + "/bin/" + arch_info["tool_path"] + "-ar"
400+
env["SHLIBSUFFIX"] = ".so"
392401

393402
env.Append(
394403
CCFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"], "-fPIC"]
395404
) # , '-fPIE', '-fno-addrsig', '-Oz'])
396405
env.Append(CCFLAGS=arch_info["ccflags"])
406+
env.Append(LINKFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"]])
397407

398408
if env["target"] == "debug":
399409
env.Append(CCFLAGS=["-Og", "-g"])
@@ -481,8 +491,16 @@ elif env["platform"] == "javascript":
481491
elif env["platform"] == "osx":
482492
arch_suffix = env["macos_arch"]
483493

484-
library = env.StaticLibrary(
485-
target="bin/" + "libgodot-cpp.{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["LIBSUFFIX"]),
486-
source=sources,
487-
)
488-
Default(library)
494+
library = None
495+
env["OBJSUFFIX"] = ".{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["OBJSUFFIX"])
496+
library_name = "libgodot-cpp.{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["LIBSUFFIX"])
497+
498+
if env["build_library"]:
499+
library = env.StaticLibrary(target=env.File("bin/%s" % library_name), source=sources)
500+
Default(library)
501+
502+
env["SHLIBSUFFIX"] = "{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["SHLIBSUFFIX"])
503+
env.Append(CPPPATH=[env.Dir(f) for f in ["gen/include", "include", "godot-headers"]])
504+
env.Append(LIBPATH=[env.Dir("bin")])
505+
env.Append(LIBS=library_name)
506+
Return("env")

test/SConstruct

+2-146
Original file line numberDiff line numberDiff line change
@@ -2,79 +2,7 @@
22
import os
33
import sys
44

5-
# default values, adapt them to your setup
6-
default_library_name = "libgdexample"
7-
default_target_path = "demo/bin/"
8-
9-
# Local dependency paths, adapt them to your setup
10-
cpp_bindings_path = "../"
11-
# cpp_bindings_path = "godot-cpp/"
12-
godot_headers_path = cpp_bindings_path + "godot-headers/"
13-
cpp_library = "libgodot-cpp"
14-
15-
# Try to detect the host platform automatically.
16-
# This is used if no `platform` argument is passed
17-
if sys.platform.startswith("linux"):
18-
host_platform = "linux"
19-
elif sys.platform.startswith("freebsd"):
20-
host_platform = "freebsd"
21-
elif sys.platform == "darwin":
22-
host_platform = "osx"
23-
elif sys.platform == "win32" or sys.platform == "msys":
24-
host_platform = "windows"
25-
else:
26-
raise ValueError("Could not detect platform automatically, please specify with " "platform=<platform>")
27-
28-
env = Environment(ENV=os.environ)
29-
30-
opts = Variables([], ARGUMENTS)
31-
32-
# Define our options
33-
opts.Add(EnumVariable("target", "Compilation target", "debug", allowed_values=("debug", "release"), ignorecase=2))
34-
opts.Add(
35-
EnumVariable(
36-
"platform",
37-
"Compilation platform",
38-
host_platform,
39-
# We'll need to support these in due times
40-
# allowed_values=("linux", "freebsd", "osx", "windows", "android", "ios", "javascript"),
41-
allowed_values=("linux", "windows", "osx"),
42-
ignorecase=2,
43-
)
44-
)
45-
opts.Add(EnumVariable("bits", "Target platform bits", "64", ("32", "64")))
46-
opts.Add(BoolVariable("use_llvm", "Use the LLVM / Clang compiler", "no"))
47-
opts.Add(EnumVariable("macos_arch", "Target macOS architecture", "universal", ["universal", "x86_64", "arm64"]))
48-
opts.Add(PathVariable("target_path", "The path where the lib is installed.", default_target_path, PathVariable.PathAccept))
49-
opts.Add(PathVariable("target_name", "The library name.", default_library_name, PathVariable.PathAccept))
50-
51-
# only support 64 at this time..
52-
bits = 64
53-
54-
# Updates the environment with the option variables.
55-
opts.Update(env)
56-
# Generates help for the -h scons option.
57-
Help(opts.GenerateHelpText(env))
58-
59-
# This makes sure to keep the session environment variables on Windows.
60-
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find
61-
# all the required tools
62-
if host_platform == "windows" and env["platform"] != "android":
63-
if env["bits"] == "64":
64-
env = Environment(TARGET_ARCH="amd64")
65-
elif env["bits"] == "32":
66-
env = Environment(TARGET_ARCH="x86")
67-
68-
opts.Update(env)
69-
70-
# Process some arguments
71-
if env["use_llvm"]:
72-
env["CC"] = "clang"
73-
env["CXX"] = "clang++"
74-
75-
if env["platform"] == "":
76-
print("No valid target platform selected.")
77-
quit()
5+
env = SConscript("../SConstruct")
786

797
# For the reference:
808
# - CCFLAGS are compilation flags shared between C and C++
@@ -84,82 +12,10 @@ if env["platform"] == "":
8412
# - CPPDEFINES are for pre-processor defines
8513
# - LINKFLAGS are for linking flags
8614

87-
if env["target"] == "debug":
88-
env.Append(CPPDEFINES=["DEBUG_ENABLED", "DEBUG_METHODS_ENABLED"])
89-
90-
# Check our platform specifics
91-
if env["platform"] == "osx":
92-
env["target_path"] += "{}.{}.framework/".format(env["target_name"], env["target"])
93-
cpp_library += ".osx"
94-
95-
if env["bits"] == "32":
96-
raise ValueError("Only 64-bit builds are supported for the macOS target.")
97-
98-
if env["macos_arch"] == "universal":
99-
env.Append(LINKFLAGS=["-arch", "x86_64", "-arch", "arm64"])
100-
env.Append(CCFLAGS=["-arch", "x86_64", "-arch", "arm64"])
101-
else:
102-
env.Append(LINKFLAGS=["-arch", env["macos_arch"]])
103-
env.Append(CCFLAGS=["-arch", env["macos_arch"]])
104-
105-
env.Append(CXXFLAGS=["-std=c++17"])
106-
if env["target"] == "debug":
107-
env.Append(CCFLAGS=["-g", "-O2"])
108-
else:
109-
env.Append(CCFLAGS=["-g", "-O3"])
110-
111-
arch_suffix = env["macos_arch"]
112-
113-
elif env["platform"] in ("x11", "linux"):
114-
cpp_library += ".linux"
115-
env.Append(CCFLAGS=["-fPIC"])
116-
env.Append(CXXFLAGS=["-std=c++17"])
117-
if env["target"] == "debug":
118-
env.Append(CCFLAGS=["-g3", "-Og"])
119-
else:
120-
env.Append(CCFLAGS=["-g", "-O3"])
121-
122-
arch_suffix = str(bits)
123-
elif env["platform"] == "windows":
124-
cpp_library += ".windows"
125-
# This makes sure to keep the session environment variables on windows,
126-
# that way you can run scons in a vs 2017 prompt and it will find all the required tools
127-
env.Append(ENV=os.environ)
128-
129-
env.Append(CPPDEFINES=["WIN32", "_WIN32", "_WINDOWS", "_CRT_SECURE_NO_WARNINGS"])
130-
env.Append(CCFLAGS=["-W3", "-GR"])
131-
env.Append(CXXFLAGS=["-std:c++17"])
132-
if env["target"] == "debug":
133-
env.Append(CPPDEFINES=["_DEBUG"])
134-
env.Append(CCFLAGS=["-EHsc", "-MDd", "-ZI", "-FS"])
135-
env.Append(LINKFLAGS=["-DEBUG"])
136-
else:
137-
env.Append(CPPDEFINES=["NDEBUG"])
138-
env.Append(CCFLAGS=["-O2", "-EHsc", "-MD"])
139-
140-
if not(env["use_llvm"]):
141-
env.Append(CPPDEFINES=["TYPED_METHOD_BIND"])
142-
143-
arch_suffix = str(bits)
144-
145-
# suffix our godot-cpp library
146-
cpp_library += "." + env["target"] + "." + arch_suffix
147-
148-
# make sure our binding library is properly includes
149-
env.Append(CPPPATH=[".", godot_headers_path, cpp_bindings_path + "include/", cpp_bindings_path + "gen/include/"])
150-
env.Append(LIBPATH=[cpp_bindings_path + "bin/"])
151-
env.Append(LIBS=[cpp_library])
152-
15315
# tweak this if you want to use different folders, or more folders, to store your source code in.
15416
env.Append(CPPPATH=["src/"])
15517
sources = Glob("src/*.cpp")
15618

157-
if env["platform"] == "osx":
158-
target_name = "{}.{}".format(env["target_name"], env["target"])
159-
else:
160-
target_name = "{}.{}.{}.{}".format(env["target_name"], env["platform"], env["target"], arch_suffix)
161-
162-
print(target_name)
163-
library = env.SharedLibrary(target=env["target_path"] + target_name, source=sources)
19+
library = env.SharedLibrary("demo/bin/libgdexample" + env["SHLIBSUFFIX"], source=sources)
16420

16521
Default(library)

0 commit comments

Comments
 (0)