Skip to content

Check availabilty of all depedencies when building if necessary #1946

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
281 changes: 278 additions & 3 deletions build.nims
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
# Libraries
#=======================================

import std/json, os
import strformat, strutils
import std/[json, os, sequtils, strformat, strutils, tables]

import ".config/utils/ui.nims"
import ".config/utils/cli.nims"
Expand All @@ -41,6 +40,28 @@ include ".config/who.nims"
# Constants
#=======================================

type
PkgMan = enum
apk
apt
brew
bsd
chimera
dnf
emerge
eopkg
guix
mandriva
nix
pacman
pkg_add
pkgin
slackware
swupd
upgradepkg
xbps
zypper

let
targetDir = getHomeDir()/".arturo"

Expand All @@ -51,6 +72,199 @@ let
mainFile: "src"/"arturo.nim",
)

# BSDs not supported yet
when defined(linux):
const
dependencies = [
"gtk+-3.0",
"webkit2gtk-4.1",
"gmp",
"mpfr",
]
elif defined(macosx):
const
dependencies = [
"mpfr",
]
elif defined(windows):
const
dependencies = []
else:
const
dependencies = []

when defined(linux):
const
distros = {
"alpine" : apk,
"altlinux" : apt,
"arch" : pacman,
"archlinux" : pacman,
"arkane" : pacman,
"artix" : pacman,
"aurora" : brew,
"blackarch" : pacman,
"blendos" : pacman,
"bluefin" : brew,
"centos" : dnf,
"chimera" : chimera,
"clear-linux-os": swupd,
"debian" : apt,
"deepin" : apt,
"fedora" : dnf,
"garuda" : pacman,
"gentoo" : emerge,
"gnoppix" : pacman,
"guix" : guix,
"kaos" : pacman,
"manjaro" : pacman,
"nixos" : nix,
"nobara" : dnf,
"openmandriva" : mandriva,
"opensuse" : zypper,
"pureos" : apt,
"rhel" : dnf,
"slackware" : upgradepkg,
"solus" : eopkg,
"suse" : zypper,
"ubuntu" : apt,
"void" : xbps,
}.toTable
elif defined(bsd):
const
distros = {
"dragonfly" : bsd,
"freebsd" : bsd,
"ghostbsd" : bsd,
"netbsd" : pkgin,
"openbsd" : pkg_add,
}.toTable
elif defined(macosx):
const
distros = {
"macos" : brew,
}.toTable
else:
const
distros = Table[string, PkgMan]()
const
buildsWithDependencies = [
"@full",
"@docgen",
]

dependenciesNames = {
apk: { "gtk+-3.0" : "gtk+3.0-dev",
"webkit2gtk-4.1": "webkit2gtk-4.1-dev",
"gmp" : "gmp-dev",
"mpfr" : "mpfr-dev",
}.toTable,
chimera: { "gtk+-3.0" : "gtk+3-devel",
"webkit2gtk-4.1": "webkitgtk-devel",
"gmp" : "gmp-devel",
"mpfr" : "mpfr-devel",
}.toTable,
apt: { "gtk+-3.0" : "libgtk-3-dev",
"webkit2gtk-4.1": "libwebkit2gtk4.1-devel",
"gmp" : "libgmp-devel",
"mpfr" : "libmpfr-devel",
}.toTable,
brew: { "gtk+-3.0" : "gtk+3",
"webkit2gtk-4.1": "webkitgtk",
"gmp" : "gmp",
"mpfr" : "mpfr",
}.toTable,
dnf: { "gtk+-3.0" : "gtk3-devel",
"webkit2gtk-4.1": "webkit2gtk4.1-devel",
"gmp" : "gmp-devel",
"mpfr" : "mpfr-devel",
}.toTable,
emerge: { "gtk+-3.0" : "gtk+",
"webkit2gtk-4.1": "webkit-gtk",
"gmp" : "gmp",
"mpfr" : "mpfr",
}.toTable,
eopkg: { "gtk+-3.0" : "libgtk-3-devel",
"webkit2gtk-4.1": "libwebkit-gtk41-devel",
"gmp" : "gmp",
"mpfr" : "mpfr",
}.toTable,
guix: { "gtk+-3.0" : "gtk+@3",
"webkit2gtk-4.1": "webkitgtk",
"gmp" : "gmp",
"mpfr" : "mpfr",
}.toTable,
mandriva: { "gtk+-3.0" : "lib64gtk+3.0-devel",
"webkit2gtk-4.1": "lib64webkit4.1-devel",
"gmp" : "lib64gmp-devel",
"mpfr" : "lib64mpfr-devel",
}.toTable,
nix: { "gtk+-3.0" : "gtk3",
"webkit2gtk-4.1": "webkitgtk_4_1",
"gmp" : "gmp",
"mpfr" : "mpfr",
}.toTable,
pacman: { "gtk+-3.0" : "gtk3",
"webkit2gtk-4.1": "webkit2gtk-4.1",
"gmp" : "gmp",
"mpfr" : "mpfr",
}.toTable,
slackware: { "gtk+-3.0" : "gtk+3[current version here].txz",
"webkit2gtk-4.1": "webkit2gtk4.1[current version here].txz",
"gmp" : "gmp[current version here].txz",
"mpfr" : "mpfr[current version here].txz",
}.toTable,
swupd: { "gtk+-3.0" : "devpkg-gtk3",
"webkit2gtk-4.1": "devpkg-webkitgtk",
"gmp" : "devpkg-gmp",
"mpfr" : "devpkg-mpfr",
}.toTable,
xbps: { "gtk+-3.0" : "gtk+3-devel",
"webkit2gtk-4.1": "webkit2gtk-devel",
"gmp" : "gmp-devel",
"mpfr" : "mpfr-devel",
}.toTable,
zypper: { "gtk+-3.0" : "gtk+3-devel",
"webkit2gtk-4.1": "webkit2gtk-devel",
"gmp" : "gmp-devel",
"mpfr" : "mpfr-devel",
}.toTable,
}.toTable

# String templates for complex installation commands
nixInstallCmd =
"""
Update configuration.nix to include:
$1

and for building applications targeting Arturo use:
nix-shell -p <THE LIST ABOVE, HERE>
or edit shell.nix accordingly.
"""

installCmds = {
apk : "apk add $1",
apt : "apt-get install $1",
brew : "brew install $1",
bsd : "pkg install $1",
chimera : "apk add $1",
dnf : "dnf install $1",
emerge : "emerge install $1",
eopkg : "eopkg install $1",
guix : "guix install $1",
mandriva : "dnf install $1",
nix : nixInstallCmd,
pacman : "pacman -S $1",
pkg_add : "pkg_add $1",
pkgin : "pkgin install $1",
swupd : "swupd bundle-add $1",
upgradepkg: "upgradepkg --install-new $1",
xbps : "xbps-install $1",
zypper : "zypper install $1",
}.toTable

#TODO OTHER = @["redox", "tinycore"] these are niche but very interesting

#=======================================
# Types
#=======================================
Expand Down Expand Up @@ -234,6 +448,63 @@ proc installAll*(config: BuildConfig, targetFile: string) =

main(config)

proc getDistro(): string =
if defined(linux):
var id = gorge("grep ^ID= /etc/os-release").toLower()
if id.len == 0: return "unknown"
var idLike = gorge("grep ^ID_LIKE= /etc/os-release")
var idLikes: seq[string]
if idLike.len > 0:
idLikes = idLike[8..^1].strip(chars = {'"'}).toLower().splitWhitespace()
for distro in distros.keys:
if distro in id or distro in idLikes:
return distro
return "unknown"

if defined(bsd):
var distro = gorge("uname -s").toLower()
if distro in distros:
return distro
else:
return "unknown"

if defined(macosx):
return "macos"

proc checkDependencies(logging: bool) =
var fails: seq[string]
var os: string

when defined(windows): return
when defined(bsd) : return

log ""
for dep in dependencies:
if gorgeEx(fmt"pkg-config --exists {dep}").exitCode != 0:
fails.add(dep)

if fails.len > 0:
os = getDistro()
let failText = (if fails.len == 1: "this dependency" else: fmt"these {fails.len} dependencies")
warn fmt"Missing {failText}:"
for fail in fails:
log fail
if os == "nixos": continue
if os != "unknown":
var cmd = installCmds[distros[os]]
log "-> " & cmd % dependenciesNames[distros[os]][fail]
log ""

if os == "nixos":
log installCmds[nix] %
(fails.map do (fail: string) -> string:
dependenciesNames[distros[os]][fail]).join("\p")

panic "Install all packages listed above and try again", 1
else:
if logging:
log "Dependencies successfully checked"

proc showBuildInfo*(config: BuildConfig) =
let
params = flags.join(" ")
Expand All @@ -250,6 +521,9 @@ proc showBuildInfo*(config: BuildConfig) =
if not config.silentCompilation:
log fmt"flags: {params}"

if config.version in buildsWithDependencies:
checkDependencies(config.shouldLog)

#=======================================
# Methods
#=======================================
Expand Down Expand Up @@ -455,6 +729,7 @@ cmd build, "[default] Build arturo and optionally install the executable":
>> ["docgen"]:
fullBuildConfig()
docgenBuildConfig()
config.version = "@docgen"
>> ["safe"]:
safeBuildConfig()
miniBuild()
Expand Down Expand Up @@ -591,4 +866,4 @@ cmd benchmark, "Run benchmark suite":
unless paths.global.performBenchmarks():
quit paths.local.performBenchmarks().toErrorCode

helpForMissingCommand()
helpForMissingCommand()
Loading