Created
December 12, 2023 11:14
-
-
Save ideasman42/80390355b49ff82cd6a7582a33d5484d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import os | |
import re | |
import shutil | |
import subprocess | |
SOURCE_DIR = "/src/blender" | |
def create_cc_wrapper(filepath: str, compiler_orig: str) -> None: | |
with open(filepath, 'w', encoding='utf-8') as fh: | |
fh.write(" \\\n".join([ | |
"#!/bin/dash\nexec " + compiler_orig, | |
"$@", | |
"-Wno-error=deprecated-declarations", | |
"-Werror=incompatible-pointer-types", | |
"-Wvla", | |
"-Wno-error=clobbered", | |
"-Wno-error=cast-function-type", | |
"-Werror=discarded-array-qualifiers", | |
"-Werror=discarded-qualifiers", | |
])) | |
os.chmod(filepath, 0o777) | |
def create_cxx_wrapper(filepath, compiler_orig: str) -> None: | |
with open(filepath, 'w', encoding='utf-8') as fh: | |
fh.write(" \\\n".join([ | |
"#!/bin/dash\nexec " + compiler_orig, | |
"$@", | |
"-Wno-error=deprecated-declarations", | |
"-Wno-error=terminate", | |
"-Wno-expansion-to-defined", | |
"-Wno-maybe-uninitialized", | |
"-fdiagnostics-color=always", | |
])) | |
os.chmod(filepath, 0o777) | |
def version_directory_name(): | |
filepath = os.path.join(SOURCE_DIR, "source", "blender", "blenkernel", "BKE_blender_version.h") | |
line_re = re.compile(r"^#define (BLENDER_VERSION[A-Z_]*)\s+([0-9a-z]+)$") | |
version_info = {} | |
with open(filepath, encoding="utf-8") as fh: | |
for line in fh: | |
match = line_re.match(line.strip()) | |
if not match: | |
continue | |
version_info[match.group(1)] = match.group(2) | |
version = int(version_info["BLENDER_VERSION"]) | |
version_major = version // 100 | |
version_minor = version % 100 | |
return "{:d}.{:d}".format(version_major, version_minor) | |
def create_fake_install(build_dir: str) -> None: | |
VERSION_NAME = version_directory_name() | |
BUILD_VERSION_DIR = os.path.join(build_dir, "bin", VERSION_NAME) | |
os.makedirs(BUILD_VERSION_DIR) | |
SOURCE_RELEASE_DIR = os.path.join(SOURCE_DIR, "release") | |
for f in os.listdir(SOURCE_RELEASE_DIR): | |
os.symlink( | |
os.path.join(SOURCE_RELEASE_DIR, f), | |
os.path.join(BUILD_VERSION_DIR, f), | |
) | |
os.symlink( | |
os.path.join(os.path.join(SOURCE_DIR, "scripts")), | |
os.path.join(BUILD_VERSION_DIR, "scripts"), | |
) | |
def gen_build_dir( | |
source_dir: str, | |
build_dir: str, | |
compiler_family: str, | |
debug: bool, | |
precompiled_libs: bool, | |
fake_install: bool, | |
) -> None: | |
# Avoid errors `cwd`. | |
cwd = os.getcwd() | |
if os.path.exists(build_dir): | |
shutil.rmtree(build_dir) | |
os.mkdir(build_dir) | |
os.chdir(cwd) | |
del cwd | |
do_compiler_wrappers = debug | |
do_compiler_asan = debug | |
do_local_python = False | |
do_lite_config = debug | |
if fake_install: | |
create_fake_install(build_dir) | |
# TODO: error check missing compilers. | |
if compiler_family == 'GCC': | |
compiler_bin_c = shutil.which("gcc") | |
compiler_bin_cxx = shutil.which("g++") | |
elif compiler_family == 'CLANG': | |
compiler_bin_c = shutil.which("clang") | |
compiler_bin_cxx = shutil.which("clang++") | |
else: | |
print("Unknown compiler family", compiler_family, "aborting!") | |
return | |
if do_compiler_wrappers: | |
compiler_c_wrap = os.path.join(os.path.join(build_dir, "cc.wrap.sh")) | |
compiler_cxx_wrap = os.path.join(os.path.join(build_dir, "cxx.wrap.sh")) | |
create_cc_wrapper(compiler_c_wrap, compiler_bin_c) | |
create_cxx_wrapper(compiler_cxx_wrap, compiler_bin_cxx) | |
compiler_bin_c = compiler_c_wrap | |
compiler_bin_cxx = compiler_cxx_wrap | |
del compiler_c_wrap | |
del compiler_cxx_wrap | |
# TODO: error check missing compilers. | |
if compiler_family == 'GCC': | |
compiler_c_flags_debug = ( | |
"-ggdb3", | |
"-fno-inline", | |
"-ftrivial-auto-var-init=pattern", | |
"-O0", | |
"-Wall", | |
"-Wunused", | |
"-Wextra", | |
# Various warnings: | |
"-Wabsolute-value", | |
"-Warray-bounds=2", | |
"-Warray-parameter", | |
"-Wduplicated-cond", | |
"-Wformat-overflow", | |
"-Wformat-truncation", | |
"-Wmisleading-indentation", | |
"-Wnull-dereference", | |
"-Wstringop-truncation", | |
"-Wsuggest-attribute=const", | |
"-Wsuggest-attribute=format", | |
"-Wsuggest-attribute=malloc", | |
"-Wsuggest-attribute=pure", | |
"-Wuninitialized", | |
# Various warnings (disable): | |
"-Wno-cast-function-type", | |
"-Wno-error=maybe-uninitialized", | |
"-Wno-error=unused-function", | |
"-Wno-missing-field-initializers", | |
"-Wno-return-local-addr", | |
"-Wno-sign-compare", | |
"-Wno-stringop-overflow", | |
"-Wno-stringop-overread", | |
# Noisy but useful at times. | |
# "-Wlogical-op", | |
# "-Wunused-macros", | |
# "-Wstack-usage=10000", | |
# "-Wduplicated-branches", | |
) | |
compiler_cxx_flags_debug = ( | |
"-ggdb3", | |
"-fno-inline", | |
"-ftrivial-auto-var-init=pattern", | |
"-O0", | |
"-Wall", | |
"-Wunused", | |
"-Wextra", | |
# "-Wstack-usage=10000", | |
# Various warnings: | |
"-Warray-bounds=2", | |
"-Warray-parameter", | |
"-Wduplicated-cond", | |
"-Wformat-overflow", | |
"-Wformat-truncation", | |
"-Wmisleading-indentation", | |
"-Wnull-dereference", | |
"-Wstringop-truncation", | |
"-Wsuggest-attribute=const", | |
"-Wsuggest-attribute=format", | |
"-Wsuggest-attribute=malloc", | |
"-Wsuggest-attribute=pure", | |
"-Wuninitialized", | |
# Various warnings (disable): | |
"-Wno-cast-function-type", | |
"-Wno-dangling-reference", | |
"-Wno-error=maybe-uninitialized", | |
"-Wno-error=unused-function", | |
"-Wno-ignored-qualifiers", | |
"-Wno-missing-field-initializers", | |
"-Wno-return-local-addr", | |
"-Wno-sign-compare", | |
"-Wno-stringop-overflow", | |
"-Wno-stringop-overread", | |
"-Wchanges-meaning", | |
"-Wattributes", | |
"-Wcomma-subscript", | |
"-Wmain", | |
"-Wnarrowing", | |
"-Wregister", | |
"-Wvla", | |
"-Wwrite-strings", | |
# TODO: we might want to shadow. | |
# "-Wshadow", | |
# Noisy but useful at times. | |
# "-Wunused-macros", | |
# "-Wduplicated-branches", | |
) | |
elif compiler_family == 'CLANG': | |
compiler_c_flags_debug = ( | |
"-ggdb3", | |
"-fno-inline", | |
"-ftrivial-auto-var-init=pattern", | |
"-O0", | |
"-Wall", | |
"-Wunused", | |
"-Wextra", | |
) | |
compiler_cxx_flags_debug = ( | |
"-ggdb3", | |
"-fno-inline", | |
"-ftrivial-auto-var-init=pattern", | |
"-O0", | |
"-Wall", | |
"-Wunused", | |
"-Wextra", | |
# "-Wstack-usage=10000", | |
) | |
args = [ | |
"cmake", | |
"-Wdev", | |
"-Wdeprecated", | |
"-B", build_dir, | |
"-S", SOURCE_DIR, | |
"-G", "Ninja" if debug else "Unix Makefiles", | |
*(["-C", os.path.join(SOURCE_DIR, "build_files/cmake/config/blender_lite.cmake")] if do_lite_config else []), | |
"-D", "CMAKE_BUILD_TYPE:STRING=" + ( | |
"Debug" if debug else | |
# "RelWithDebInfo" | |
"Release" | |
), | |
"-D", "CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON", | |
"-D", "WITH_LINKER_MOLD:BOOL=ON", | |
# Incompatible with "code_clean" utility. | |
"-D", "WITH_UNITY_BUILD:BOOL=OFF", | |
"-D", "WITH_COMPILER_CCACHE:BOOL=ON", | |
# Use my systems libraries. | |
"-D", "WITH_LIBS_PRECOMPILED:BOOL=" + ("ON" if precompiled_libs else "OFF"), | |
# Enable tests. | |
"-D", "WITH_GTESTS:BOOL=ON", | |
# Debug string overflow. | |
"-D", "WITH_STRSIZE_DEBUG:BOOL=ON", | |
# Support VALGRIND. | |
"-D", "WITH_MEM_VALGRIND:BOOL=" + ("ON" if debug else "OFF"), | |
# JEMALLOC isn't compatible with ASAN. | |
"-D", "WITH_MEM_JEMALLOC:BOOL=OFF", | |
# Compiler flags. | |
"-D", "CMAKE_C_FLAGS:STRING=-fdiagnostics-color=always -Werror=parentheses", | |
"-D", "CMAKE_CXX_FLAGS:STRING=-fdiagnostics-color=always -Werror=parentheses", | |
# Used by LSP programs such as CLANGD. | |
"-D", "CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON", | |
"-D", "CMAKE_C_FLAGS_DEBUG:STRING=" + " ".join([ | |
*compiler_c_flags_debug, | |
]), | |
"-D", "CMAKE_CXX_FLAGS_DEBUG:STRING=" + " ".join([ | |
*compiler_cxx_flags_debug, | |
]), | |
# ASAN flags. | |
"-D", "COMPILER_ASAN_CFLAGS:STRING=" + " ".join([ | |
"-Wanalyzer-allocation-size", | |
"-Wanalyzer-deref-before-check", | |
"-Wanalyzer-exposure-through-uninit-copy", | |
"-Wanalyzer-fd-access-mode-mismatch", | |
"-Wanalyzer-fd-double-close", | |
"-Wanalyzer-fd-leak", | |
"-Wanalyzer-fd-phase-mismatch", | |
"-Wanalyzer-fd-type-mismatch", | |
"-Wanalyzer-fd-use-after-close", | |
"-Wanalyzer-fd-use-without-check", | |
"-Wanalyzer-imprecise-fp-arithmetic", | |
"-Wanalyzer-infinite-recursion", | |
"-Wanalyzer-jump-through-null", | |
"-Wanalyzer-out-of-bounds", | |
"-Wanalyzer-putenv-of-auto-var", | |
"-Wanalyzer-tainted-assertion", | |
"-Wanalyzer-use-of-uninitialized-value", | |
"-Wanalyzer-write-to-const", | |
"-Wanalyzer-write-to-string-literal ", | |
"-fno-sanitize=alignment", | |
"-fsanitize-address-use-after-scope", | |
"-fsanitize=address", | |
"-fsanitize=bool", | |
"-fsanitize=bounds", | |
"-fsanitize=enum", | |
"-fsanitize=float-cast-overflow", | |
"-fsanitize=float-divide-by-zero", | |
"-fsanitize=leak", | |
"-fsanitize=nonnull-attribute", | |
"-fsanitize=object-size", | |
"-fsanitize=returns-nonnull-attribute", | |
"-fsanitize=signed-integer-overflow", | |
"-fsanitize=vla-bound", | |
]), | |
"-D", "COMPILER_ASAN_CXXFLAGS:STRING=" + " ".join([ | |
"-Wanalyzer-allocation-size", | |
"-Wanalyzer-deref-before-check", | |
"-Wanalyzer-exposure-through-uninit-copy", | |
"-Wanalyzer-fd-access-mode-mismatch", | |
"-Wanalyzer-fd-double-close", | |
"-Wanalyzer-fd-leak", | |
"-Wanalyzer-fd-phase-mismatch", | |
"-Wanalyzer-fd-type-mismatch", | |
"-Wanalyzer-fd-use-after-close", | |
"-Wanalyzer-fd-use-without-check", | |
"-Wanalyzer-imprecise-fp-arithmetic", | |
"-Wanalyzer-infinite-recursion", | |
"-Wanalyzer-jump-through-null", | |
"-Wanalyzer-out-of-bounds", | |
"-Wanalyzer-putenv-of-auto-var", | |
"-Wanalyzer-tainted-assertion", | |
"-Wanalyzer-use-of-uninitialized-value", | |
"-Wanalyzer-write-to-const", | |
"-Wanalyzer-write-to-string-literal ", | |
"-fno-sanitize=alignment", | |
"-fsanitize-address-use-after-scope", | |
"-fsanitize=address", | |
"-fsanitize=bool", | |
"-fsanitize=bounds", | |
"-fsanitize=enum", | |
"-fsanitize=float-cast-overflow", | |
"-fsanitize=float-divide-by-zero", | |
"-fsanitize=leak", | |
"-fsanitize=nonnull-attribute", | |
"-fsanitize=object-size", | |
"-fsanitize=returns-nonnull-attribute", | |
"-fsanitize=signed-integer-overflow", | |
"-fsanitize=vla-bound", | |
]), | |
] | |
args.extend([ | |
"-D", "CMAKE_C_COMPILER:STRING=" + compiler_bin_c, | |
"-D", "CMAKE_CXX_COMPILER=" + compiler_bin_cxx, | |
]) | |
if do_compiler_asan: | |
args.extend([ | |
"-D", "WITH_COMPILER_ASAN:BOOL=ON", | |
]) | |
if do_local_python: | |
args.extend([ | |
"-D", "PYTHON_VERSION:STRING=3.12", | |
"-D", "PYTHON_ROOT_DIR:FILEPATH=/opt/py312", | |
"-D", "WITH_PYTHON_INSTALL:BOOL=OFF", | |
"-D", "WITH_PYTHON_INSTALL_ZSTANDARD:BOOL=OFF", | |
]) | |
else: | |
if not precompiled_libs: | |
args.extend([ | |
"-D", "PYTHON_VERSION:STRING=3.11", | |
"-D", "WITH_PYTHON_INSTALL:BOOL=OFF", | |
"-D", "WITH_PYTHON_INSTALL_ZSTANDARD:BOOL=OFF", | |
]) | |
subprocess.call(args) | |
def main(): | |
import sys | |
if "debug" in sys.argv: | |
gen_build_dir( | |
source_dir="/src/blender", | |
build_dir="/src/cmake_debug", | |
compiler_family="GCC", | |
debug=True, | |
precompiled_libs=False, | |
fake_install=True, | |
) | |
if "release" in sys.argv: | |
gen_build_dir( | |
source_dir="/src/blender", | |
build_dir="/src/cmake_release", | |
compiler_family="CLANG", | |
debug=False, | |
precompiled_libs=True, | |
fake_install=False, | |
) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment