mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-20 23:01:16 +00:00
115 lines
4.0 KiB
Python
Executable File
115 lines
4.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import io
|
|
import os
|
|
import pathlib
|
|
import platform
|
|
import requests
|
|
import shutil
|
|
import subprocess
|
|
import textwrap
|
|
import zipfile
|
|
|
|
ISLE_PATH = pathlib.Path(__file__).parents[0]
|
|
|
|
parser = argparse.ArgumentParser(allow_abbrev=False)
|
|
parser.add_argument("-m", "--modern-compiler", action="store_true",
|
|
help="Use a contemporary compiler instead of Microsoft Visual C++ 4.2 even though this will result in non-matching code")
|
|
parser.add_argument("-B", dest="builddir", default=ISLE_PATH / "build", type=pathlib.Path, help="build directory")
|
|
args = parser.parse_args()
|
|
|
|
builddir = args.builddir.resolve()
|
|
|
|
compilerdir = ISLE_PATH / "tools/msvc42"
|
|
|
|
# Create a build folder in the current directory if it does not exist
|
|
builddir.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Check if MSVC420 is in the INCLUDE environment variable
|
|
set_compiler_paths = not args.modern_compiler
|
|
if not args.modern_compiler and not compilerdir.exists():
|
|
# Create a folder for the compiler
|
|
compilerdir.mkdir(parents=True, exist_ok=True)
|
|
|
|
print(f"MSVC420 not found in {compilerdir}/...")
|
|
url = "https://github.com/itsmattkc/MSVC420/archive/refs/heads/master.zip"
|
|
print("Downloading MSVC420...")
|
|
r = requests.get(url, stream=True)
|
|
print(f"Unzipping MSVC420 to {compilerdir}/...")
|
|
z = zipfile.ZipFile(io.BytesIO(r.content))
|
|
z.extractall(path=str(compilerdir))
|
|
|
|
# Run cmake in the build folder
|
|
cmake_cmd = [
|
|
"cmake",
|
|
str(ISLE_PATH),
|
|
"-G", "Ninja",
|
|
"-DCMAKE_BUILD_TYPE=RelWithDebInfo"
|
|
]
|
|
|
|
# Do we have a builtin ninja?
|
|
if shutil.which("ninja") is None:
|
|
sys = platform.system()
|
|
ninjadir = ISLE_PATH / "tools/ninja" / sys
|
|
ninja_urls = {
|
|
"Windows": "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip",
|
|
"Linux": "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip",
|
|
"Darwin": "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-mac.zip",
|
|
}
|
|
if sys not in ninja_urls:
|
|
print("Ninja is not available for this platform, please install ninja and add it to your PATH.")
|
|
exit(1)
|
|
if not ninjadir.exists():
|
|
print("Downloading Ninja...")
|
|
r = requests.get(ninja_urls[sys], stream=True)
|
|
print(f"Unzipping Ninja to {ninjadir}/...")
|
|
z = zipfile.ZipFile(io.BytesIO(r.content))
|
|
z.extractall(path=str(ninjadir))
|
|
|
|
specific_ninja = ninjadir / ("ninja" + ".exe" if sys == "Windows" else "")
|
|
|
|
print("Using specific ninja:", specific_ninja)
|
|
cmake_cmd += [f"-DCMAKE_MAKE_PROGRAM={specific_ninja.as_posix()}"]
|
|
|
|
extra_include_dirs = []
|
|
extra_library_dirs = []
|
|
|
|
if set_compiler_paths:
|
|
full_compiler_path = compilerdir / "MSVC420-master"
|
|
cl_path = (full_compiler_path / "bin" / "CL.EXE").as_posix()
|
|
link_path = (full_compiler_path / "bin" / "LINK.EXE").as_posix()
|
|
rc_path = (full_compiler_path / "bin" / "RC.EXE").as_posix()
|
|
|
|
extra_include_dirs += [
|
|
(full_compiler_path / "include").as_posix(),
|
|
]
|
|
extra_library_dirs += [
|
|
(full_compiler_path / "lib").as_posix(),
|
|
]
|
|
|
|
cmake_toolchain_file = builddir / "msvc42.cmake"
|
|
cmake_cmd += [f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}"]
|
|
with cmake_toolchain_file.open("w") as f:
|
|
print(textwrap.dedent(f"""\
|
|
set(CMAKE_C_COMPILER "{cl_path}")
|
|
set(CMAKE_CXX_COMPILER "{cl_path}")
|
|
set(CMAKE_RC_COMPILER "{rc_path}")
|
|
set(CMAKE_LINKER "{link_path}")
|
|
"""), file=f)
|
|
for incdir in extra_include_dirs:
|
|
print(f"""include_directories("{incdir}")""", file=f)
|
|
for libdir in extra_library_dirs:
|
|
print(f"""link_directories("{libdir}")""", file=f)
|
|
|
|
print("cmake command:", " ".join(cmake_cmd))
|
|
subprocess.run(cmake_cmd, cwd=builddir)
|
|
|
|
# Create a folder for the original binaries
|
|
if not pathlib.Path("original/LEGO1.DLL").exists():
|
|
pathlib.Path("original").mkdir(parents=True, exist_ok=True)
|
|
print("\nIf you plan on contributing, place a copy of the original game's "
|
|
"ISLE.EXE and LEGO1.DLL into the `original/` folder so that the assembly "
|
|
"diff tools can compare against them. If you do not, build.py will download "
|
|
"a copy of these files for you.")
|