Skip to content
Draft
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
241 changes: 241 additions & 0 deletions .build-aux/fetchcontent2flatpak.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import argparse
import json
import os
import re
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
from typing import Final

FETCHCONTENT_REGEX: Final[str] = (
r"^--\ Fetching\ (?P<name>.+)\ (?P<url>.+)\ (?P<commit>.+)\n?$"
)
SHA1_REGEX: Final[str] = r"^[0-9a-f]{40}$"


class FetchContent:
name: str
url: str
branch: str | None = None
commit: str | None = None
tag: str | None = None
custom_flag: str | None = None

def __init__(
self, name: str, url: str, rev: str, custom_flag: str | None = None
) -> None:
self.name = name
self.url = url

if custom_flag:
self.custom_flag = custom_flag

if not re.match(SHA1_REGEX, rev, re.IGNORECASE):
self.branch = rev

# Maybe not a good idea running processes on __init__?
result = subprocess.run(
["git", "ls-remote", url, rev], stdout=subprocess.PIPE, text=True
)
if result.returncode == 0:
output = result.stdout.rstrip().split()

if re.match(SHA1_REGEX, output[0], re.IGNORECASE):
self.commit = output[0]
if output[1].startswith("refs/tags/"):
self.tag = output[1].split("/")[2]
else:
self.commit = rev


def parse_stdout(command: list[str]) -> list[FetchContent]:
matches: list[FetchContent] = []

process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=sys.stderr,
text=True,
bufsize=1,
)

if process.stdout:
for line in process.stdout:
line = line.rstrip()
print(line)

try_match = re.match(FETCHCONTENT_REGEX, line)
if try_match:
name, url, rev = try_match.groups()
matches.append(FetchContent(name, url, rev))

process.stdout.close()

returncode = process.wait()
if returncode != 0:
raise subprocess.CalledProcessError(returncode, command)

return matches


def flatpak_configure(
build_dir: str, runtime: str, additional_args: list[str] = []
) -> list[FetchContent]:
flatpak = shutil.which("flatpak")
cwd = os.getcwd()

if not flatpak:
raise FileNotFoundError("flatpak")

command = [
flatpak,
"run",
"--devel",
"--share=network",
f"--filesystem={cwd}",
f"--filesystem={build_dir}",
"--command=cmake",
runtime,
"-B",
build_dir,
*additional_args,
]
return parse_stdout(command)


def local_configure(
build_dir: str, additional_args: list[str] = []
) -> list[FetchContent]:
cmake = shutil.which("cmake")

if not cmake:
raise FileNotFoundError("cmake")

command = [cmake, "-B", build_dir, *additional_args]
return parse_stdout(command)


def to_flatpak(sources: list[FetchContent]):
sources_array: list[dict[str, str]] = []
flags: list[str] = []

for source in sources:
obj = {
"type": "git",
"url": source.url,
"dest": f"_deps/{source.name.lower()}",
}

if source.commit:
obj.update({"commit": source.commit})
if source.tag:
obj.update({"tag": source.tag})
# elif source.branch:
# obj.update({"branch": source.branch})

sources_array.append(obj)

env = (
source.custom_flag
if source.custom_flag
else f"FETCHCONTENT_SOURCE_DIR_{source.name.upper()}"
)
# Assumes `builddir: true` on manifest
flags.append(f"-D{env}=../_deps/{source.name.lower()}")

sources_json = json.dumps(sources_array, indent=4)

return (sources_json, "\n".join(flags))


def to_nix(sources: list[FetchContent]):
lines: list[str] = []
flags: list[str] = []

flags.append("cmakeFlags = with finalAttrs; [")

for source in sources:
lines.append(f"{source.name.lower()}-src = fetchgit {{")
lines.append(f' url = "{source.url}";')
if source.tag:
lines.append(f' tag = "{source.tag}";')
elif source.commit:
lines.append(f' rev = "{source.commit}";')
lines.append(' hash = "TODO";') # I don't use nix, btw
lines.append("};\n")

env = (
source.custom_flag
if source.custom_flag
else f"FETCHCONTENT_SOURCE_DIR_{source.name.upper()}"
)
flags.append(f' (lib.cmakeFeature "{env}" "${{{source.name.lower()}-src}}")')

flags.append("];")

return ("\n".join(lines), "\n".join(flags))


def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--runtime", "-r")
parser.add_argument("--output", "-o")
parser.add_argument("--to-flatpak", "-f", action="store_true")
parser.add_argument("--to-nix", "-n", action="store_true")
parser.add_argument("--args", action="store_true")

opts, args = parser.parse_known_args()
args = args if opts.args else []

matches: list[FetchContent] = []

if opts.to_flatpak or opts.to_nix:
with tempfile.TemporaryDirectory() as build_dir:
try:
if opts.runtime:
matches.extend(flatpak_configure(build_dir, opts.runtime, args))
else:
matches.extend(local_configure(build_dir, args))
except FileNotFoundError as err:
print(f'File "{err}" was not found!')
return 1
except subprocess.CalledProcessError as err:
print(f'Subprocess "{" ".join(err.cmd)}" failed!')
return 1
else:
print("You need to specify either --to-flatpak or --to-nix")
return 1

matches.append(
FetchContent(
"cryptopp",
"https://github.com/weidai11/cryptopp",
"master",
"CRYPTOPP_SOURCES",
)
)

if opts.to_flatpak:
sources, flags = to_flatpak(matches)

print()
if opts.output:
path = Path(opts.output)
path.write_text(sources)
else:
print(sources)

print(flags)
elif opts.to_nix:
sources, flags = to_nix(matches)
print()
print(sources)
print(flags)

return 0


if __name__ == "__main__":
sys.exit(main())
87 changes: 87 additions & 0 deletions .build-aux/flatpak/fetchcontent-sources.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
[
{
"type": "git",
"url": "https://github.com/craftablescience/BufferStream",
"dest": "_deps/bufferstream",
"commit": "2a7c9e8b786fa50a3ae1961f1ee5bca6c4a5a6c5"
},
{
"type": "git",
"url": "https://github.com/craftablescience/compressonator",
"dest": "_deps/cmp_compressonator",
"commit": "f9c8c58fe753108c260b33ec32301805c33c08b7"
},
{
"type": "git",
"url": "https://github.com/abdes/cryptopp-cmake",
"dest": "_deps/cryptopp-cmake",
"commit": "866aceb8b13b6427a3c4541288ff412ad54f11ea"
},
{
"type": "git",
"url": "https://github.com/richgel999/miniz",
"dest": "_deps/miniz",
"commit": "4b9fcf1df525114484be49f3216169b061c07ac6"
},
{
"type": "git",
"url": "https://github.com/craftablescience/minizip-ng",
"dest": "_deps/minizip-ng",
"commit": "2f0041b6f7c2193a06d18ca47ccd81fc7070ee8f"
},
{
"type": "git",
"url": "https://github.com/zlib-ng/zlib-ng",
"dest": "_deps/zlib",
"commit": "12731092979c6d07f42da27da673a9f6c7b13586"
},
{
"type": "git",
"url": "https://sourceware.org/git/bzip2.git",
"dest": "_deps/bzip2",
"commit": "af79253677ad98d6dfe11ea315ee9947d86586d3"
},
{
"type": "git",
"url": "https://github.com/tukaani-project/xz",
"dest": "_deps/liblzma",
"commit": "ebb0e6789cefe3be71756881aa8f2009fda9938c"
},
{
"type": "git",
"url": "https://github.com/ip7z/7zip",
"dest": "_deps/ppmd",
"commit": "5e96a8279489832924056b1fa82f29d5837c9469",
"tag": "25.01"
},
{
"type": "git",
"url": "https://github.com/facebook/zstd",
"dest": "_deps/zstd",
"commit": "f8745da6ff1ad1e7bab384bd1f9d742439278e99"
},
{
"type": "git",
"url": "https://github.com/phoboslab/qoi",
"dest": "_deps/qoi",
"commit": "6fff9b70dd79b12f808b0acc5cb44fde9998725e"
},
{
"type": "git",
"url": "https://github.com/syoyo/tinyexr",
"dest": "_deps/tinyexr",
"commit": "3ffe5f9d5e673e6e8c378d59b306b2824993e705"
},
{
"type": "git",
"url": "https://github.com/webmproject/libwebp",
"dest": "_deps/webp",
"commit": "f342dfc1756785df8803d25478bf664c0de629de"
},
{
"type": "git",
"url": "https://github.com/weidai11/cryptopp",
"dest": "_deps/cryptopp",
"commit": "b5242667a24e3db8e4600e77b2e502ef204e5280"
}
]
58 changes: 58 additions & 0 deletions .build-aux/flatpak/science.craftable.MareTF.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/flatpak/flatpak-builder/refs/heads/main/data/flatpak-manifest.schema.json
id: science.craftable.MareTF
runtime: org.kde.Platform
runtime-version: "6.10"
sdk: org.kde.Sdk
command: maretf-wrapper
finish-args:
- --share=ipc
- --socket=wayland
- --socket=fallback-x11
- --device=dri
# Discord RPC support
- --filesystem=xdg-run/app/com.discordapp.Discord:create

modules:
- name: maretf
buildsystem: cmake-ninja
builddir: true
config-opts:
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
- -DMARETF_BUILD_THUMBNAILER=OFF
- -DMARETF_BUILD_INSTALLER=ON
- -DMARETF_USE_LTO=ON
- -DFLATPAK=ON

- -DFETCHCONTENT_SOURCE_DIR_BUFFERSTREAM=../_deps/bufferstream
- -DFETCHCONTENT_SOURCE_DIR_CMP_COMPRESSONATOR=../_deps/cmp_compressonator
- -DFETCHCONTENT_SOURCE_DIR_CRYPTOPP-CMAKE=../_deps/cryptopp-cmake
- -DFETCHCONTENT_SOURCE_DIR_MINIZ=../_deps/miniz
- -DFETCHCONTENT_SOURCE_DIR_MINIZIP-NG=../_deps/minizip-ng
- -DFETCHCONTENT_SOURCE_DIR_ZLIB=../_deps/zlib
- -DFETCHCONTENT_SOURCE_DIR_BZIP2=../_deps/bzip2
- -DFETCHCONTENT_SOURCE_DIR_LIBLZMA=../_deps/liblzma
- -DFETCHCONTENT_SOURCE_DIR_PPMD=../_deps/ppmd
- -DFETCHCONTENT_SOURCE_DIR_ZSTD=../_deps/zstd
- -DFETCHCONTENT_SOURCE_DIR_QOI=../_deps/qoi
- -DFETCHCONTENT_SOURCE_DIR_TINYEXR=../_deps/tinyexr
- -DFETCHCONTENT_SOURCE_DIR_WEBP=../_deps/webp
- -DCRYPTOPP_SOURCES=../_deps/cryptopp
sources:
- fetchcontent-sources.json
- type: dir
path: ../../

- name: wrapper
buildsystem: simple
build-commands:
- install -Dm0755 maretf-wrapper "${FLATPAK_DEST}/bin"
sources:
- type: inline
dest-filename: maretf-wrapper
contents: |
#!/usr/bin/env bash
for i in {0..9}; do
test -S $XDG_RUNTIME_DIR/discord-ipc-$i || ln -sf {app/com.discordapp.Discord,$XDG_RUNTIME_DIR}/discord-ipc-$i;
done

exec maretf_gui "$@"
Loading
Loading