Skip to content

Commit d8f908c

Browse files
authored
Merge pull request #33 from OpenVicProject/build-system-improvements
Adds support for out of source builds by adding Variant-dir-aware glob, deterministic platform option order, deterministic build module resolution
2 parents 4ddc9a1 + 92e8ee9 commit d8f908c

4 files changed

Lines changed: 57 additions & 13 deletions

File tree

‎SConstruct‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@ from typing import List, Union
88

99
import SCons
1010

11+
_SCRIPTS_DIR = Dir(".").abspath
12+
if _SCRIPTS_DIR not in sys.path:
13+
sys.path.insert(0, _SCRIPTS_DIR)
14+
1115
# Local
1216
from build.option_handler import OptionsClass
1317
from build.glob_recursive import GlobRecursive
1418
from build.git_info import get_git_info, git_builder
1519
from build.license_info import license_builder
1620
from build.author_info import author_builder
1721
from build.cache import show_progress
22+
from build.pch import setup_pch
1823

1924
def normalize_path(val, env):
2025
return val if os.path.isabs(val) else os.path.join(env.Dir("#").abspath, val)
@@ -167,9 +172,14 @@ def SetupOptions():
167172
)
168173
)
169174

170-
# Add platform options
175+
# Add platform options. Iterate deterministically with the current platform
176+
# registered last so its defaults win
171177
tools = {}
172-
for pl in set(platforms) - set(unsupported_known_platforms):
178+
current_platform = env.get("platform", default_platform)
179+
supported = sorted(set(platforms) - set(unsupported_known_platforms))
180+
if current_platform in supported:
181+
supported = [pl for pl in supported if pl != current_platform] + [current_platform]
182+
for pl in supported:
173183
tool = Tool(pl, toolpath=env.TOOLPATH)
174184
if hasattr(tool, "options"):
175185
tool.options(opts)
@@ -205,6 +215,7 @@ def SetupOptions():
205215
opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
206216
opts.Add(BoolVariable("intermediate_delete", "Enables automatically deleting unassociated intermediate binary files.", True))
207217
opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True))
218+
opts.Add(BoolVariable("use_pch", "Enable precompiled headers when the toolchain supports it", True))
208219

209220
# Targets flags tool (optimizations, debug symbols)
210221
target_tool = Tool("targets", toolpath=env.TOOLPATH)
@@ -261,10 +272,11 @@ def FinalizeOptions():
261272
target_tool.generate(env)
262273
tool.generate(env)
263274

275+
Decider("MD5-timestamp")
276+
264277
scons_cache_path = os.environ.get("SCONS_CACHE")
265278
if scons_cache_path != None:
266279
CacheDir(scons_cache_path)
267-
Decider("MD5")
268280
print("Scons cache enabled... (path: '" + scons_cache_path + "')")
269281

270282
if env["compiledb"] and is_standalone:
@@ -279,6 +291,7 @@ env.get_git_info = get_git_info
279291
env.license_builder = license_builder
280292
env.git_builder = git_builder
281293
env.author_builder = author_builder
294+
env.SetupPCH = lambda header, source: setup_pch(env, header, source)
282295

283296

284297
def to_raw_cstring(value: Union[str, List[str]]) -> str:

‎build/__init__.py‎

Whitespace-only changes.

‎build/glob_recursive.py‎

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
def GlobRecursive(pattern, nodes=["."], exclude=None):
22
import fnmatch
3+
import os
34

45
import SCons
56

@@ -11,15 +12,20 @@ def GlobRecursive(pattern, nodes=["."], exclude=None):
1112

1213
results = []
1314
for node in nodes:
14-
nnodes = []
15-
for f in Glob(str(node) + "/*", source=True):
15+
node_str = str(node)
16+
17+
for f in Glob(node_str + "/*", source=True):
1618
if type(f) is SCons.Node.FS.Dir:
17-
nnodes.append(f)
18-
results += GlobRecursive(pattern, nnodes)
19-
results += Glob(str(node) + "/" + pattern, source=True)
20-
if isinstance(exclude, list):
21-
for val in results:
22-
for pat in exclude:
23-
if fnmatch.fnmatch(str(val), pat):
24-
results.remove(val)
19+
child = node_str + "/" + os.path.basename(str(f))
20+
results += GlobRecursive(pattern, [child])
21+
22+
results += Glob(node_str + "/" + pattern)
23+
24+
if isinstance(exclude, list):
25+
26+
def norm(s):
27+
return str(s).replace("\\", "/")
28+
29+
norm_exclude = [norm(p) for p in exclude]
30+
results = [r for r in results if not any(fnmatch.fnmatch(norm(r), p) for p in norm_exclude)]
2531
return results

‎build/pch.py‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
def setup_pch(env, header_rel, source_cpp_variant):
2+
if not env.get("use_pch", True):
3+
return
4+
5+
handler = _select_handler(env)
6+
if handler is None:
7+
return
8+
9+
name = handler(env, header_rel, source_cpp_variant)
10+
print(f"[PCH] enabled ({name}): {header_rel}")
11+
12+
13+
def _select_handler(env):
14+
if env.get("is_msvc", False):
15+
return _msvc_pch
16+
# TODO: GCC/Clang/MinGW
17+
return None
18+
19+
20+
def _msvc_pch(env, header_rel, source_cpp_variant):
21+
env["PCHSTOP"] = header_rel
22+
pch_pch, _pch_obj = env.PCH(source_cpp_variant)
23+
env["PCH"] = pch_pch
24+
env.Append(CCFLAGS=["/FI" + header_rel])
25+
return "msvc"

0 commit comments

Comments
 (0)