Unverified Commit e55531c9 authored by Maxim Cournoyer's avatar Maxim Cournoyer Committed by Maxim Cournoyer

build.py: Add support for Guix.

This enables building Jami in a development setting on any GNU/Linux
distribution, provided Guix is installed.  It supports building both
the Qt and the GNOME clients.  It uses ffmpeg and pjproject from the
contribs.

Change-Id: I1bf0c9f3f9c08361b9016fe04581902ec27f2312
parent f47e94cb
......@@ -305,6 +305,12 @@ def run_dependencies(args):
elif args.distribution == WIN32_DISTRIBUTION_NAME:
print("The win32 version does not install dependencies with this script.\nPlease continue with the --install instruction.")
sys.exit(1)
elif args.distribution == 'guix':
print("Building the environment defined in 'guix/manifest.scm'...")
execute_script(['mkdir -p ~/.config/guix/profiles',
('guix time-machine --channels=guix/channels.scm -- '
'package --manifest=guix/manifest.scm '
'--profile=$HOME/.config/guix/profiles/jami')])
else:
print("Not yet implemented for current distribution (%s). Please continue with the --install instruction. Note: You may need to install some dependencies manually." %
......@@ -398,8 +404,28 @@ def run_install(args):
install_args += ("-q", args.qtver)
install_args += ("-Q", args.qt)
print(f'info: Invoking scripts/install.sh with arguments: {install_args}')
return subprocess.run(["./scripts/install.sh"] + install_args, env=environ, check=True)
command = ['bash', 'scripts/install.sh'] + install_args
if args.distribution == 'guix':
if args.global_install:
print('error: global install is not supported when using Guix.')
sys.exit(1)
# Run the build in an isolated container.
share_tarballs_args = []
if 'TARBALLS' in os.environ:
share_tarballs_args = ['--preserve=TARBALLS',
f'--share={os.environ["TARBALLS"]}']
# Note: we must expose /gnu/store because /etc/ssl/certs
# contains certs that are symlinks to store items.
command = ['guix', 'time-machine', '-C', 'guix/channels.scm', '--',
'environment', '--manifest=guix/manifest.scm',
'--expose=/gnu/store', '--expose=/etc/ssl/certs',
'--expose=/usr/bin/env',
'--container', '--network'] + share_tarballs_args \
+ ['--'] + command
print(f'info: Building/installing using the command: {" ".join(command)}')
return subprocess.run(command, env=environ, check=True)
def run_uninstall(args):
......@@ -525,13 +551,25 @@ def execute_script(script, settings=None, fail=True):
sys.exit(1)
def has_guix():
"""Check whether the 'guix' command is available."""
with open(os.devnull, 'w') as f:
try:
subprocess.run(["sh", "-c", "command -v guix"],
check=True, stdout=f)
except subprocess.CalledProcessError:
return False
else:
return True
def validate_args(parsed_args):
"""Validate the args values, exit if error is found"""
# Filter unsupported distributions.
supported_distros = [
ANDROID_DISTRIBUTION_NAME, OSX_DISTRIBUTION_NAME, IOS_DISTRIBUTION_NAME,
WIN32_DISTRIBUTION_NAME
WIN32_DISTRIBUTION_NAME, 'guix'
] + APT_BASED_DISTROS + DNF_BASED_DISTROS + PACMAN_BASED_DISTROS \
+ ZYPPER_BASED_DISTROS + FLATPAK_BASED_RUNTIMES
......@@ -551,6 +589,7 @@ def validate_args(parsed_args):
# The Qt client support will be added incrementally.
if parsed_args.qt is not None:
supported_qt_distros = [
'guix',
WIN32_DISTRIBUTION_NAME
] + APT_BASED_DISTROS + DNF_BASED_DISTROS + PACMAN_BASED_DISTROS
......@@ -619,7 +658,7 @@ def parse_args():
parsed_args = ap.parse_args()
if (parsed_args.distribution is not None):
if parsed_args.distribution:
parsed_args.distribution = parsed_args.distribution.lower()
else:
parsed_args.distribution = dist
......@@ -642,6 +681,8 @@ def choose_distribution():
if k.strip() == 'ID':
return v.strip().replace('"', '').split(' ')[0]
except FileNotFoundError:
if has_guix():
return 'guix'
return 'Unknown'
elif system == "darwin":
return OSX_DISTRIBUTION_NAME
......@@ -669,7 +710,23 @@ def main():
run_uninstall(parsed_args)
elif parsed_args.run:
run_run(parsed_args)
if (parsed_args.distribution == 'guix'
and 'GUIX_ENVIRONMENT' not in os.environ):
if parsed_args.qt is not None:
print('FIXME: Qt fails loading QML modules due to '
'https://issues.guix.gnu.org/47655')
# Relaunch this script, this time in a pure Guix environment.
guix_args = ['time-machine', '--channels=guix/channels.scm',
'--', 'environment', '--pure',
# to allow pulseaudio to connect to an existing server
"-E", "XAUTHORITY", "-E", "XDG_RUNTIME_DIR",
'--manifest=guix/manifest.scm', '--']
args = sys.argv + ['--distribution=guix']
print('Running in a guix environment spawned with: guix {}'
.format(str.join(' ', guix_args + args)))
os.execlp('guix', 'guix', *(guix_args + args))
else:
run_run(parsed_args)
elif parsed_args.stop:
run_stop(parsed_args)
......
(list (channel
(inherit %default-guix-channel)
;; Use the staging branch for now, as it includes more debug
;; symbols and fixes a propagation conflict between
;; gdk-pixbuf+svg and gdk-pixbuf.
(branch "staging")
(commit
"42231bc15df441d6426dec57283aca9ae7a03fcf")))
;;; To use with the GNU Guix package manager.
;;; Available at https://guix.gnu.org/.
;;;
;;; Commentary:
;;;
;;; A full-blown development environment that can be used to build the
;;; whole project. It includes both the GNOME as well as the Qt
;;; libraries, so that both clients can be built. The sensitive
;;; (i.e., patched) dependencies are consciously omitted from this
;;; list so that the bundled libraries are the ones used, which is
;;; usually what is desired for development purposes.
;;; The make-jami.py script makes use of it to build Jami in a Linux
;;; container with the dependencies below when Guix is detected (and
;;; no /etc/os-release file exists) or when explicitly specified,
;;; e.g.:
;;;
;;; $ ./make-jami.py --distribution=guix --install
;;;
;;; It can also be invoked directly to spawn a development environment, like so:
;;;
;;; $ guix environment --pure --manifest=guix/manifest.scm
(specifications->manifest
(list
;; Minimal requirements of the daemon contrib build system.
"coreutils"
"gcc-toolchain"
"git-minimal"
"grep"
"gzip"
"make"
"nss-certs"
"pkg-config"
"python"
"sed"
"tar"
"wget"
"xz"
;; For the daemon and its contribs.
"alsa-lib"
"autoconf"
"automake"
"bash"
"bzip2"
"cmake"
"dbus"
;; Bundled because broken with GCC 7 upstream (unmaintained). When
;; attempting to use it, it would cause confusing errors such as
;; "ld: ../src/.libs/libring.a(libupnpcontrol_la-upnp_context.o): in
;; function `jami::upnp::UPnPContext::updateMappingList(bool)':
;; upnp_context.cpp:(.text+0xa4be): undefined reference to
;; `std::__cxx11::basic_ostringstream<char, std::char_traits<char>,
;; std::allocator<char> >::basic_ostringstream()'
;;"dbus-c++" ;for dbusxx-xml2cpp
"diffutils"
"doxygen"
"eudev" ;udev library
"expat"
"findutils"
"gawk"
"gettext"
"gnutls"
;;"ffmpeg" ;bundled because patched
"gmp"
"gsm"
"gtk-doc"
"http-parser"
"jsoncpp"
"libarchive"
"libnatpmp"
"libupnp"
"libsecp256k1"
"libtool"
"libva" ;vaapi
"libvdpau"
"libx264"
"nasm"
"nettle"
"openssl"
"opus"
"patch"
"pcre"
"perl"
;;"pjproject" ;bundled because patched
"pulseaudio"
"speex"
"speexdsp"
"which"
"yaml-cpp"
"yasm"
;; For libringclient (LRC) and the Qt client.
"qtbase"
"qtbase:debug"
;; Shared by the GNOME and Qt clients.
"qrencode"
;; Shared by the LRC, GNOME and Qt clients.
"network-manager" ;libnm
;; For the GNOME client (client-gnome)
"adwaita-icon-theme"
"hicolor-icon-theme"
"clutter"
"clutter-gtk"
"glib:bin" ;for glib-compile-resources
"gtk+"
"gtk+:debug"
"libcanberra"
"libindicator"
"libnotify"
"sqlite"
"webkitgtk"
;; For the Qt client.
"qtsvg"
"qtsvg:debug"
"qttools"
"qtwebengine"
"qtwebengine:debug"
"qtwebchannel"
"qtwebchannel:debug"
"qtmultimedia"
"qtmultimedia:debug"
"qtdeclarative"
"qtdeclarative:debug"
"qtgraphicaleffects"
"qtgraphicaleffects:debug"
"qtquickcontrols"
"qtquickcontrols:debug"
"qtquickcontrols2"
"qtquickcontrols2:debug"
;; For tests and debugging.
"cppunit"
"file"
"gdb"
"ltrace"
"strace"))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment