Skip to content

Commit

Permalink
SCons: Add explicit dependencies on thirdparty code in cloned env
Browse files Browse the repository at this point in the history
Since we clone the environments to build thirdparty code, we don't get an
explicit dependency on the build objects produced by that environment.

So when we update thirdparty code, Godot code using it is not necessarily
rebuilt (I think it is for changed headers, but not for changed .c/.cpp files),
which can lead to an invalid compilation output (linking old Godot .o files
with a newer, potentially ABI breaking version of thirdparty code).

This was only seen as really problematic with bullet updates (leading to
crashes when rebuilding Godot after a bullet update without cleaning .o files),
but it's safer to fix it everywhere, even if it's a LOT of hacky boilerplate.
  • Loading branch information
akien-mga committed Dec 18, 2020
1 parent 5332d21 commit c7b53c0
Show file tree
Hide file tree
Showing 50 changed files with 602 additions and 165 deletions.
20 changes: 15 additions & 5 deletions core/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ with open("script_encryption_key.gen.cpp", "w") as f:


# Add required thirdparty code.

thirdparty_obj = []

env_thirdparty = env.Clone()
env_thirdparty.disable_warnings()

Expand All @@ -55,7 +58,7 @@ thirdparty_misc_sources = [
"clipper.cpp",
]
thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
env_thirdparty.add_source_files(env.core_sources, thirdparty_misc_sources)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_misc_sources)

# Zlib library, can be unbundled
if env["builtin_zlib"]:
Expand All @@ -81,14 +84,14 @@ if env["builtin_zlib"]:
if env["target"] == "debug":
env_thirdparty.Append(CPPDEFINES=["ZLIB_DEBUG"])

env_thirdparty.add_source_files(env.core_sources, thirdparty_zlib_sources)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_zlib_sources)

# Minizip library, could be unbundled in theory
# However, our version has some custom modifications, so it won't compile with the system one
thirdparty_minizip_dir = "#thirdparty/minizip/"
thirdparty_minizip_sources = ["ioapi.c", "unzip.c", "zip.c"]
thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
env_thirdparty.add_source_files(env.core_sources, thirdparty_minizip_sources)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_minizip_sources)

# Zstd library, can be unbundled in theory
# though we currently use some private symbols
Expand Down Expand Up @@ -130,10 +133,14 @@ if env["builtin_zstd"]:
# Also needed in main env includes will trigger warnings
env.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"])

env_thirdparty.add_source_files(env.core_sources, thirdparty_zstd_sources)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_zstd_sources)


env.core_sources += thirdparty_obj


# Godot source files

# Godot's own sources
env.add_source_files(env.core_sources, "*.cpp")

# Certificates
Expand Down Expand Up @@ -185,3 +192,6 @@ SConscript("error/SCsub")
# Build it all as a library
lib = env.add_library("core", env.core_sources)
env.Prepend(LIBS=[lib])

# Needed to force rebuilding the core files when the thirdparty code is updated.
env.Depends(lib, thirdparty_obj)
15 changes: 13 additions & 2 deletions core/crypto/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ env_crypto = env.Clone()

is_builtin = env["builtin_mbedtls"]
has_module = env["module_mbedtls_enabled"]
thirdparty_obj = []

if is_builtin or not has_module:
# Use our headers for builtin or if the module is not going to be compiled.
Expand Down Expand Up @@ -35,6 +36,16 @@ if not has_module:
"godot_core_mbedtls_platform.c",
]
thirdparty_mbedtls_sources = [thirdparty_mbedtls_dir + file for file in thirdparty_mbedtls_sources]
env_thirdparty.add_source_files(env.core_sources, thirdparty_mbedtls_sources)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_mbedtls_sources)
env.core_sources += thirdparty_obj

env_crypto.add_source_files(env.core_sources, "*.cpp")

# Godot source files

core_obj = []

env_crypto.add_source_files(core_obj, "*.cpp")
env.core_sources += core_obj

# Needed to force rebuilding the core files when the thirdparty library is updated.
env.Depends(core_obj, thirdparty_obj)
19 changes: 15 additions & 4 deletions drivers/png/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Import("env")
env_png = env.Clone()

# Thirdparty source files

thirdparty_obj = []

if env["builtin_libpng"]:
thirdparty_dir = "#thirdparty/libpng/"
thirdparty_sources = [
Expand Down Expand Up @@ -41,7 +44,7 @@ if env["builtin_libpng"]:

env_thirdparty = env_png.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.drivers_sources, thirdparty_sources)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)

if use_neon:
env_neon = env_thirdparty.Clone()
Expand All @@ -52,9 +55,17 @@ if env["builtin_libpng"]:
neon_sources.append(env_neon.Object(thirdparty_dir + "/arm/filter_neon_intrinsics.c"))
neon_sources.append(env_neon.Object(thirdparty_dir + "/arm/filter_neon.S"))
neon_sources.append(env_neon.Object(thirdparty_dir + "/arm/palette_neon_intrinsics.c"))
env.drivers_sources += neon_sources
thirdparty_obj += neon_sources

env.drivers_sources += thirdparty_obj


# Godot source files
env_png.add_source_files(env.drivers_sources, "*.cpp")

Export("env")
driver_obj = []

env_png.add_source_files(driver_obj, "*.cpp")
env.drivers_sources += driver_obj

# Needed to force rebuilding the driver files when the thirdparty library is updated.
env.Depends(driver_obj, thirdparty_obj)
8 changes: 4 additions & 4 deletions drivers/spirv-reflect/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

Import("env")

env_spirv_reflect = env.Clone()
env_spirv_reflect.disable_warnings()
# Thirdparty source files

thirdparty_dir = "#thirdparty/spirv-reflect/"
thirdparty_sources = [
Expand All @@ -12,6 +11,7 @@ thirdparty_sources = [

thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]

env_spirv_reflect.add_source_files(env.drivers_sources, thirdparty_sources)
env_thirdparty = env.Clone()
env_thirdparty.disable_warnings()

Export("env")
env_thirdparty.add_source_files(env.drivers_sources, thirdparty_sources)
29 changes: 23 additions & 6 deletions drivers/vulkan/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Import("env")

env.add_source_files(env.drivers_sources, "*.cpp")
thirdparty_obj = []

# FIXME: Refactor all this to reduce code duplication.
if env["platform"] == "android":
Expand All @@ -22,7 +22,8 @@ if env["platform"] == "android":

thirdparty_dir = "#thirdparty/vulkan"
vma_sources = [thirdparty_dir + "/android/vk_mem_alloc.cpp"]
env_thirdparty.add_source_files(env.drivers_sources, vma_sources)
env_thirdparty.add_source_files(thirdparty_obj, vma_sources)

elif env["platform"] == "iphone":
# Use bundled Vulkan headers
thirdparty_dir = "#thirdparty/vulkan"
Expand All @@ -33,7 +34,8 @@ elif env["platform"] == "iphone":
env_thirdparty.disable_warnings()

vma_sources = [thirdparty_dir + "/vk_mem_alloc.cpp"]
env_thirdparty.add_source_files(env.drivers_sources, vma_sources)
env_thirdparty.add_source_files(thirdparty_obj, vma_sources)

elif env["builtin_vulkan"]:
# Use bundled Vulkan headers
thirdparty_dir = "#thirdparty/vulkan"
Expand Down Expand Up @@ -98,8 +100,9 @@ elif env["builtin_vulkan"]:
env_thirdparty.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])

loader_sources = [thirdparty_dir + "/loader/" + file for file in loader_sources]
env_thirdparty.add_source_files(env.drivers_sources, loader_sources)
env_thirdparty.add_source_files(env.drivers_sources, vma_sources)
env_thirdparty.add_source_files(thirdparty_obj, loader_sources)
env_thirdparty.add_source_files(thirdparty_obj, vma_sources)

else: # Always build VMA.
thirdparty_dir = "#thirdparty/vulkan"
env.Prepend(CPPPATH=[thirdparty_dir])
Expand All @@ -109,4 +112,18 @@ else: # Always build VMA.
env_thirdparty.disable_warnings()
vma_sources = [thirdparty_dir + "/vk_mem_alloc.cpp"]

env_thirdparty.add_source_files(env.drivers_sources, vma_sources)
env_thirdparty.add_source_files(thirdparty_obj, vma_sources)


env.drivers_sources += thirdparty_obj


# Godot source files

driver_obj = []

env.add_source_files(driver_obj, "*.cpp")
env.drivers_sources += driver_obj

# Needed to force rebuilding the driver files when the thirdparty code is updated.
env.Depends(driver_obj, thirdparty_obj)
30 changes: 22 additions & 8 deletions modules/assimp/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ Import("env_modules")

env_assimp = env_modules.Clone()

# Thirdparty source files

thirdparty_obj = []

# Force bundled version for now, there's no released version of Assimp with
# support for ArmaturePopulate which we use from their master branch.

if True: # env['builtin_assimp']:
thirdparty_dir = "#thirdparty/assimp"

Expand Down Expand Up @@ -84,11 +89,20 @@ if True: # env['builtin_assimp']:

env_thirdparty = env_assimp.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, Glob("#thirdparty/assimp/code/CApi/*.cpp"))
env_thirdparty.add_source_files(env.modules_sources, Glob("#thirdparty/assimp/code/Common/*.cpp"))
env_thirdparty.add_source_files(env.modules_sources, Glob("#thirdparty/assimp/code/PostProcessing/*.cpp"))
env_thirdparty.add_source_files(env.modules_sources, Glob("#thirdparty/assimp/code/Material/*.cpp"))
env_thirdparty.add_source_files(env.modules_sources, Glob("#thirdparty/assimp/code/FBX/*.cpp"))

# Godot's own source files
env_assimp.add_source_files(env.modules_sources, "*.cpp")
env_thirdparty.add_source_files(thirdparty_obj, Glob("#thirdparty/assimp/code/CApi/*.cpp"))
env_thirdparty.add_source_files(thirdparty_obj, Glob("#thirdparty/assimp/code/Common/*.cpp"))
env_thirdparty.add_source_files(thirdparty_obj, Glob("#thirdparty/assimp/code/PostProcessing/*.cpp"))
env_thirdparty.add_source_files(thirdparty_obj, Glob("#thirdparty/assimp/code/Material/*.cpp"))
env_thirdparty.add_source_files(thirdparty_obj, Glob("#thirdparty/assimp/code/FBX/*.cpp"))
env.modules_sources += thirdparty_obj


# Godot source files

module_obj = []

env_assimp.add_source_files(module_obj, "*.cpp")
env.modules_sources += module_obj

# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)
17 changes: 14 additions & 3 deletions modules/basis_universal/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ Import("env_modules")
env_basisu = env_modules.Clone()

# Thirdparty source files

thirdparty_obj = []

# Not unbundled so far since not widespread as shared library
thirdparty_dir = "#thirdparty/basis_universal/"
tool_sources = [
Expand Down Expand Up @@ -41,8 +44,16 @@ if env["target"] == "debug":
env_thirdparty = env_basisu.Clone()
env_thirdparty.disable_warnings()
if env["tools"]:
env_thirdparty.add_source_files(env.modules_sources, tool_sources)
env_thirdparty.add_source_files(env.modules_sources, transcoder_sources)
env_thirdparty.add_source_files(thirdparty_obj, tool_sources)
env_thirdparty.add_source_files(thirdparty_obj, transcoder_sources)
env.modules_sources += thirdparty_obj

# Godot source files
env_basisu.add_source_files(env.modules_sources, "*.cpp")

module_obj = []

env_basisu.add_source_files(module_obj, "*.cpp")
env.modules_sources += module_obj

# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)
14 changes: 12 additions & 2 deletions modules/bullet/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ env_bullet = env_modules.Clone()

# Thirdparty source files

thirdparty_obj = []

if env["builtin_bullet"]:
# Build only version 2 for now (as of 2.89)
# Sync file list with relevant upstream CMakeLists.txt for each folder.
Expand Down Expand Up @@ -208,8 +210,16 @@ if env["builtin_bullet"]:

env_thirdparty = env_bullet.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
env.modules_sources += thirdparty_obj


# Godot source files
env_bullet.add_source_files(env.modules_sources, "*.cpp")

module_obj = []

env_bullet.add_source_files(module_obj, "*.cpp")
env.modules_sources += module_obj

# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)
15 changes: 13 additions & 2 deletions modules/cvtt/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ Import("env_modules")
env_cvtt = env_modules.Clone()

# Thirdparty source files

thirdparty_obj = []

thirdparty_dir = "#thirdparty/cvtt/"
thirdparty_sources = [
"ConvectionKernels.cpp",
Expand All @@ -17,7 +20,15 @@ env_cvtt.Prepend(CPPPATH=[thirdparty_dir])

env_thirdparty = env_cvtt.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
env.modules_sources += thirdparty_obj

# Godot source files
env_cvtt.add_source_files(env.modules_sources, "*.cpp")

module_obj = []

env_cvtt.add_source_files(module_obj, "*.cpp")
env.modules_sources += module_obj

# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)
17 changes: 14 additions & 3 deletions modules/denoise/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Import("env_modules")
env_oidn = env_modules.Clone()

# Thirdparty source files

thirdparty_obj = []

thirdparty_dir = "#thirdparty/oidn/"
thirdparty_sources = [
"core/api.cpp",
Expand Down Expand Up @@ -106,13 +109,21 @@ env_oidn.Append(

env_thirdparty = env_oidn.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
env.modules_sources += thirdparty_obj

weights_in_path = thirdparty_dir + "weights/rtlightmap_hdr.tza"
weights_out_path = thirdparty_dir + "weights/rtlightmap_hdr.gen.cpp"

env_thirdparty.Depends(weights_out_path, weights_in_path)
env_thirdparty.CommandNoCache(weights_out_path, weights_in_path, resource_to_cpp.tza_to_cpp)

env_oidn.add_source_files(env.modules_sources, "denoise_wrapper.cpp")
env_modules.add_source_files(env.modules_sources, ["register_types.cpp", "lightmap_denoiser.cpp"])
# Godot source files

module_obj = []

env_oidn.add_source_files(module_obj, "*.cpp")
env.modules_sources += module_obj

# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)
16 changes: 14 additions & 2 deletions modules/enet/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ env_enet = env_modules.Clone()

# Thirdparty source files

thirdparty_obj = []

if env["builtin_enet"]:
thirdparty_dir = "#thirdparty/enet/"
thirdparty_sources = [
Expand All @@ -26,6 +28,16 @@ if env["builtin_enet"]:

env_thirdparty = env_enet.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
env.modules_sources += thirdparty_obj


# Godot source files

module_obj = []

env_enet.add_source_files(module_obj, "*.cpp")
env.modules_sources += module_obj

env_enet.add_source_files(env.modules_sources, "*.cpp")
# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)
Loading

0 comments on commit c7b53c0

Please sign in to comment.