diff --git a/.dockerignore b/.dockerignore index 3cbfcd20d3cf09b99a18fb2bbdd0aca8f5d7ccf8..e66200a3042564cb46798b1416b9594d78f53433 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,7 +1,9 @@ client-android client-gnome +client-ios client-macosx -client-windows +client-qt +client-uwp daemon lrc ring_* diff --git a/.gitignore b/.gitignore index d00229a382d70bb769196bd9f83fa0f947313f13..5e135de74b32810f5d5495e19f49772f4c31f3c2 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,6 @@ repositories manual-download .docker-image-* qemu-static + +# QtCreator +/build-* diff --git a/.gitmodules b/.gitmodules index fa9d2c5ca02b24cb104d3ddf266acb2845d56dfe..17349a6d9fccab2e24a318bebbf15be9e6700fce 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,6 @@ [submodule "client-gnome"] path = client-gnome url = https://review.jami.net/ring-client-gnome -[submodule "client-windows"] - path = client-windows - url = https://review.jami.net/ring-client-windows [submodule "daemon"] path = daemon url = https://review.jami.net/ring-daemon @@ -25,3 +22,6 @@ [submodule "client-electron"] path = client-electron url = https://review.jami.net/ring-client-electron +[submodule "client-qt"] + path = client-qt + url = https://review.jami.net/jami-client-qt diff --git a/client-qt b/client-qt new file mode 160000 index 0000000000000000000000000000000000000000..1f91576a0bf33c9d632595cf433d547d1f1d1e06 --- /dev/null +++ b/client-qt @@ -0,0 +1 @@ +Subproject commit 1f91576a0bf33c9d632595cf433d547d1f1d1e06 diff --git a/client-windows b/client-windows deleted file mode 160000 index 5fac25a5cbfd98a750b8c3e1ef67b36e52d312b3..0000000000000000000000000000000000000000 --- a/client-windows +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5fac25a5cbfd98a750b8c3e1ef67b36e52d312b3 diff --git a/make-ring.py b/make-ring.py index 14e1f1c6d43f45b1145b7050833cf9b1f5f0bce2..3d6629f821153ec67d332eeaae8648af4b089c6f 100755 --- a/make-ring.py +++ b/make-ring.py @@ -22,9 +22,13 @@ OSX_DISTRIBUTION_NAME = "osx" ANDROID_DISTRIBUTION_NAME = "android" WIN32_DISTRIBUTION_NAME = "win32" -# vs help +# Qt 5.15 is currently only available using the maintenance tool. +QT5_VERSION = "5.15" +DEFAULT_QT_5_15_PATH = "~/Qt/5.15.0/gcc_64" + +# vs vars win_sdk_default = '10.0.16299.0' -win_toolset_default = 'v141' +win_toolset_default = 'v142' APT_BASED_DISTROS = [ 'debian', @@ -110,7 +114,7 @@ DNF_DEPENDENCIES = [ 'gtk3-devel', 'clutter-devel', 'clutter-gtk-devel', 'libnotify-devel', 'libappindicator-gtk3-devel', 'patch', 'libva-devel', 'openssl-devel', 'webkitgtk4-devel', 'NetworkManager-libnm-devel', 'libvdpau-devel', 'msgpack-devel', 'libcanberra-devel', - 'sqlite-devel', 'openssl-static' + 'sqlite-devel', 'openssl-static', 'pandoc' ] APT_DEPENDENCIES = [ @@ -124,7 +128,8 @@ APT_DEPENDENCIES = [ 'libspeex-dev', 'libspeexdsp-dev', 'libswscale-dev', 'libtool', 'libudev-dev', 'libyaml-cpp-dev', 'qtbase5-dev', 'libqt5sql5-sqlite', 'sip-tester', 'swig', 'uuid-dev', 'yasm', 'libqrencode-dev', 'libjsoncpp-dev', 'libappindicator3-dev', - 'libva-dev', 'libwebkit2gtk-4.0-dev', 'libnm-dev', 'libvdpau-dev', 'libmsgpack-dev', 'libcanberra-gtk3-dev' + 'libva-dev', 'libwebkit2gtk-4.0-dev', 'libnm-dev', 'libvdpau-dev', 'libmsgpack-dev', 'libcanberra-gtk3-dev', + 'pandoc' ] PACMAN_DEPENDENCIES = [ @@ -182,8 +187,22 @@ def run_powersell_cmd(cmd): return +def write_qt_conf(path): + # Add a configuration that can be supplied to qmake + # e.g. `qmake -qt=5.15 [mode] [options] [files]` + if path is '': + return + with open('/usr/share/qtchooser/' + QT5_VERSION + '.conf', 'w+') as fd: + fd.write(path.rstrip('/') + '/bin\n') + fd.write(path.rstrip('/') + '/lib\n') + return + + def run_dependencies(args): - if(args.distribution == WIN32_DISTRIBUTION_NAME): + if args.qt is not None: + write_qt_conf(args.qt) + + if args.distribution == WIN32_DISTRIBUTION_NAME: run_powersell_cmd( 'Set-ExecutionPolicy Unrestricted; .\\scripts\\build-package-windows.ps1') @@ -258,7 +277,8 @@ def run_init(): module_names.append(line[line.find('"')+1:line.rfind('"')]) subprocess.run(["git", "submodule", "update", "--init"], check=True) - subprocess.run(["git", "submodule", "foreach", "git checkout master && git pull"], check=True) + subprocess.run(["git", "submodule", "foreach", + "git checkout master && git pull"], check=True) for name in module_names: copy_file("./scripts/commit-msg", ".git/modules/"+name+"/hooks") @@ -283,7 +303,8 @@ def run_install(args): return subprocess.run(["./compile.sh"], cwd="./client-android", check=True) elif args.distribution == WIN32_DISTRIBUTION_NAME: return subprocess.run([ - sys.executable, os.path.join(os.getcwd(), "scripts/build-windows.py"), + sys.executable, os.path.join( + os.getcwd(), "scripts/build-windows.py"), "--toolset", args.toolset, "--sdk", args.sdk, "--qtver", args.qtver @@ -311,13 +332,21 @@ def run_install(args): universal_newlines=True) environ['CMAKE_PREFIX_PATH'] = proc.stdout.rstrip("\n") - environ['CONFIGURE_FLAGS'] = '--without-dbus' + environ['CONFIGURE_FLAGS'] = '--without-dbus' install_args += ("-c", "client-macosx") else: if args.distribution in ZYPPER_BASED_DISTROS: # fix jsoncpp pkg-config bug, remove when jsoncpp package bumped environ['JSONCPP_LIBS'] = "-ljsoncpp" - install_args += ("-c", "client-gnome") + if args.qt is None: + install_args += ("-c", "client-gnome") + else: + install_args += ("-c", "client-qt") + install_args += ("-q", QT5_VERSION) + if args.qt is '': + install_args += ("-Q", DEFAULT_QT_5_15_PATH) + else: + install_args += ("-Q", args.qt) return subprocess.run(["./scripts/install.sh"] + install_args, env=environ, check=True) @@ -352,11 +381,17 @@ def run_run(args): with open('daemon.pid', 'w') as f: f.write(str(dring_process.pid)+'\n') - client_log = open("jami-gnome.log", 'a') + client_suffix = "" + if args.qt is not None: + client_suffix += "qt" + else: + client_suffix += "gnome" + client_log = open("jami-" + client_suffix + ".log", 'a') client_log.write('=== Starting client (%s) ===' % time.strftime("%d/%m/%Y %H:%M:%S")) client_process = subprocess.Popen( - ["./install/client-gnome/bin/jami-gnome", "-d"], + ["./install/client-" + client_suffix + + "/bin/jami-" + client_suffix, "-d"], stdout=client_log, stderr=client_log, env=run_env @@ -416,7 +451,7 @@ def execute_script(script, settings=None, fail=True): def validate_args(parsed_args): """Validate the args values, exit if error is found""" - # Check arg values + # Filter unsupported distributions. supported_distros = [ ANDROID_DISTRIBUTION_NAME, OSX_DISTRIBUTION_NAME, IOS_DISTRIBUTION_NAME, WIN32_DISTRIBUTION_NAME @@ -429,6 +464,24 @@ def validate_args(parsed_args): ), file=sys.stderr) sys.exit(1) + # The Qt client support will be added incrementally. + if parsed_args.qt is not None: + supported_qt_distros = [ + WIN32_DISTRIBUTION_NAME, APT_BASED_DISTROS, DNF_BASED_DISTROS + ] + if parsed_args.distribution not in supported_distros: + print('Distribution \'{0}\' not supported when building the Qt client.' + '\nChoose one of: {1}'.format( + parsed_args.distribution, ', '.join(supported_qt_distros) + ), file=sys.stderr) + sys.exit(1) + + # The windows client can only be built on a Windows 10 host. + if parsed_args.distribution == WIN32_DISTRIBUTION_NAME: + if platform.release() != '10': + print('Windows version must be built on Windows 10') + sys.exit(1) + def parse_args(): ap = argparse.ArgumentParser(description="Ring build tool") @@ -459,24 +512,26 @@ def parse_args(): ap.add_argument('--global-install', default=False, action='store_true') ap.add_argument('--debug', default=False, action='store_true') ap.add_argument('--background', default=False, action='store_true') - ap.add_argument('--no-priv-install', dest='priv_install', default=True, action='store_false') - - if choose_distribution() == WIN32_DISTRIBUTION_NAME: - ap.add_argument('--toolset', default=win_toolset_default, type=str, help='Windows use only, specify Visual Studio toolset version') - ap.add_argument('--sdk', default=win_sdk_default, type=str, help='Windows use only, specify Windows SDK version') - ap.add_argument('--qtver', default='5.9.4', help='Sets the Qt version to build with') + ap.add_argument('--no-priv-install', dest='priv_install', + default=True, action='store_false') + ap.add_argument('--qt', nargs='?', const='', type=str, + help='Build the Qt client with the Qt 5.15 path supplied') + + dist = choose_distribution() + if dist == WIN32_DISTRIBUTION_NAME: + ap.add_argument('--toolset', default=win_toolset_default, type=str, + help='Windows use only, specify Visual Studio toolset version') + ap.add_argument('--sdk', default=win_sdk_default, type=str, + help='Windows use only, specify Windows SDK version') + ap.add_argument('--qtver', default='5.15.0', + help='Sets the Qt version to build with') parsed_args = ap.parse_args() if (parsed_args.distribution is not None): parsed_args.distribution = parsed_args.distribution.lower() else: - parsed_args.distribution = choose_distribution() - - if parsed_args.distribution == WIN32_DISTRIBUTION_NAME: - if platform.release() != '10': - print('Windows version must be built on Windows 10') - sys.exit(1) + parsed_args.distribution = dist validate_args(parsed_args) diff --git a/packaging/rules/debian-one-click-install/copyright b/packaging/rules/debian-one-click-install/copyright index d1f27599c012280c06dca121df2daf3f21da65b6..73da38fc6d7fd99caf7a84c6f7658d9d9b2f79f0 100644 --- a/packaging/rules/debian-one-click-install/copyright +++ b/packaging/rules/debian-one-click-install/copyright @@ -4,7 +4,7 @@ Upstream-Contact: Alexandre Viau <alexandre.viau@savoirfairelinux.net> Source: https://dl.jami.net/release/tarballs/ Files-Excluded: client-electron/* client-uwp/* - client-windows/* + client-qt/* client-android/* client-macosx/* client-ios/* diff --git a/packaging/rules/debian/copyright b/packaging/rules/debian/copyright index d1f27599c012280c06dca121df2daf3f21da65b6..73da38fc6d7fd99caf7a84c6f7658d9d9b2f79f0 100644 --- a/packaging/rules/debian/copyright +++ b/packaging/rules/debian/copyright @@ -4,7 +4,7 @@ Upstream-Contact: Alexandre Viau <alexandre.viau@savoirfairelinux.net> Source: https://dl.jami.net/release/tarballs/ Files-Excluded: client-electron/* client-uwp/* - client-windows/* + client-qt/* client-android/* client-macosx/* client-ios/* diff --git a/scripts/build-windows.py b/scripts/build-windows.py index 1980f6fb5b47a8acf0591eb798edd7eb00a1fc36..1eb2265472198d2aca208c4f365a2fdcdf0aba95 100644 --- a/scripts/build-windows.py +++ b/scripts/build-windows.py @@ -15,7 +15,8 @@ def execute_cmd(cmd, with_shell=False): def build_daemon(parsed_args): make_cmd = os.path.dirname(this_dir) + '\\daemon\\compat\\msvc\\winmake.py' os.chdir(os.path.dirname(this_dir) + '\\daemon\\compat\\msvc') - status_code = execute_cmd('python ' + make_cmd + ' -iv -t ' + parsed_args.toolset + ' -s ' + parsed_args.sdk + ' -b daemon') + status_code = execute_cmd('python ' + make_cmd + ' -iv -t ' + + parsed_args.toolset + ' -s ' + parsed_args.sdk + ' -b daemon') os.chdir(os.path.dirname(this_dir)) return status_code @@ -26,17 +27,20 @@ def build_lrc(parsed_args): def build_client(parsed_args): - os.chdir('./client-windows') + os.chdir('./client-qt') ret = 0 - ret &= not execute_cmd('pandoc -f markdown -t html5 -o changelog.html changelog.md', True) + ret &= not execute_cmd( + 'pandoc -f markdown -t html5 -o changelog.html changelog.md', True) ret &= not execute_cmd('python make-client.py -d') - ret &= not execute_cmd('python make-client.py -b ' + '-t ' + parsed_args.toolset + ' -s ' + parsed_args.sdk + ' -q ' + parsed_args.qtver) + ret &= not execute_cmd('python make-client.py -b ' + '-t ' + + parsed_args.toolset + ' -s ' + parsed_args.sdk + ' -q ' + parsed_args.qtver) if not os.path.exists('./x64/Release/qt.conf'): ret &= not execute_cmd( 'powershell -ExecutionPolicy Unrestricted -File copy-runtime-files.ps1' + ' "Release" ' + '"' + parsed_args.qtver + '"', True) return ret + def parse_args(): ap = argparse.ArgumentParser(description="Qt Client build tool") @@ -44,14 +48,14 @@ def parse_args(): help='Windows use only, specify Visual Studio toolset version') ap.add_argument('--sdk', default='', type=str, help='Windows use only, specify Windows SDK version') - ap.add_argument('--qtver', default='5.9.4', + ap.add_argument('--qtver', default='5.15.0', help='Sets the Qt version to build with') parsed_args = ap.parse_args() - return parsed_args + def main(): parsed_args = parse_args() diff --git a/scripts/install.sh b/scripts/install.sh index ba91024895e154f1d9b8dc303d538392c106f2de..5ddc324716e12eb84e84d50cc4178431739bc529 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -16,9 +16,11 @@ set -ex global=false static='' client='' +qt5ver='' +qt5path='' proc='1' priv_install=true -while getopts gsc:P:p:u OPT; do +while getopts gsc:q:Q:P:p:u OPT; do case "$OPT" in g) global='true' @@ -29,6 +31,12 @@ while getopts gsc:P:p:u OPT; do c) client="${OPTARG}" ;; + q) + qt5ver="${OPTARG}" + ;; + Q) + qt5path="${OPTARG}" + ;; P) prefix="${OPTARG}" ;; @@ -64,6 +72,7 @@ else BUILDDIR="build-local" fi +# dring cd "${TOP}/daemon" DAEMON="$(pwd)" cd contrib @@ -95,38 +104,59 @@ fi make -j"${proc}" make_install "${global}" "${priv_install}" +# libringclient cd "${TOP}/lrc" mkdir -p "${BUILDDIR}" cd "${BUILDDIR}" if [ "${global}" = "true" ]; then if [ "${prefix+set}" ]; then - cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX="${prefix}" $static + cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX="${prefix}" $static \ + -DQT_MIN_VER="${qt5ver}" \ + -DQT5_PATH="${qt5path}" else - cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" -DCMAKE_BUILD_TYPE=Debug $static + cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \ + -DCMAKE_BUILD_TYPE=Debug $static \ + -DQT_MIN_VER="${qt5ver}" \ + -DQT5_PATH="${qt5path}" fi else cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_INSTALL_PREFIX="${INSTALL}/lrc" \ - -DRING_BUILD_DIR="${DAEMON}/src" $static + -DRING_BUILD_DIR="${DAEMON}/src" $static \ + -DQT_MIN_VER="${qt5ver}" \ + -DQT5_PATH="${qt5path}" fi make -j"${proc}" make_install "${global}" "${priv_install}" +# client cd "${TOP}/${client}" mkdir -p "${BUILDDIR}" cd "${BUILDDIR}" -if [ "${global}" = "true" ]; then - if [ "${prefix+set}" ]; then - cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" -DCMAKE_INSTALL_PREFIX="${prefix}" $static - else - cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" $static - fi +if [ "${client}" = "client-qt" ]; then + echo building client-qt using Qt ${qt5ver} + pandoc -f markdown -t html5 -o ../changelog.html ../changelog.md + if ! command -v qmake &> /dev/null; then + eval ${qt5path}/bin/qmake PREFIX="${INSTALL}/${client}" .. + else + qmake -qt=${qt5ver} PREFIX="${INSTALL}/${client}" .. + fi else - cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \ - -DCMAKE_INSTALL_PREFIX="${INSTALL}/${client}" \ - -DRINGTONE_DIR="${INSTALL}/daemon/share/ring/ringtones" \ - -DLibRingClient_DIR="${INSTALL}/lrc/lib/cmake/LibRingClient" $static + if [ "${global}" = "true" ]; then + if [ "${prefix+set}" ]; then + cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" -DCMAKE_INSTALL_PREFIX="${prefix}" $static + else + cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" $static + fi + else + cmake .. -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \ + -DCMAKE_INSTALL_PREFIX="${INSTALL}/${client}" \ + -DRINGTONE_DIR="${INSTALL}/daemon/share/ring/ringtones" \ + -DLibRingClient_DIR="${INSTALL}/lrc/lib/cmake/LibRingClient" $static + fi fi make -j"${proc}" make_install "${global}" "${priv_install}" diff --git a/scripts/update-submodules.sh b/scripts/update-submodules.sh index 0c437623b045df0e3696bce69d4686a54f1a8c73..15befcc6cbcc7a384c5a19eed9128bff80fcc941 100755 --- a/scripts/update-submodules.sh +++ b/scripts/update-submodules.sh @@ -1,5 +1,12 @@ #!/usr/bin/env bash git submodule foreach "git pull origin master" -git add client-android client-gnome client-macosx client-windows daemon lrc +git add client-android \ + client-gnome \ + client-ios \ + client-macosx \ + client-qt \ + client-uwp \ + daemon \ + lrc git commit