mirror of
https://github.com/kiwix/kiwix-build.git
synced 2025-06-27 21:39:34 +00:00
The target_platform option has always be wrongly named. This is not the platform we are targeted but how we compile. This was ok at beginning as specifying how we compile somehow define for what we compile but this is not a one to one mapping.
181 lines
6.6 KiB
Python
181 lines
6.6 KiB
Python
import os, sys, shutil
|
|
import subprocess
|
|
import platform
|
|
import distro
|
|
|
|
from .utils import pj, download_remote, escape_path
|
|
from ._global import neutralEnv, option
|
|
|
|
|
|
class NeutralEnv:
|
|
def __init__(self):
|
|
self.working_dir = option("working_dir")
|
|
self.source_dir = pj(self.working_dir, "SOURCE")
|
|
self.archive_dir = pj(self.working_dir, "ARCHIVE")
|
|
self.toolchain_dir = pj(self.working_dir, "TOOLCHAINS")
|
|
self.log_dir = pj(self.working_dir, "LOGS")
|
|
for d in (self.source_dir, self.archive_dir, self.toolchain_dir, self.log_dir):
|
|
os.makedirs(d, exist_ok=True)
|
|
self.detect_platform()
|
|
self.ninja_command = self._detect_command(
|
|
"ninja", default=[["ninja"], ["ninja-build"]]
|
|
)
|
|
self.meson_command = self._detect_command(
|
|
"meson", default=[["meson.py"], ["meson"]]
|
|
)
|
|
self.mesontest_command = [*self.meson_command, "test"]
|
|
self.patch_command = self._detect_command("patch")
|
|
self.git_command = self._detect_command("git")
|
|
self.make_command = self._detect_command("make")
|
|
self.cmake_command = self._detect_command("cmake")
|
|
self.qmake_command = self._detect_command("qmake", required=False)
|
|
|
|
def detect_platform(self):
|
|
_platform = platform.system()
|
|
self.distname = _platform
|
|
if _platform == "Windows":
|
|
print(
|
|
"ERROR: kiwix-build is not intented to run on Windows platform.\n"
|
|
"It should probably not work, but well, you still can have a try."
|
|
)
|
|
cont = input("Do you want to continue ? [y/N]")
|
|
if cont.lower() != "y":
|
|
sys.exit(0)
|
|
if _platform == "Linux":
|
|
self.distname = distro.id()
|
|
if self.distname == "ubuntu":
|
|
self.distname = "debian"
|
|
|
|
def download(self, what, where=None):
|
|
where = where or self.archive_dir
|
|
download_remote(what, where)
|
|
|
|
def _detect_command(self, name, default=None, options=["--version"], required=True):
|
|
if default is None:
|
|
default = [[name]]
|
|
env_key = "KBUILD_{}_COMMAND".format(name.upper())
|
|
if env_key in os.environ:
|
|
default = [os.environ[env_key].split()] + default
|
|
for command in default:
|
|
try:
|
|
retcode = subprocess.check_call(
|
|
command + options, stdout=subprocess.DEVNULL
|
|
)
|
|
except (FileNotFoundError, PermissionError, OSError):
|
|
# Doesn't exist in PATH or isn't executable
|
|
continue
|
|
if retcode == 0:
|
|
return command
|
|
else:
|
|
if required:
|
|
sys.exit("ERROR: {} command not found".format(name))
|
|
else:
|
|
print("WARNING: {} command not found".format(name))
|
|
return ["{}_NOT_FOUND".format(name.upper())]
|
|
|
|
|
|
class BuildEnv:
|
|
def __init__(self, configInfo):
|
|
build_dir = "BUILD_{}".format(configInfo.name)
|
|
self.configInfo = configInfo
|
|
self.base_build_dir = pj(option("working_dir"), option("build_dir"))
|
|
self.build_dir = pj(self.base_build_dir, build_dir)
|
|
self.install_dir = pj(self.build_dir, "INSTALL")
|
|
self.toolchain_dir = pj(self.build_dir, "TOOLCHAINS")
|
|
self.log_dir = pj(self.build_dir, "LOGS")
|
|
for d in (self.build_dir, self.install_dir, self.toolchain_dir, self.log_dir):
|
|
os.makedirs(d, exist_ok=True)
|
|
|
|
self.libprefix = option("libprefix") or self._detect_libdir()
|
|
|
|
def clean_intermediate_directories(self):
|
|
for subdir in os.listdir(self.build_dir):
|
|
subpath = pj(self.build_dir, subdir)
|
|
if subpath == self.install_dir:
|
|
continue
|
|
if os.path.isdir(subpath):
|
|
shutil.rmtree(subpath)
|
|
else:
|
|
os.remove(subpath)
|
|
|
|
def _is_debianlike(self):
|
|
return os.path.isfile("/etc/debian_version")
|
|
|
|
def _detect_libdir(self):
|
|
if self.configInfo.libdir is not None:
|
|
return self.configInfo.libdir
|
|
if self._is_debianlike():
|
|
try:
|
|
pc = subprocess.Popen(
|
|
["dpkg-architecture", "-qDEB_HOST_MULTIARCH"],
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.DEVNULL,
|
|
)
|
|
(stdo, _) = pc.communicate()
|
|
if pc.returncode == 0:
|
|
archpath = stdo.decode().strip()
|
|
return "lib/" + archpath
|
|
except Exception:
|
|
pass
|
|
if os.path.isdir("/usr/lib64") and not os.path.islink("/usr/lib64"):
|
|
return "lib64"
|
|
return "lib"
|
|
|
|
def get_env(self, *, cross_comp_flags, cross_compilers, cross_path):
|
|
env = self.configInfo.get_env()
|
|
pkgconfig_path = pj(self.install_dir, self.libprefix, "pkgconfig")
|
|
env["PKG_CONFIG_PATH"] = ":".join([env["PKG_CONFIG_PATH"], pkgconfig_path])
|
|
|
|
env["PATH"] = ":".join([escape_path(pj(self.install_dir, "bin")), env["PATH"]])
|
|
|
|
env["LD_LIBRARY_PATH"] = ":".join(
|
|
[
|
|
env["LD_LIBRARY_PATH"],
|
|
pj(self.install_dir, "lib"),
|
|
pj(self.install_dir, self.libprefix),
|
|
]
|
|
)
|
|
|
|
env["QMAKE_CXXFLAGS"] = " ".join(
|
|
[escape_path("-I" + pj(self.install_dir, "include")), env["QMAKE_CXXFLAGS"]]
|
|
)
|
|
env["CPPFLAGS"] = " ".join(
|
|
[escape_path("-I" + pj(self.install_dir, "include")), env["CPPFLAGS"]]
|
|
)
|
|
env["QMAKE_LFLAGS"] = " ".join(
|
|
[
|
|
escape_path("-L" + pj(self.install_dir, "lib")),
|
|
escape_path("-L" + pj(self.install_dir, self.libprefix)),
|
|
env["QMAKE_LFLAGS"],
|
|
]
|
|
)
|
|
env["LDFLAGS"] = " ".join(
|
|
[
|
|
escape_path("-L" + pj(self.install_dir, "lib")),
|
|
escape_path("-L" + pj(self.install_dir, self.libprefix)),
|
|
env["LDFLAGS"],
|
|
]
|
|
)
|
|
|
|
if cross_comp_flags:
|
|
self.configInfo.set_comp_flags(env)
|
|
if cross_compilers:
|
|
self.configInfo.set_compiler(env)
|
|
if cross_path:
|
|
env["PATH"] = ":".join(self.configInfo.get_bin_dir() + [env["PATH"]])
|
|
return env
|
|
|
|
@property
|
|
def configure_wrapper(self):
|
|
try:
|
|
yield self.configInfo.configure_wrapper
|
|
except AttributeError:
|
|
pass
|
|
|
|
@property
|
|
def make_wrapper(self):
|
|
try:
|
|
yield self.configInfo.make_wrapper
|
|
except AttributeError:
|
|
pass
|