9@brief Build-time helper for assembling the Rendering Engine SDK.
11This script is intended to be invoked indirectly via the platform build
14 - Windows: build_engine.bat --build-sdk
15 - Unix/FreeBSD: ./build_engine.sh --build-sdk
18 - Read engine version from Intermediate/Generated/version.h.
19 - Copy the installed RenderingEngine library, headers,
and CMake config
20 into a distributable SDK layout.
21 - Copy vendored headers (glm, boost, nlohmann_json, Vulkan headers
if used).
22 - Copy project templates
and the create_project.py helper.
23 - Copy
and patch ContentExamples into SDK-user mode (RE_DEV_MODE=OFF).
24 - Emit documentation files
and a human-readable Manifest.txt.
25 - Create a compressed archive suitable
for CI/CD artifacts.
35# --------------------------------------------------------------------
37# --------------------------------------------------------------------
39REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../"))
40BUILD_ROOT = os.path.join(REPO_ROOT, "Build")
41INSTALL_ROOT = os.path.join(BUILD_ROOT, "Installed")
42PACKAGE_ROOT = os.path.join(BUILD_ROOT, "Packages")
43SDK_TEMP_ROOT = os.path.join(BUILD_ROOT, "SDK")
44LOGS_ROOT = os.path.join(BUILD_ROOT, "Logs")
46VERSION_HEADER = os.path.join(
47 BUILD_ROOT, "Intermediate",
"Generated",
"version.h"
52 "Doc/app_config_guide.md",
53 "Doc/application_development_guide.md",
55 "Doc/debugging_guide.md",
56 "Doc/developer_guide.md",
57 "Doc/docker_container.md",
58 "Doc/getting_started.md",
59 "Doc/performance_profiling_guide.md",
60 "Doc/prepare_environment.md",
61 "Doc/project_creation_guide.md",
62 "Doc/project_packaging_guide.md",
63 "Doc/sdk_packaging_guide.md",
72 """Parse version.h and extract MAJOR.MINOR.PATCH as a string."""
73 if not os.path.isfile(VERSION_HEADER):
74 raise RuntimeError(f
"version.h not found at: {VERSION_HEADER}")
76 with open(VERSION_HEADER,
"r", encoding=
"utf-8")
as f:
79 major = re.search(
r"#define\s+RENDERING_ENGINE_VERSION_MAJOR\s+(\d+)", text)
80 minor = re.search(
r"#define\s+RENDERING_ENGINE_VERSION_MINOR\s+(\d+)", text)
81 patch = re.search(
r"#define\s+RENDERING_ENGINE_VERSION_PATCH\s+(\d+)", text)
83 if not (major
and minor
and patch):
85 "version.h missing required version macros "
86 "(RENDERING_ENGINE_VERSION_MAJOR/MINOR/PATCH)."
89 return f
"{major.group(1)}.{minor.group(1)}.{patch.group(1)}"
93 """Return a human-readable platform string."""
95 if p.startswith(
"win"):
97 elif p.startswith(
"linux"):
99 elif p.startswith(
"freebsd"):
105 if not os.path.exists(src):
106 logging.warning(f
"Source path does not exist, skipping: {src}")
108 if os.path.exists(dst):
110 shutil.copytree(src, dst, ignore=ignore)
111 logging.info(f
"Copied tree: {src} -> {dst}")
115 os.makedirs(path, exist_ok=
True)
120 with open(path,
"w", encoding=
"utf-8")
as f:
121 f.write(
"Rendering Engine SDK Manifest\n")
122 f.write(
"=====================================\n\n")
123 f.write(f
"Version : {version}\n")
124 f.write(f
"Platform: {platform}\n")
125 f.write(f
"Date : {datetime.datetime.now()}\n\n")
127 f.write(
"- RenderingEngine/RenderingLibrary : core engine library + headers + cmake files\n")
128 f.write(
"- RenderingEngine/MaterialCompiler : material compiler tool + local engine DLL\n")
129 f.write(
"- RenderingEngine/Scripts : project generation scripts + templates\n")
130 f.write(
"- ContentExamples/ : sample projects\n")
131 f.write(
"- UserApplications/ : place for user-created apps\n")
132 f.write(
"- Doc/ : documentation\n")
133 logging.info(f
"Manifest written: {path}")
136 """Force RE_DEV_MODE=OFF inside build_project.sh"""
137 if not os.path.isfile(build_script_path):
140 with open(build_script_path,
"r", encoding=
"utf-8")
as f:
146 r'cmake\s+-S\s+"\$PROJECT_SOURCE_DIR"\s+-B\s+"\$PROJECT_BUILD_DIR"\s+-DCMAKE_BUILD_TYPE=\$BUILD_MODE',
147 r'cmake -S "$PROJECT_SOURCE_DIR" -B "$PROJECT_BUILD_DIR" -DCMAKE_BUILD_TYPE=$BUILD_MODE -DRE_DEV_MODE=OFF',
151 with open(build_script_path,
"w", encoding=
"utf-8")
as f:
154 logging.info(f
"Patched build_project.sh for SDK: {build_script_path}")
165 filename=os.path.join(LOGS_ROOT,
"packaging.log"),
167 format=
"%(asctime)s %(levelname)s: %(message)s",
169 logging.info(
"=== SDK Packaging Started ===")
175 sdk_name = f
"RenderingEngine-v{version}-SDK-{platform}"
176 sdk_root = os.path.join(SDK_TEMP_ROOT, sdk_name)
179 if os.path.exists(sdk_root):
180 shutil.rmtree(sdk_root)
183 logging.info(f
"Version : {version}")
184 logging.info(f
"Platform: {platform}")
185 logging.info(f
"SDK root: {sdk_root}")
188 sdk_rendering_engine_root =
ensure_dir(os.path.join(sdk_root,
"RenderingEngine"))
189 sdk_render_lib_root =
ensure_dir(os.path.join(sdk_rendering_engine_root,
"RenderingLibrary"))
190 sdk_material_compiler_root =
ensure_dir(os.path.join(sdk_rendering_engine_root,
"MaterialCompiler"))
191 sdk_scripts_root =
ensure_dir(os.path.join(sdk_rendering_engine_root,
"Scripts"))
196 installed_engine_root = os.path.join(INSTALL_ROOT,
"RenderingEngine")
199 installed_render_lib = os.path.join(installed_engine_root,
"RenderingLibrary")
202 os.path.join(installed_render_lib,
"Include"),
203 os.path.join(sdk_render_lib_root,
"Include"),
207 os.path.join(installed_render_lib,
"Library"),
208 os.path.join(sdk_render_lib_root,
"Library"),
214 installed_mc_root = os.path.join(installed_engine_root,
"MaterialCompiler")
215 copy_tree(installed_mc_root, sdk_material_compiler_root)
220 installed_external_root = os.path.join(installed_engine_root,
"External")
221 copy_tree(installed_external_root, os.path.join(sdk_rendering_engine_root,
"External"))
227 os.path.join(REPO_ROOT,
"RenderingEngine",
"Scripts",
"Templates"),
228 os.path.join(sdk_scripts_root,
"Templates"),
234 cmake_template_path = os.path.join(sdk_scripts_root,
"Templates",
"CMakeLists.txt.in")
238 os.path.join(REPO_ROOT,
"RenderingEngine",
"Scripts",
"Templates"),
239 os.path.join(sdk_scripts_root,
"Templates"),
243 create_project_src = os.path.join(REPO_ROOT,
"RenderingEngine",
"Scripts",
"create_project.py")
244 if os.path.isfile(create_project_src):
245 shutil.copy2(create_project_src, os.path.join(sdk_scripts_root,
"create_project.py"))
246 logging.info(
"Copied script: create_project.py")
248 logging.warning(f
"create_project.py not found at {create_project_src}")
251 cmake_template_path = os.path.join(sdk_scripts_root,
"Templates",
"CMakeLists.txt.in")
253 with open(cmake_template_path,
"r", encoding=
"utf-8")
as f:
257 r'option\(RE_DEV_MODE\s+"[^"]+"\s+ON\)',
258 'option(RE_DEV_MODE "Build using RenderingEngine directly from source tree (Windows only)" OFF)',
262 with open(cmake_template_path,
"w", encoding=
"utf-8")
as f:
265 logging.info(
"Updated CMakeLists.txt.in to set RE_DEV_MODE=OFF")
271 doc_dst =
ensure_dir(os.path.join(sdk_root,
"Doc"))
272 for doc
in DOC_FILES:
273 src = os.path.join(REPO_ROOT, doc)
274 if os.path.isfile(src):
275 shutil.copy2(src, doc_dst)
276 logging.info(f
"Copied documentation: {src}")
278 logging.warning(f
"Documentation file missing, skipped: {src}")
283 examples_src_root = os.path.join(REPO_ROOT,
"ContentExamples")
284 examples_dst_root =
ensure_dir(os.path.join(sdk_root,
"ContentExamples"))
286 def ignore_example(dirpath, names):
289 if n
in (
"Build",
"Intermediate",
".vs",
".vscode",
"x64"):
291 elif n.endswith(
".user")
or n.endswith(
".vcxproj")
or n.endswith(
".vcxproj.filters"):
295 if os.path.isdir(examples_src_root):
296 copy_tree(examples_src_root, examples_dst_root, ignore=ignore_example)
297 logging.info(
"Copied ContentExamples folder.")
300 for proj
in os.listdir(examples_dst_root):
301 proj_path = os.path.join(examples_dst_root, proj)
302 if os.path.isdir(proj_path):
303 build_script = os.path.join(proj_path,
"build_project.sh")
306 logging.warning(
"No ContentExamples folder found.")
311 ensure_dir(os.path.join(sdk_root,
"UserApplications"))
316 write_manifest(os.path.join(sdk_root,
"Manifest.txt"), version, platform)
322 archive_path = os.path.join(PACKAGE_ROOT, sdk_name)
325 for ext
in (
".tar.gz",
".zip",
".tgz"):
326 old = archive_path + ext
327 if os.path.exists(old):
330 shutil.make_archive(archive_path,
"gztar", root_dir=SDK_TEMP_ROOT)
331 logging.info(f
"Archive created: {archive_path}.tar.gz")
332 logging.info(
"=== SDK Packaging Complete ===")
334 except Exception
as e:
335 logging.error(f
"SDK packaging failed: {e}", exc_info=
True)
336 print(f
"SDK packaging failed: {e}")
339if __name__ ==
"__main__":
def copy_tree(src, dst, ignore=None)
def patch_build_script_for_sdk(build_script_path)
def write_manifest(path, version, platform)