Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 144 additions & 18 deletions compile_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,6 @@ def get_cmake_options(self) -> List[str]:
f"-D Qt6_DIR={self.install_dir}/lib/cmake/Qt6",
f"-D SWIG_EXECUTABLE={self.install_dir}/bin/swig" + to_exe(),
f"-D ZLIB_DIR={self.install_dir}/lib/cmake/",
f"-D ZLIB_INCLUDE_DIR={self.install_dir}/include",
f"-D ZLIB_LIBRARY_RELEASE={self.install_dir}/lib/zlib" + to_static(),
f"-D ZLIB_LIBRARY_DEBUG={self.install_dir}/lib/zlibd" + to_static(),
"-D CMAKE_DISABLE_FIND_PACKAGE_SoQt=True",
# Absolutely never find SoQt (it's deprecated and we don't want it!)
]
Expand Down Expand Up @@ -342,7 +339,7 @@ def build_python(self, args=None):
if os.path.exists(target):
os.unlink(target)
file.rename(target)
pyconfig = os.path.join("PCBuild", path.lower(), "pyconfig.h")
pyconfig = os.path.join("PC", "pyconfig.h")
target = os.path.join(inc_dir, "pyconfig.h")
if not os.path.exists(pyconfig):
print("ERROR: Could not locate pyconfig.h, cannot complete installation of Python")
Expand Down Expand Up @@ -513,7 +510,7 @@ def _build_qt_from_source(self, options: dict):

# Qt needs access to zlib and libpng, and assumes they are installed at the system level. We want to
# use the LibPack versions. The easiest thing to do is just copy the DLLs:
files = ["zlib.dll", "zlib1.dll", "libpng16.dll"]
files = ["z.dll", "libpng16.dll"]
source = os.path.join(self.install_dir, "bin")
destination = os.path.join(build_dir, "qtbase", "bin")
os.makedirs(destination, exist_ok=True)
Expand Down Expand Up @@ -737,8 +734,10 @@ def build_zlib(self, _=None):
self._build_standard_cmake()
# Qt really wants to find these under an alternate name, so just make copies...
name_mapping = [
(os.path.join("lib", "zlib.lib"), os.path.join("lib", "zlib1.lib")),
(os.path.join("bin", "zlib.dll"), os.path.join("bin", "zlib1.dll")),
(os.path.join("lib", "z.lib"), os.path.join("lib", "zlib.lib")),
(os.path.join("bin", "z.dll"), os.path.join("bin", "zlib.dll")),
(os.path.join("lib", "z.lib"), os.path.join("lib", "zlib1.lib")),
(os.path.join("bin", "z.dll"), os.path.join("bin", "zlib1.dll")),
]
for name1, name2 in name_mapping:
full_name1 = os.path.join(self.install_dir, name1)
Expand Down Expand Up @@ -1022,6 +1021,121 @@ def build_rapidjson(self, _):
shutil.rmtree(os.path.join(self.install_dir, "include", "rapidjson"))
shutil.copytree("include", os.path.join(self.install_dir, "include"), dirs_exist_ok=True)

def build_ifcopenshell(self, options: dict):
if os.path.exists(os.path.join(self.install_dir, "include", "ifcparse")):
if self.skip_existing:
print(" Not rebuilding IfcOpenShell, it is already in the LibPack")
return
ifcos_root = os.path.join(self.base_dir, "ifcopenshell")
src_patches_dir = os.path.join(os.path.dirname(self.base_dir), "patches")
win_dir = os.path.join(ifcos_root, "win")
win_patches_dir = os.path.join(win_dir, "patches")
os.makedirs(win_dir, exist_ok=True)
os.makedirs(win_patches_dir, exist_ok=True)
patch_files = {
"build-deps.cmd": win_dir,
"mpfr-arm64-changes.patch": win_patches_dir,
"mpir-arm64-changes.patch": win_patches_dir,
}
for name, dest_dir in patch_files.items():
src_file = os.path.join(src_patches_dir, name)
if os.path.exists(src_file):
shutil.copy(src_file, dest_dir)
vs_version = "vs2022" # TODO Un-hardcode
platform_str = "arm64" if platform.machine() == "ARM64" else "x64"
vs_platform = f"{vs_version}-{platform_str}"
build_cfg = "RelWithDebInfo" if self.mode == BuildMode.RELEASE else "Debug"
env = os.environ.copy()
if os.path.exists(self.python_exe()):
env["IFCOS_INSTALL_PYTHON"] = "FALSE"
env["PY_VER_MAJOR_MINOR"] = "314" # TODO Un-hardcode
env["PYTHONHOME"] = os.path.join(self.install_dir, "bin")
build_deps_cmd = os.path.join(win_dir, "build-deps.cmd")
try:
print(" Running build-deps.cmd")
subprocess.run(
[self.init_script, "&", build_deps_cmd, vs_platform, build_cfg],
check=True,
capture_output=True,
input="y\n".encode("utf-8"),
env=env,
cwd=win_dir,
)
except subprocess.CalledProcessError as e:
print(f"ERROR: IfcOpenShell build-deps.cmd failed!")
print(e.stdout.decode("utf-8", errors="ignore"))
if e.stderr:
print(e.stderr.decode("utf-8", errors="ignore"))
exit(e.returncode)
run_cmake_bat = os.path.join(win_dir, "run-cmake.bat")
if os.path.exists(run_cmake_bat):
try:
print(" Running run-cmake.bat")
subprocess.run(
[self.init_script, "&", run_cmake_bat, vs_platform, build_cfg],
check=True,
capture_output=True,
env=env,
cwd=win_dir,
)
except subprocess.CalledProcessError as e:
print(f"ERROR: IfcOpenShell CMake configuration failed!")
print(e.stdout.decode("utf-8", errors="ignore"))
if e.stderr:
print(e.stderr.decode("utf-8", errors="ignore"))
exit(e.returncode)
install_bat = os.path.join(win_dir, "install-ifcopenshell.bat")
if os.path.exists(install_bat):
try:
print(" Running install-ifcopenshell.bat")
subprocess.run(
[self.init_script, "&", install_bat, vs_platform, build_cfg],
check=True,
capture_output=True,
env=env,
cwd=win_dir,
)
except subprocess.CalledProcessError as e:
print(f"ERROR: IfcOpenShell installation failed!")
print(e.stdout.decode("utf-8", errors="ignore"))
if e.stderr:
print(e.stderr.decode("utf-8", errors="ignore"))
exit(e.returncode)
parent_dir = os.path.dirname(win_dir)
ifcos_install_dir = None
for item in os.listdir(parent_dir):
if item.startswith("_installed-") and vs_platform.lower() in item.lower():
ifcos_install_dir = os.path.join(parent_dir, item)
if os.path.exists(ifcos_install_dir):
break
if ifcos_install_dir:
for subdir in ["include", "lib", "bin"]:
src_path = os.path.join(ifcos_install_dir, subdir)
if os.path.exists(src_path):
dest_path = os.path.join(self.install_dir, subdir)
shutil.copytree(src_path, dest_path, dirs_exist_ok=True)
site_packages = os.path.join(
self.install_dir, "bin", "Lib", "site-packages", "ifcopenshell"
)
os.makedirs(site_packages, exist_ok=True)
for root, dirs, files in os.walk(ifcos_install_dir):
for file in files:
if file.endswith(".pyd") and "ifcopenshell" in file.lower():
shutil.copy2(os.path.join(root, file), os.path.join(site_packages, file))
ifcos_root = os.path.dirname(win_dir)
python_src_dir = os.path.join(ifcos_root, "src", "ifcopenshell-python", "ifcopenshell")
if os.path.exists(python_src_dir):
for item in os.listdir(python_src_dir):
src_item = os.path.join(python_src_dir, item)
dest_item = os.path.join(site_packages, item)
if os.path.isfile(src_item):
shutil.copy2(src_item, dest_item)
elif os.path.isdir(src_item):
shutil.copytree(src_item, dest_item, dirs_exist_ok=True)

print(" IfcOpenShell installed successfully")
os.chdir(self.base_dir)

def _get_vtk_include_path(self) -> str:
"""
OpenCASCADE needs a manually-set include path for VTK (the find_package script provided by VTK does not provide
Expand All @@ -1041,14 +1155,20 @@ def build_opencascade(self, _=None):
if os.path.exists(os.path.join(self.install_dir, "cmake", "OpenCASCADEConfig.cmake")):
print(" Not rebuilding OpenCASCADE, it is already in the LibPack")
return
install_dir = self.install_dir
vtk_include_dir = self._get_vtk_include_path()
if os.path.sep == "\\":
# OpenCASCADE's CMake is not tolerant of backslashes in paths, even on Windows
install_dir = install_dir.replace("\\", "/")
vtk_include_dir = vtk_include_dir.replace("\\", "/")
extra_args = [
f"-D CMAKE_MODULE_PATH={self.install_dir}/lib/cmake;{self.install_dir}/share/cmake;{self.install_dir}"
f"-D TCL_DIR={self.install_dir}/include",
f"-D TK_DIR={self.install_dir}/include",
f"-D FREETYPE_DIR={self.install_dir}/lib/cmake",
f"-D VTK_DIR={self.install_dir}/lib/cmake",
f"-D 3RDPARTY_VTK_INCLUDE_DIRS={self._get_vtk_include_path()}",
f"-D EIGEN_DIR={self.install_dir}/share/eigen3/cmake",
f"-D CMAKE_MODULE_PATH={install_dir}/lib/cmake;{install_dir}/share/cmake;{install_dir}"
f"-D TCL_DIR={install_dir}/include",
f"-D TK_DIR={install_dir}/include",
f"-D FREETYPE_DIR={install_dir}/lib/cmake",
f"-D VTK_DIR={install_dir}/lib/cmake",
f"-D 3RDPARTY_VTK_INCLUDE_DIRS={vtk_include_dir}",
f"-D EIGEN_DIR={install_dir}/share/eigen3/cmake",
"-D USE_VTK=On",
"-D USE_FREETYPE=On",
"-D USE_RAPIDJSON=On",
Expand Down Expand Up @@ -1099,6 +1219,7 @@ def build_netgen(self, _: None):
print(" Not rebuilding netgen, it is already in the LibPack")
return
extra_args = [
f"-D USE_NATIVE_ARCH=OFF", # prevent the use of AVX512, for portability
f"-D CMAKE_FIND_ROOT_PATH={self.install_dir}",
"-D USE_SUPERBUILD=OFF",
"-D USE_GUI=OFF",
Expand All @@ -1117,11 +1238,16 @@ def build_hdf5(self, _: None):
if os.path.exists(os.path.join(self.install_dir, "include", "hdf5.h")):
print(" Not rebuilding hdf5, it is already in the LibPack")
return
# HDF5 is VERY picky about how you specify the location of zlib: you must actually set the precise path to the
# library file itself. TODO future work to internally detect that library name and path and fill them here

# Per the recommendation of the HDF5 developers, let HDF5 build and link to its own internal
# copy of ZLib, since their CMake scripts are broken when trying to use a custom compiled
# version. See e.g. https://github.com/HDFGroup/hdf5/issues/5303
extra_args = [
f"-D ZLIB_INCLUDE_DIR={self.install_dir}/include",
f"-D ZLIB_LIBRARY={self.install_dir}/lib/zlib.lib",
"-D HDF5_BUILD_EXAMPLES=OFF",
"-D HDF5_BUILD_TOOLS=OFF",
"-D HDF5_BUILD_UTILS=OFF",
"-D HDF5_ENABLE_Z_LIB_SUPPORT=ON",
"-D ZLIB_USE_EXTERNAL=ON",
]
self._build_standard_cmake(extra_args)

Expand Down
Loading