Merge pull request #719 from kiwix/win-kiwix-desktop

This commit is contained in:
Matthieu Gautier 2024-08-26 12:26:22 +02:00 committed by GitHub
commit 4ff5132704
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 178 additions and 40 deletions

View File

@ -24,7 +24,7 @@ BUILD_DEF = """
# On Windows, we build only libzim for now. And only native_mixed as xapian doesn't compile as dll # On Windows, we build only libzim for now. And only native_mixed as xapian doesn't compile as dll
| windows | native_static | Bd | d | | d | | win-x86_64 | win-x86_64-static | | windows | native_static | Bd | d | | d | | win-x86_64 | win-x86_64-static |
| windows | native_dyn | Bd | | | | | win-x86_64 | win-x86_64-dyn | | windows | native_dyn | Bd | | | | | win-x86_64 | win-x86_64-dyn |
| windows | native_mixed | BPd | d | | | d | win-x86_64 | win-x86_64-mixed | | windows | native_mixed | BPd | d | | | Bd | win-x86_64 | win-x86_64-mixed |
---------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------
# Osx builds, build binaries on native_dyn and native_static. On anyother things, build only the libraries # Osx builds, build binaries on native_dyn and native_static. On anyother things, build only the libraries
| macos | native_dyn | d | d | dB | B | | | macos-x86_64-dyn | | macos | native_dyn | d | d | dB | B | | | macos-x86_64-dyn |

View File

@ -42,9 +42,13 @@ SOURCE_DIR = HOME / "SOURCE"
ARCHIVE_DIR = HOME / "ARCHIVE" ARCHIVE_DIR = HOME / "ARCHIVE"
TOOLCHAIN_DIR = BASE_DIR / "TOOLCHAINS" TOOLCHAIN_DIR = BASE_DIR / "TOOLCHAINS"
INSTALL_DIR = BASE_DIR / "INSTALL" INSTALL_DIR = BASE_DIR / "INSTALL"
default_tmp_dir = os.getenv("TEMP") if platform.system() == 'Windows' else "/tmp" default_tmp_dir = os.getenv("TEMP") if platform.system() == "Windows" else "/tmp"
TMP_DIR = Path(os.getenv("TMP_DIR", default_tmp_dir)) TMP_DIR = Path(os.getenv("TMP_DIR", default_tmp_dir))
KBUILD_SOURCE_DIR = HOME / "kiwix-build" if platform.system() == "Windows":
KBUILD_SOURCE_DIR = Path(_environ["GITHUB_WORKSPACE"])
else:
KBUILD_SOURCE_DIR = HOME / "kiwix-build"
_ref = _environ.get("GITHUB_REF", "").split("/")[-1] _ref = _environ.get("GITHUB_REF", "").split("/")[-1]
MAKE_RELEASE = re.fullmatch(r"r_[0-9]+", _ref) is not None MAKE_RELEASE = re.fullmatch(r"r_[0-9]+", _ref) is not None
@ -204,6 +208,7 @@ def run_kiwix_build(
subprocess.check_call(command, cwd=str(HOME), env=env) subprocess.check_call(command, cwd=str(HOME), env=env)
print_message("Build ended") print_message("Build ended")
try: try:
import paramiko import paramiko
@ -216,8 +221,8 @@ try:
host, port = host.split(":", 1) host, port = host.split(":", 1)
else: else:
port = "22" port = "22"
if '@' in host: if "@" in host:
user, host = host.split('@', 1) user, host = host.split("@", 1)
else: else:
user = None user = None
@ -228,7 +233,14 @@ try:
client = paramiko.client.SSHClient() client = paramiko.client.SSHClient()
client.set_missing_host_key_policy(paramiko.client.WarningPolicy) client.set_missing_host_key_policy(paramiko.client.WarningPolicy)
print_message(f"Connect to {host}:{port}") print_message(f"Connect to {host}:{port}")
client.connect(host, port=port, username=user, key_filename=_environ.get("SSH_KEY"), look_for_keys=False, compress=True) client.connect(
host,
port=port,
username=user,
key_filename=_environ.get("SSH_KEY"),
look_for_keys=False,
compress=True,
)
try: try:
yield client yield client
finally: finally:
@ -257,7 +269,6 @@ try:
print_message(f"Sending archive {file_to_upload} to {remote_file}") print_message(f"Sending archive {file_to_upload} to {remote_file}")
sftp.put(str(file_to_upload), str(remote_file), confirm=True) sftp.put(str(file_to_upload), str(remote_file), confirm=True)
except ModuleNotFoundError: except ModuleNotFoundError:
# On old system (bionic) paramiko is really complex to install # On old system (bionic) paramiko is really complex to install
# Keep the old implementaion on sush system. # Keep the old implementaion on sush system.
@ -473,11 +484,27 @@ def create_desktop_image(make_release):
build_path = BASE_DIR / "org.kiwix.desktop.flatpak" build_path = BASE_DIR / "org.kiwix.desktop.flatpak"
app_name = "org.kiwix.desktop.{}.flatpak".format(postfix) app_name = "org.kiwix.desktop.{}.flatpak".format(postfix)
print_message("archive is {}", build_path) print_message("archive is {}", build_path)
elif platform.system() == "Windows":
archive_basename = "Kiwix-{}-win-amd64".format(postfix)
working_dir = INSTALL_DIR / archive_basename
build_path = working_dir.with_suffix(".zip")
app_name = build_path.name
command = [
"python",
KBUILD_SOURCE_DIR / "scripts" / "package_kiwix-desktop_windows.py",
str(INSTALL_DIR),
str(working_dir),
str(build_path),
]
if make_release:
command += ["-s"]
print_message("Package archive of kiwix-desktop")
subprocess.check_call(command, cwd=str(HOME))
else: else:
build_path = HOME / "Kiwix-{}-x86_64.AppImage".format(postfix) build_path = HOME / "Kiwix-{}-x86_64.AppImage".format(postfix)
app_name = "kiwix-desktop_x86_64_{}.appimage".format(postfix) app_name = "kiwix-desktop_x86_64_{}.appimage".format(postfix)
command = [ command = [
"kiwix-build/scripts/create_kiwix-desktop_appImage.sh", KBUILD_SOURCE_DIR / "scripts" / "create_kiwix-desktop_appImage.sh",
str(INSTALL_DIR), str(INSTALL_DIR),
str(src_dir), str(src_dir),
str(HOME / "AppDir"), str(HOME / "AppDir"),

View File

@ -22,10 +22,10 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Setup python 3.8 - name: Setup python 3.12
uses: actions/setup-python@v3 uses: actions/setup-python@v3
with: with:
python-version: '3.8' python-version: '3.12'
- name: Install packages - name: Install packages
run: | run: |
choco.exe install pkgconfiglite ninja choco.exe install pkgconfiglite ninja
@ -34,6 +34,12 @@ jobs:
run: | run: |
pip3 install meson pytest requests distro paramiko pip3 install meson pytest requests distro paramiko
pip3 install --no-deps $GITHUB_WORKSPACE pip3 install --no-deps $GITHUB_WORKSPACE
- name: Install QT
uses: jurplel/install-qt-action@v4
with:
version: 5.15.2
modules: "qtwebengine"
setup-python: false
- name: Setup MSVC compiler - name: Setup MSVC compiler
uses: bus1/cabuild/action/msdevshell@v1 uses: bus1/cabuild/action/msdevshell@v1
with: with:

View File

@ -30,7 +30,10 @@ class NeutralEnv:
self.mesontest_command = [*self.meson_command, "test"] self.mesontest_command = [*self.meson_command, "test"]
self.patch_command = self._detect_command("patch") self.patch_command = self._detect_command("patch")
self.git_command = self._detect_command("git") self.git_command = self._detect_command("git")
self.make_command = self._detect_command("make") if platform.system() == "Windows":
self.make_command = self._detect_command("nmake", options=["/?", "/NOLOGO"])
else:
self.make_command = self._detect_command("make")
self.cmake_command = self._detect_command("cmake") self.cmake_command = self._detect_command("cmake")
self.qmake_command = self._detect_command( self.qmake_command = self._detect_command(
"qmake", required=False, default=[["qmake"], ["qmake-qt5"]] "qmake", required=False, default=[["qmake"], ["qmake-qt5"]]

View File

@ -13,32 +13,50 @@ class AllBaseDependencies(Dependency):
class Builder(NoopBuilder): class Builder(NoopBuilder):
@classmethod @classmethod
def get_dependencies(cls, configInfo, allDeps): def get_dependencies(cls, configInfo, allDeps):
if neutralEnv("distname") == "Windows":
return ["zlib", "zstd", "icu4c", "zim-testing-suite", "xapian-core"]
if configInfo.build == "wasm" or environ.get("OS_NAME") == "manylinux": if configInfo.build == "wasm" or environ.get("OS_NAME") == "manylinux":
return ["zlib", "lzma", "zstd", "icu4c", "xapian-core"] return ["zlib", "lzma", "zstd", "icu4c", "xapian-core"]
base_deps = [ if neutralEnv("distname") == "Windows":
"zlib", base_deps = [
"lzma", "zlib",
"zstd", "zstd",
"xapian-core", "xapian-core",
"pugixml", "zim-testing-suite",
"libcurl", "icu4c",
"icu4c", ]
"mustache",
"libmicrohttpd", if not configInfo.name.endswith("_dyn"):
"zim-testing-suite", base_deps += [
] "pugixml",
# Add specific dependencies depending of the config "libcurl",
if configInfo.build not in ("android", "iOS"): "mustache",
# For zimtools "libmicrohttpd",
base_deps += ["docoptcpp"] ]
if configInfo.build != "win32": else:
# zimwriterfs base_deps = [
base_deps += ["libmagic", "gumbo"] "zlib",
if configInfo.build == "native" and neutralEnv("distname") != "Darwin": "lzma",
# We compile kiwix-desktop only on native and not on `Darwin` "zstd",
# So we need aria2 only there "xapian-core",
base_deps += ["aria2"] "pugixml",
"libcurl",
"icu4c",
"mustache",
"libmicrohttpd",
"zim-testing-suite",
]
# Add specific dependencies depending of the config
if configInfo.build not in ("android", "iOS"):
# For zimtools
base_deps += ["docoptcpp"]
if configInfo.build != "win32":
# zimwriterfs
base_deps += ["libmagic", "gumbo"]
if (
configInfo.build == "native"
and neutralEnv("distname") != "Darwin"
):
# We compile kiwix-desktop only on native and not on `Darwin`
# So we need aria2 only there
base_deps += ["aria2"]
return base_deps return base_deps

View File

@ -2,6 +2,7 @@ import subprocess
import os import os
import shutil import shutil
import time import time
import platform
from kiwixbuild.utils import ( from kiwixbuild.utils import (
pj, pj,
@ -379,7 +380,7 @@ class MakeBuilder(Builder):
configure_options = [] configure_options = []
dynamic_configure_options = ["--enable-shared", "--disable-static"] dynamic_configure_options = ["--enable-shared", "--disable-static"]
static_configure_options = ["--enable-static", "--disable-shared"] static_configure_options = ["--enable-static", "--disable-shared"]
make_options = [] make_options = ["-j4"]
install_options = [] install_options = []
configure_script = "configure" configure_script = "configure"
configure_env = { configure_env = {
@ -435,7 +436,6 @@ class MakeBuilder(Builder):
command = [ command = [
*self.buildEnv.make_wrapper, *self.buildEnv.make_wrapper,
*neutralEnv("make_command"), *neutralEnv("make_command"),
"-j4",
*self.make_targets, *self.make_targets,
*self.make_options, *self.make_options,
] ]
@ -492,6 +492,12 @@ class QMakeBuilder(MakeBuilder):
qmake_targets = [] qmake_targets = []
flatpak_buildsystem = "qmake" flatpak_buildsystem = "qmake"
@property
def make_options(self):
if platform.system() == "Windows":
return []
return super().make_options
@property @property
def env_options(self): def env_options(self):
if "QMAKE_CC" in os.environ: if "QMAKE_CC" in os.environ:

View File

@ -1,4 +1,6 @@
from kiwixbuild._global import option
from .base import Dependency, GitClone, QMakeBuilder from .base import Dependency, GitClone, QMakeBuilder
import platform
class KiwixDesktop(Dependency): class KiwixDesktop(Dependency):
@ -11,11 +13,24 @@ class KiwixDesktop(Dependency):
class Builder(QMakeBuilder): class Builder(QMakeBuilder):
dependencies = ["qt", "qtwebengine", "libkiwix", "aria2"] dependencies = ["qt", "qtwebengine", "libkiwix", "aria2"]
make_install_targets = ["install"]
configure_env = None configure_env = None
flatpack_build_options = {"env": {"QMAKEPATH": "/app/lib"}} flatpack_build_options = {"env": {"QMAKEPATH": "/app/lib"}}
@property
def make_targets(self):
if platform.system() == "Windows":
yield "release-all" if option("make_release") else "debug-all"
else:
yield from super().make_targets
@property
def make_install_targets(self):
if platform.system() == "Windows":
yield "release-install" if option("make_release") else "debug-install"
else:
yield "install"
@property @property
def configure_options(self): def configure_options(self):
if self.buildEnv.configInfo.name != "flatpak": if self.buildEnv.configInfo.name != "flatpak":

View File

@ -39,7 +39,7 @@ release_versions = {
# This is the "version" of the whole base_deps_versions dict. # This is the "version" of the whole base_deps_versions dict.
# Change this when you change base_deps_versions. # Change this when you change base_deps_versions.
base_deps_meta_version = "04" base_deps_meta_version = "05"
base_deps_versions = { base_deps_versions = {
"zlib": "1.2.12", "zlib": "1.2.12",

View File

@ -0,0 +1,63 @@
#!/usr/bin/env python3
import sys, subprocess, shutil, argparse
from pathlib import Path
parser = argparse.ArgumentParser()
parser.add_argument("install_dir")
parser.add_argument("out_dir")
parser.add_argument("--static_dir")
parser.add_argument("archive_path", help="The full path of the archive to create")
parser.add_argument("-s", "--sign", action="store_true")
args = parser.parse_args()
install_dir = Path(args.install_dir)
if args.static_dir:
static_dir = Path(args.static_dir)
else:
static_dir = install_dir
out_dir = Path(args.out_dir)
archive_path = Path(args.archive_path)
out_dir.mkdir(parents=True, exist_ok=True)
print(
f"""Packaging kiwix-desktop
- From {install_dir}
- Static dir is {static_dir}
- Working dir {out_dir}
- Archive path is {archive_path}
- Python version {sys.version}"""
)
shutil.copy2(install_dir / "bin" / "kiwix-desktop.exe", out_dir)
subprocess.run(["windeployqt", "--compiler-runtime", str(out_dir)], check=True)
shutil.copy2(static_dir / "bin" / "aria2c.exe", out_dir)
for dll in (static_dir / "bin").glob("*.dll"):
shutil.copy2(dll, out_dir)
# Copy ssl stuff
ssl_directory = Path("C:/") / "Program Files" / "OpenSSL"
shutil.copy2(ssl_directory / "libcrypto-1_1-x64.dll", out_dir)
shutil.copy2(ssl_directory / "libssl-1_1-x64.dll", out_dir)
# [TODO] Sign binary
if args.sign:
pass
print(
f"""Create archive
- {archive_path.with_suffix('')}
- From {out_dir.parent}
- With {out_dir.name}"""
)
shutil.make_archive(
archive_path.with_suffix(""), "zip", root_dir=out_dir.parent, base_dir=out_dir.name
)