Skip to content

Commit 568577c

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. Run with: ``` scons build_project=test,/path/to/other/project ``` Add test to CI. Various mingw fixes.
1 parent 71ed758 commit 568577c

File tree

3 files changed

+47
-126
lines changed

3 files changed

+47
-126
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ jobs:
8282
run: |
8383
scons platform=${{ matrix.platform }} target=release generate_bindings=yes ${{ matrix.flags }} -j2
8484
85+
- name: Build test
86+
run: |
87+
scons platform=${{ matrix.platform }} target=release ${{ matrix.flags }} -j2 build_projects=test
88+
8589
- name: Upload artifact
8690
uses: actions/upload-artifact@v2
8791
with:

SConstruct

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,12 @@ 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

150-
# Require C++17
151-
if host_platform == "windows" and env["platform"] == "windows" and not env["use_mingw"]:
152-
# MSVC
153-
env.Append(CCFLAGS=["/std:c++17"])
154-
else:
155-
env.Append(CCFLAGS=["-std=c++17"])
156-
157153
# This makes sure to keep the session environment variables on Windows.
158154
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find
159155
# all the required tools
@@ -165,6 +161,13 @@ if host_platform == "windows" and env["platform"] != "android":
165161

166162
opts.Update(env)
167163

164+
# Require C++17
165+
if host_platform == "windows" and env["platform"] == "windows" and not env["use_mingw"]:
166+
# MSVC
167+
env.Append(CCFLAGS=["/std:c++17"])
168+
else:
169+
env.Append(CCFLAGS=["-std=c++17"])
170+
168171
if env["target"] == "debug":
169172
env.Append(CPPDEFINES=["DEBUG_ENABLED", "DEBUG_METHODS_ENABLED"])
170173

@@ -243,14 +246,13 @@ elif env["platform"] == "ios":
243246
env["CXX"] = compiler_path + "clang++"
244247
env["AR"] = compiler_path + "ar"
245248
env["RANLIB"] = compiler_path + "ranlib"
249+
env["SHLIBSUFFIX"] = ".dylib"
246250

247251
env.Append(CCFLAGS=["-arch", env["ios_arch"], "-isysroot", sdk_path])
248252
env.Append(
249253
LINKFLAGS=[
250254
"-arch",
251255
env["ios_arch"],
252-
"-framework",
253-
"Cocoa",
254256
"-Wl,-undefined,dynamic_lookup",
255257
"-isysroot",
256258
sdk_path,
@@ -293,8 +295,13 @@ elif env["platform"] == "windows":
293295

294296
# Still need to use C++17.
295297
env.Append(CCFLAGS=["-std=c++17"])
298+
# Don't want lib prefixes
299+
env["IMPLIBPREFIX"] = ""
300+
env["SHLIBPREFIX"] = ""
296301

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

299306
# Native or cross-compilation using MinGW
300307
if host_platform == "linux" or host_platform == "freebsd" or host_platform == "osx" or env["use_mingw"]:
@@ -314,9 +321,10 @@ elif env["platform"] == "android":
314321
# Don't Clone the environment. Because otherwise, SCons will pick up msvc stuff.
315322
env = Environment(ENV=os.environ, tools=["mingw"])
316323
opts.Update(env)
317-
# env = env.Clone(tools=['mingw'])
318324

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

321329
# Verify NDK root
322330
if not "ANDROID_NDK_ROOT" in env:
@@ -382,11 +390,13 @@ elif env["platform"] == "android":
382390
env["CC"] = toolchain + "/bin/clang"
383391
env["CXX"] = toolchain + "/bin/clang++"
384392
env["AR"] = toolchain + "/bin/" + arch_info["tool_path"] + "-ar"
393+
env["SHLIBSUFFIX"] = ".so"
385394

386395
env.Append(
387396
CCFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"], "-fPIC"]
388397
) # , '-fPIE', '-fno-addrsig', '-Oz'])
389398
env.Append(CCFLAGS=arch_info["ccflags"])
399+
env.Append(LINKFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"]])
390400

391401
if env["target"] == "debug":
392402
env.Append(CCFLAGS=["-Og", "-g"])
@@ -473,8 +483,22 @@ elif env["platform"] == "javascript":
473483
elif env["platform"] == "osx":
474484
arch_suffix = env["macos_arch"]
475485

476-
library = env.StaticLibrary(
477-
target="bin/" + "libgodot-cpp.{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["LIBSUFFIX"]),
478-
source=sources,
479-
)
480-
Default(library)
486+
library = None
487+
env["OBJSUFFIX"] = ".{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["OBJSUFFIX"])
488+
library_name = "libgodot-cpp.{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["LIBSUFFIX"])
489+
490+
if env["build_library"]:
491+
library = env.StaticLibrary(target=os.path.join("bin", library_name), source=sources)
492+
Default(library)
493+
494+
if env["build_projects"]:
495+
base_env = env.Clone()
496+
for v in env["build_projects"].split(","):
497+
env = base_env.Clone()
498+
env["SHLIBSUFFIX"] = "{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["SHLIBSUFFIX"])
499+
Export("env")
500+
env.Append(CPPPATH=["#gen/include", "#include", "#godot-headers"])
501+
env.Append(LIBPATH=["#bin"])
502+
env.Append(LIBS=library_name)
503+
504+
SConscript(os.path.join(v, "SConstruct"))

test/SConstruct

Lines changed: 4 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python
2-
import os
3-
import sys
2+
3+
Import("env")
44

55
# default values, adapt them to your setup
66
default_library_name = "libgdexample"
@@ -10,71 +10,20 @@ default_target_path = "demo/bin/"
1010
cpp_bindings_path = "../"
1111
# cpp_bindings_path = "godot-cpp/"
1212
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)
2913

3014
opts = Variables([], ARGUMENTS)
3115

3216
# Define our options
33-
opts.Add(EnumVariable("target", "Compilation target", "debug", allowed_values=("debug", "release"), ignorecase=2))
3417
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"),
42-
ignorecase=2,
43-
)
18+
PathVariable("target_path", "The path where the lib is installed.", default_target_path, PathVariable.PathAccept)
4419
)
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(PathVariable("target_path", "The path where the lib is installed.", default_target_path, PathVariable.PathAccept))
4820
opts.Add(PathVariable("target_name", "The library name.", default_library_name, PathVariable.PathAccept))
4921

50-
# only support 64 at this time..
51-
bits = 64
52-
5322
# Updates the environment with the option variables.
5423
opts.Update(env)
5524
# Generates help for the -h scons option.
5625
Help(opts.GenerateHelpText(env))
5726

58-
# This makes sure to keep the session environment variables on Windows.
59-
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find
60-
# all the required tools
61-
if host_platform == "windows" and env["platform"] != "android":
62-
if env["bits"] == "64":
63-
env = Environment(TARGET_ARCH="amd64")
64-
elif env["bits"] == "32":
65-
env = Environment(TARGET_ARCH="x86")
66-
67-
opts.Update(env)
68-
69-
# Process some arguments
70-
if env["use_llvm"]:
71-
env["CC"] = "clang"
72-
env["CXX"] = "clang++"
73-
74-
if env["platform"] == "":
75-
print("No valid target platform selected.")
76-
quit()
77-
7827
# For the reference:
7928
# - CCFLAGS are compilation flags shared between C and C++
8029
# - CFLAGS are for C-specific compilation flags
@@ -83,67 +32,11 @@ if env["platform"] == "":
8332
# - CPPDEFINES are for pre-processor defines
8433
# - LINKFLAGS are for linking flags
8534

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

145-
target_name = "{}.{}.{}.{}".format(env["target_name"], env["platform"], env["target"], arch_suffix)
146-
print(target_name)
39+
target_name = "{}{}".format(env["target_name"], env["SHLIBSUFFIX"])
14740
library = env.SharedLibrary(target=env["target_path"] + target_name, source=sources)
14841

14942
Default(library)

0 commit comments

Comments
 (0)