mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-07-23 00:45:29 +02:00
build: Import build.py and associated scripts from jami-project.
Bring over the build.py script and its associated scripts from the scripts subdirectory of the jami-project.git as of commit 14a328b88007bff5ea21650fb00f6d4ead14cf02, with small changes to simplify and drop unneeded parts and adapt to their new locations. Change-Id: I500702854e45392a931ff7505e191b966015cd16
This commit is contained in:
parent
adcdcc8c1e
commit
355c0e63d5
7 changed files with 1445 additions and 39 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -19,12 +19,16 @@ changelog.html
|
|||
obj/
|
||||
build/
|
||||
build-local/
|
||||
install-local/
|
||||
build-global/
|
||||
install/
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*qmlcache.qrc
|
||||
.deploy.stamp
|
||||
|
||||
*.log
|
||||
*.pid
|
||||
|
||||
# auto-gen files
|
||||
src/app/resources.qrc
|
||||
src/app/qml.qrc
|
||||
|
|
75
INSTALL.md
75
INSTALL.md
|
@ -1,8 +1,8 @@
|
|||
# Build instructions
|
||||
|
||||
There is basically two ways to build `client-qt`:
|
||||
There are essentially two ways to build `client-qt`:
|
||||
|
||||
- Use `build.py` script which will build all Jami (daemon/client lib/client-qt)
|
||||
- Use `build.py` script which will build all of Jami (daemon and client)
|
||||
- Build only this client.
|
||||
|
||||
## Disclaimer
|
||||
|
@ -55,14 +55,14 @@ Then, you can build the project
|
|||
|
||||
### With build.py
|
||||
|
||||
```bash
|
||||
git clone https://review.jami.net/jami-project
|
||||
```
|
||||
|
||||
Jami installer uses **python3 (minimum v3.6)**. If it's not installed, please install it:
|
||||
The build.py Jami installer uses **python3 (minimum v3.6)**. If it's not installed,
|
||||
please install it. Then run the following to initialize and update
|
||||
the submodules to set them at the top of their latest commit (ideal
|
||||
for getting the latest development versions; otherwise, you can use
|
||||
`git submodule update --init` then checkout specific commits for each
|
||||
submodule).
|
||||
|
||||
```bash
|
||||
cd jami-project/
|
||||
./build.py --init
|
||||
```
|
||||
|
||||
|
@ -71,21 +71,24 @@ Then you will need to install dependencies:
|
|||
- For GNU/Linux
|
||||
|
||||
```bash
|
||||
./build.py --dependencies --qt # needs sudo
|
||||
./build.py --dependencies # needs sudo
|
||||
```
|
||||
|
||||
Then, you can build daemon and the client with:
|
||||
Then, you can build daemon and the client using:
|
||||
|
||||
```bash
|
||||
./build.py --install --qt
|
||||
./build.py --install
|
||||
```
|
||||
|
||||
And you will have the daemon in `daemon/bin/jamid` and the client in `client-qt/build-local/jami`. You also can run it with
|
||||
If you use a Qt version that is not system-wide installed, you need to
|
||||
specify its path using the `--qt` flag, e.g.
|
||||
`./build.py --install --qt=/home/<username>/Qt/6.2.1/gcc_64`.
|
||||
|
||||
If you use a Qt version that is not wide-system installed you need to specify its path after the `--qt` flag, i. e., `./build.py --install --qt /home/<username>/Qt/6.2.1/gcc_64
|
||||
Now you will have the daemon in `daemon/bin/jamid` and the client in
|
||||
`build/bin/jami`. You can now run Jami using
|
||||
|
||||
```bash
|
||||
./build.py --run --qt
|
||||
./build.py --run
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
@ -122,7 +125,7 @@ cmake can take some options:
|
|||
e.g. (with Qt version from https://jami.net)
|
||||
|
||||
```
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=jami-project/install/client-qt -DCMAKE_PREFIX_PATH=/usr/lib/libqt-jami
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=../install -DCMAKE_PREFIX_PATH=/usr/lib/libqt-jami
|
||||
```
|
||||
|
||||
After the build has finished, you are finally ready to launch jami in your build directory.
|
||||
|
@ -208,9 +211,8 @@ Only 64-bit MSVC build can be compiled.
|
|||
|
||||
```bash
|
||||
python build.py --install
|
||||
cd client-qt
|
||||
python build.py init
|
||||
python build.py --qtver <your qt version>
|
||||
python extras\scripts\build-windows.py init
|
||||
python extras\scripts\build-windows.py --qtver <your qt version>
|
||||
```
|
||||
|
||||
- Then you should be able to use the Visual Studio Solution file in client-qt folder **(Configuration = Release, Platform = x64)**
|
||||
|
@ -221,15 +223,15 @@ Only 64-bit MSVC build can be compiled.
|
|||
|
||||
**Daemon**
|
||||
|
||||
- Make sure that dependencies is built by make-ring.py
|
||||
- On MSVC folder (jami-project\daemon\MSVC):
|
||||
- Make sure that dependencies is built by build.py
|
||||
- On MSVC folder (daemon\MSVC):
|
||||
|
||||
```sh
|
||||
cmake -DCMAKE_CONFIGURATION_TYPES="ReleaseLib_win32" -DCMAKE_VS_PLATFORM_NAME="x64" -G "Visual Studio 16 2019" -A x64 -T '$(DefaultPlatformToolset)' ..
|
||||
python winmake.py -b daemon
|
||||
```
|
||||
|
||||
- This will generate a `.lib` file in the path of ring-project\daemon\MSVC\x64\ReleaseLib_win32\bin
|
||||
- This will generate a `.lib` file in the path of daemon\MSVC\x64\ReleaseLib_win32\bin
|
||||
|
||||
> Note: each dependencies contrib for daemon can also be updated individually <br>
|
||||
> For example:
|
||||
|
@ -240,15 +242,14 @@ Only 64-bit MSVC build can be compiled.
|
|||
|
||||
**Jami**
|
||||
|
||||
- Make sure that daemon, is built first
|
||||
- Make sure that daemon is built first. Then,
|
||||
|
||||
```bash
|
||||
cd client-qt
|
||||
python build.py init
|
||||
python build.py
|
||||
python extras\scripts\build-windows.py init
|
||||
python extras\scripts\build-windows.py
|
||||
```
|
||||
|
||||
Note: if your qt version is different than 6.2.3, you need to use `python build.py --qtver <your qt version>`.
|
||||
Note: if your qt version is different than 6.2.3, you need to use `python extras\scripts\build-windows.py --qtver <your qt version>`.
|
||||
|
||||
## Building On MacOS
|
||||
|
||||
|
@ -272,33 +273,31 @@ Then, you can build the project
|
|||
**Build with build.py**
|
||||
|
||||
```bash
|
||||
git clone https://review.jami.net/jami-project
|
||||
cd jami-project
|
||||
./build.py --init
|
||||
./build.py --dependencies --qt
|
||||
./build.py --install --qt
|
||||
./build.py --dependencies
|
||||
./build.py --install
|
||||
```
|
||||
|
||||
If you use a Qt version that is installed in a different than standard location you need to specify its path
|
||||
|
||||
```bash
|
||||
./build.py --install --qt QT_ROOT_DIRECTORY=your_qt_directory
|
||||
QT_ROOT_DIRECTORY=your_qt_directory ./build.py --install
|
||||
```
|
||||
|
||||
Built client could be find in `client-qt/build-local/Jami`
|
||||
Built client could be find in `build/Jami`
|
||||
|
||||
## Packaging On Native Windows
|
||||
|
||||
- To be able to generate a msi package, first download and install [Wixtoolset](https://wixtoolset.org/releases/).
|
||||
- In Visual Studio, download WiX Toolset Visual Studio Extension.
|
||||
- Build client-qt project first, then the JamiInstaller project, msi package should be stored in jami-project\client-qt\JamiInstaller\bin\Release
|
||||
- Build client-qt project first, then the JamiInstaller project, msi package should be stored in JamiInstaller\bin\Release
|
||||
|
||||
## Testing for Client-qt on Windows
|
||||
|
||||
- We currently use [GoogleTest](https://github.com/google/googletest) and [Qt Quick Test](https://doc.qt.io/qt-5/qtquicktest-index.html#introduction) in our product. To build and run tests, you could use the following command.
|
||||
|
||||
```
|
||||
python build.py [runtests, pack]
|
||||
python extras\scripts\build-windows.py [runtests, pack]
|
||||
```
|
||||
|
||||
- Note that, for tests, the path of local storage files for jami will be changed based on following environment variables.
|
||||
|
@ -309,11 +308,11 @@ Built client could be find in `client-qt/build-local/Jami`
|
|||
%JAMI_CACHE_HOME% = %TEMP% + '\\jami_test\\.cache'
|
||||
```
|
||||
|
||||
- These environment variables will be temporarily set when using make-client.py to run tests.
|
||||
- These environment variables will be temporarily set when using build-windows.py to run tests.
|
||||
|
||||
## Debugging
|
||||
|
||||
Compile the client with `BUILD=Debug` and compile LibRingClient with
|
||||
`-DCMAKE_BUILD_TYPE=Debug`
|
||||
Compile the client with with `-DCMAKE_BUILD_TYPE=Debug`.
|
||||
|
||||
Then, if you want to enable logging when running `jami` launch it with `-d` or `--debug`
|
||||
Then, if you want to enable logging when running `jami`, launch it
|
||||
with `-d` or `--debug`.
|
||||
|
|
696
build.py
Executable file
696
build.py
Executable file
|
@ -0,0 +1,696 @@
|
|||
#!/usr/bin/env python3
|
||||
# build.py --- Convenience script for building and running Jami
|
||||
|
||||
# Copyright (C) 2016-2022 Savoir-faire Linux Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
import argparse
|
||||
import contextlib
|
||||
import multiprocessing
|
||||
import os
|
||||
import platform
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
OSX_DISTRIBUTION_NAME = "osx"
|
||||
WIN32_DISTRIBUTION_NAME = "win32"
|
||||
|
||||
# vs vars
|
||||
win_sdk_default = '10.0.16299.0'
|
||||
win_toolset_default = '142'
|
||||
|
||||
APT_BASED_DISTROS = [
|
||||
'debian',
|
||||
'linuxmint',
|
||||
'raspbian',
|
||||
'trisquel',
|
||||
'ubuntu',
|
||||
]
|
||||
|
||||
DNF_BASED_DISTROS = [
|
||||
'fedora', 'rhel',
|
||||
]
|
||||
|
||||
PACMAN_BASED_DISTROS = [
|
||||
'arch', 'parabola',
|
||||
]
|
||||
|
||||
ZYPPER_BASED_DISTROS = [
|
||||
'opensuse-leap',
|
||||
]
|
||||
|
||||
FLATPAK_BASED_RUNTIMES = [
|
||||
'org.gnome.Platform',
|
||||
]
|
||||
|
||||
APT_INSTALL_SCRIPT = [
|
||||
'apt-get update',
|
||||
'apt-get install %(packages)s'
|
||||
]
|
||||
|
||||
BREW_UNLINK_SCRIPT = [
|
||||
'brew unlink %(packages)s'
|
||||
]
|
||||
|
||||
BREW_INSTALL_SCRIPT = [
|
||||
'brew update',
|
||||
'brew install %(packages)s',
|
||||
'brew link --force --overwrite %(packages)s'
|
||||
]
|
||||
|
||||
RPM_INSTALL_SCRIPT = [
|
||||
'dnf update',
|
||||
'dnf install %(packages)s'
|
||||
]
|
||||
|
||||
PACMAN_INSTALL_SCRIPT = [
|
||||
'pacman -Sy',
|
||||
'pacman -S --asdeps --needed %(packages)s'
|
||||
]
|
||||
|
||||
ZYPPER_INSTALL_SCRIPT = [
|
||||
'zypper update',
|
||||
'zypper install %(packages)s'
|
||||
]
|
||||
|
||||
ZYPPER_DEPENDENCIES = [
|
||||
# build system
|
||||
'autoconf', 'autoconf-archive', 'automake', 'cmake', 'make', 'patch', 'gcc-c++',
|
||||
'libtool', 'which', 'pandoc','nasm', 'doxygen', 'graphviz',
|
||||
# contrib dependencies
|
||||
'curl', 'gzip', 'bzip2',
|
||||
# daemon
|
||||
'speexdsp-devel', 'speex-devel', 'libdbus-c++-devel', 'jsoncpp-devel', 'yaml-cpp-devel',
|
||||
'yasm', 'libuuid-devel', 'libnettle-devel', 'libopus-devel', 'libexpat-devel',
|
||||
'libgnutls-devel', 'msgpack-devel', 'libavcodec-devel', 'libavdevice-devel', 'pcre-devel',
|
||||
'alsa-devel', 'libpulse-devel', 'libudev-devel', 'libva-devel', 'libvdpau-devel',
|
||||
'libopenssl-devel', 'libavutil-devel',
|
||||
]
|
||||
|
||||
ZYPPER_CLIENT_DEPENDENCIES = [
|
||||
# lrc
|
||||
'qt6-core-devel', 'qt6-dbus-devel', 'qt6-linguist-devel',
|
||||
# client-qt
|
||||
'qt6-svg-devel', 'qt6-multimedia-devel', 'qt6-declarative-devel',
|
||||
'qt6-quickcontrols2-devel',
|
||||
'qrencode-devel', 'NetworkManager-devel'
|
||||
]
|
||||
|
||||
ZYPPER_QT_WEBENGINE = [
|
||||
'qt6-webenginecore-devel',
|
||||
'qt6-webenginequick-devel',
|
||||
'qt6-webenginewidgets-devel'
|
||||
]
|
||||
|
||||
DNF_DEPENDENCIES = [
|
||||
'autoconf', 'autoconf-archive', 'automake', 'cmake', 'make', 'speexdsp-devel', 'pulseaudio-libs-devel',
|
||||
'libtool', 'dbus-devel', 'expat-devel', 'pcre-devel', 'doxygen', 'graphviz',
|
||||
'yaml-cpp-devel', 'boost-devel', 'dbus-c++-devel', 'dbus-devel',
|
||||
'libXext-devel', 'libXfixes-devel', 'yasm',
|
||||
'speex-devel', 'chrpath', 'check', 'astyle', 'uuid-c++-devel', 'gettext-devel',
|
||||
'gcc-c++', 'which', 'alsa-lib-devel', 'systemd-devel', 'libuuid-devel',
|
||||
'uuid-devel', 'gnutls-devel', 'nettle-devel', 'opus-devel', 'speexdsp-devel',
|
||||
'yaml-cpp-devel', 'swig', 'jsoncpp-devel',
|
||||
'patch', 'libva-devel', 'openssl-devel', 'libvdpau-devel', 'msgpack-devel',
|
||||
'sqlite-devel', 'openssl-static', 'pandoc', 'nasm',
|
||||
'bzip2'
|
||||
]
|
||||
|
||||
DNF_CLIENT_DEPENDENCIES = [
|
||||
'libnotify-devel',
|
||||
'qt6-qtbase-devel',
|
||||
'qt6-qtsvg-devel', 'qt6-qtmultimedia-devel', 'qt6-qtdeclarative-devel',
|
||||
'qrencode-devel', 'NetworkManager-libnm-devel'
|
||||
]
|
||||
|
||||
DNF_QT_WEBENGINE = [ 'qt6-qtwebengine-devel' ]
|
||||
|
||||
APT_DEPENDENCIES = [
|
||||
'autoconf', 'autoconf-archive', 'autopoint', 'automake', 'cmake', 'make', 'dbus', 'doxygen', 'graphviz',
|
||||
'g++', 'gettext', 'libasound2-dev', 'libavcodec-dev',
|
||||
'libavdevice-dev', 'libavformat-dev', 'libboost-dev',
|
||||
'libcppunit-dev', 'libdbus-1-dev',
|
||||
'libdbus-c++-dev', 'libebook1.2-dev', 'libexpat1-dev', 'libgnutls28-dev',
|
||||
'libgtk-3-dev', 'libjack-dev',
|
||||
'libopus-dev', 'libpcre3-dev', 'libpulse-dev', 'libssl-dev',
|
||||
'libspeex-dev', 'libspeexdsp-dev', 'libswscale-dev', 'libtool',
|
||||
'libudev-dev', 'libyaml-cpp-dev', 'sip-tester', 'swig',
|
||||
'uuid-dev', 'yasm', 'libjsoncpp-dev', 'libva-dev', 'libvdpau-dev', 'libmsgpack-dev',
|
||||
'pandoc', 'nasm', 'dpkg-dev'
|
||||
]
|
||||
|
||||
APT_CLIENT_DEPENDENCIES = [
|
||||
'qt6-base-dev', 'qt6-tools-dev', 'qt6-tools-dev-tools',
|
||||
'qt6-l10n-tools', 'libnotify-dev', 'libqt6sql6-sqlite',
|
||||
'libqt6core5compat6-dev', 'libqt6networkauth6-dev',
|
||||
'qt6-multimedia-dev', 'libqt6svg6-dev', 'qt6-declarative-dev',
|
||||
'qml6-module-qt-labs-qmlmodels',
|
||||
'qml6-module-qt5compat-graphicaleffects',
|
||||
'qml6-module-qtqml-workerscript',
|
||||
'qml6-module-qtmultimedia',
|
||||
'qml6-module-qtquick', 'qml6-module-qtquick-controls',
|
||||
'qml6-module-qtquick-dialogs', 'qml6-module-qtquick-layouts',
|
||||
'qml6-module-qtquick-shapes', 'qml6-module-qtquick-window',
|
||||
'qml6-module-qtquick-templates', 'qml6-module-qt-labs-platform',
|
||||
'libqrencode-dev', 'libnm-dev'
|
||||
]
|
||||
|
||||
APT_QT_WEBENGINE = [
|
||||
'libqt6webengine6-data', 'libqt6webenginecore6-bin',
|
||||
'qt6-webengine-dev', 'qt6-webengine-dev-tools',
|
||||
'qml6-module-qtwebengine', 'qml6-module-qtwebchannel' ]
|
||||
|
||||
PACMAN_DEPENDENCIES = [
|
||||
'autoconf', 'autoconf-archive', 'gettext', 'cmake', 'dbus', 'doxygen', 'graphviz',
|
||||
'gcc', 'ffmpeg', 'boost', 'cppunit', 'libdbus', 'dbus-c++', 'libe-book', 'expat',
|
||||
'jack', 'opus', 'pcre', 'libpulse', 'speex', 'speexdsp', 'libtool', 'yaml-cpp',
|
||||
'swig', 'yasm', 'make', 'patch', 'pkg-config',
|
||||
'automake', 'libva', 'libvdpau', 'openssl', 'pandoc', 'nasm'
|
||||
]
|
||||
|
||||
PACMAN_CLIENT_DEPENDENCIES = [
|
||||
# lrc
|
||||
'qt6-base',
|
||||
# client-qt
|
||||
'qt6-declarative', 'qt6-5compat', 'qt6-multimedia',
|
||||
'qt6-networkauth', 'qt6-shadertools',
|
||||
'qt6-svg', 'qt6-tools',
|
||||
'qrencode', 'libnm'
|
||||
]
|
||||
|
||||
PACMAN_QT_WEBENGINE = [ 'qt6-webengine' ]
|
||||
|
||||
OSX_DEPENDENCIES = [
|
||||
'autoconf', 'cmake', 'gettext', 'pkg-config', 'qt6',
|
||||
'libtool', 'yasm', 'nasm', 'automake'
|
||||
]
|
||||
|
||||
OSX_DEPENDENCIES_UNLINK = [
|
||||
'autoconf*', 'cmake*', 'gettext*', 'pkg-config*', 'qt*', 'qt@6.*',
|
||||
'libtool*', 'yasm*', 'nasm*', 'automake*', 'gnutls*', 'nettle*', 'msgpack*'
|
||||
]
|
||||
|
||||
UNINSTALL_DAEMON_SCRIPT = [
|
||||
'make -C daemon uninstall'
|
||||
]
|
||||
|
||||
ASSUME_YES_FLAG = ' -y'
|
||||
ASSUME_YES_FLAG_PACMAN = ' --noconfirm'
|
||||
|
||||
def run_powershell_cmd(cmd):
|
||||
p = subprocess.Popen(["powershell.exe", cmd], stdout=sys.stdout)
|
||||
p.communicate()
|
||||
p.wait()
|
||||
return
|
||||
|
||||
|
||||
def run_dependencies(args):
|
||||
if args.distribution == WIN32_DISTRIBUTION_NAME:
|
||||
run_powershell_cmd(
|
||||
'Set-ExecutionPolicy Unrestricted; .\\extras\\scripts\\install-deps-windows.ps1')
|
||||
|
||||
elif args.distribution in APT_BASED_DISTROS:
|
||||
if args.assume_yes:
|
||||
for i, _ in enumerate(APT_INSTALL_SCRIPT):
|
||||
APT_INSTALL_SCRIPT[i] += ASSUME_YES_FLAG
|
||||
execute_script(
|
||||
APT_INSTALL_SCRIPT,
|
||||
{"packages": ' '.join(map(shlex.quote, APT_DEPENDENCIES))})
|
||||
if not args.no_webengine:
|
||||
APT_CLIENT_DEPENDENCIES.extend(APT_QT_WEBENGINE)
|
||||
execute_script(
|
||||
APT_INSTALL_SCRIPT,
|
||||
{"packages": ' '.join(map(shlex.quote, APT_CLIENT_DEPENDENCIES))})
|
||||
|
||||
elif args.distribution in DNF_BASED_DISTROS:
|
||||
if args.assume_yes:
|
||||
for i, _ in enumerate(DNF_INSTALL_SCRIPT):
|
||||
DNF_INSTALL_SCRIPT[i] += ASSUME_YES_FLAG
|
||||
execute_script(
|
||||
RPM_INSTALL_SCRIPT,
|
||||
{"packages": ' '.join(map(shlex.quote, DNF_DEPENDENCIES))})
|
||||
if not args.no_webengine:
|
||||
DNF_CLIENT_DEPENDENCIES.extend(DNF_QT_WEBENGINE)
|
||||
execute_script(
|
||||
RPM_INSTALL_SCRIPT,
|
||||
{"packages": ' '.join(map(shlex.quote, DNF_CLIENT_DEPENDENCIES))})
|
||||
|
||||
elif args.distribution in PACMAN_BASED_DISTROS:
|
||||
if args.assume_yes:
|
||||
for i, _ in enumerate(PACMAN_INSTALL_SCRIPT):
|
||||
PACMAN_INSTALL_SCRIPT[i] += ASSUME_YES_FLAG_PACMAN
|
||||
execute_script(
|
||||
PACMAN_INSTALL_SCRIPT,
|
||||
{"packages": ' '.join(map(shlex.quote, PACMAN_DEPENDENCIES))})
|
||||
if not args.no_webengine:
|
||||
PACMAN_CLIENT_DEPENDENCIES.extend(PACMAN_QT_WEBENGINE)
|
||||
execute_script(
|
||||
PACMAN_INSTALL_SCRIPT,
|
||||
{"packages": ' '.join(map(shlex.quote, PACMAN_CLIENT_DEPENDENCIES))})
|
||||
|
||||
elif args.distribution in ZYPPER_BASED_DISTROS:
|
||||
if args.assume_yes:
|
||||
for i, _ in enumerate(ZYPPER_INSTALL_SCRIPT):
|
||||
ZYPPER_INSTALL_SCRIPT[i] += ASSUME_YES_FLAG
|
||||
execute_script(
|
||||
ZYPPER_INSTALL_SCRIPT,
|
||||
{"packages": ' '.join(map(shlex.quote, ZYPPER_DEPENDENCIES))})
|
||||
if not args.no_webengine:
|
||||
ZYPPER_CLIENT_DEPENDENCIES.extend(ZYPPER_QT_WEBENGINE)
|
||||
execute_script(
|
||||
ZYPPER_INSTALL_SCRIPT,
|
||||
{"packages": ' '.join(map(shlex.quote, ZYPPER_CLIENT_DEPENDENCIES))})
|
||||
|
||||
elif args.distribution == OSX_DISTRIBUTION_NAME:
|
||||
execute_script(
|
||||
BREW_UNLINK_SCRIPT,
|
||||
{"packages": ' '.join(map(shlex.quote, OSX_DEPENDENCIES_UNLINK))},
|
||||
False
|
||||
)
|
||||
execute_script(
|
||||
BREW_INSTALL_SCRIPT,
|
||||
{"packages": ' '.join(map(shlex.quote, OSX_DEPENDENCIES))},
|
||||
False
|
||||
)
|
||||
|
||||
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 profile defined in 'guix/manifest.scm'...")
|
||||
execute_script(['guix shell --manifest=guix/manifest.scm -- true'])
|
||||
|
||||
else:
|
||||
print("Not yet implemented for current distribution (%s). Please continue with the --install instruction. Note: You may need to install some dependencies manually." %
|
||||
args.distribution)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def run_init():
|
||||
# Extract modules path from '.gitmodules' file
|
||||
module_names = []
|
||||
with open('.gitmodules') as fd:
|
||||
for line in fd.readlines():
|
||||
if line.startswith('[submodule "'):
|
||||
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)
|
||||
|
||||
for name in module_names:
|
||||
hooks_dir = f'.git/modules/{name}/hooks'
|
||||
if not os.path.exists(hooks_dir):
|
||||
os.makedirs(hooks_dir)
|
||||
copy_file("./extras/scripts/commit-msg", f'{hooks_dir}/commit-msg')
|
||||
|
||||
module_names_to_format = ['daemon']
|
||||
for name in module_names_to_format:
|
||||
hooks_dir = f'.git/modules/{name}/hooks'
|
||||
execute_script(['./extras/scripts/format.sh --install %(path)s'],
|
||||
{"path": hooks_dir})
|
||||
|
||||
subprocess.run(["git", "submodule", "update", "--recursive", "--init"],
|
||||
check=True)
|
||||
|
||||
|
||||
def copy_file(src, dest):
|
||||
print(f'Copying: {src} to {dest}')
|
||||
try:
|
||||
shutil.copy2(src, dest)
|
||||
# e.g. src and dest are the same file
|
||||
except shutil.Error as e:
|
||||
print(f'Error: {e}')
|
||||
# e.g. source or destination doesn't exist
|
||||
except IOError as e:
|
||||
print(f'Error: {e.strerror}')
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def cwd(path):
|
||||
owd = os.getcwd()
|
||||
os.chdir(path)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
os.chdir(owd)
|
||||
|
||||
|
||||
def run_install(args):
|
||||
# Platforms with special compilation scripts
|
||||
if args.distribution == WIN32_DISTRIBUTION_NAME:
|
||||
winmake = 'daemon/compat/msvc/winmake.py'
|
||||
with cwd(os.path.dirname(winmake)):
|
||||
execute_script(
|
||||
f'python {winmake} -iv -t {args.toolset} -s {args.sdk} -b daemon')
|
||||
build_windows = 'extras/scripts/build-windows.py'
|
||||
execute_script(f'python {build_windows} init')
|
||||
execute_script(f'python {build_windows}')
|
||||
return True
|
||||
|
||||
# Unix-like platforms
|
||||
environ = os.environ.copy()
|
||||
|
||||
install_args = ['-p', str(multiprocessing.cpu_count())]
|
||||
if args.static:
|
||||
install_args.append('-s')
|
||||
if args.global_install:
|
||||
install_args.append('-g')
|
||||
if args.prefix:
|
||||
install_args += ('-P', args.prefix)
|
||||
if not args.priv_install:
|
||||
install_args.append('-u')
|
||||
if args.debug:
|
||||
install_args.append('-d')
|
||||
if args.no_libwrap:
|
||||
install_args.append('-W')
|
||||
if args.no_webengine:
|
||||
install_args.append('-w')
|
||||
|
||||
if args.distribution == OSX_DISTRIBUTION_NAME:
|
||||
# The `universal_newlines` parameter has been renamed to `text` in
|
||||
# Python 3.7+ and triggering automatical binary to text conversion is
|
||||
# what it actually does
|
||||
proc = subprocess.run(["brew", "--prefix", "qt6"],
|
||||
stdout=subprocess.PIPE, check=True,
|
||||
universal_newlines=True)
|
||||
|
||||
environ['CMAKE_PREFIX_PATH'] = proc.stdout.rstrip("\n")
|
||||
environ['CONFIGURE_FLAGS'] = '--without-dbus'
|
||||
if not args.qt:
|
||||
raise Exception('provide the Qt path using --qt=/qt/install/prefix')
|
||||
install_args += ("-Q", args.qt)
|
||||
else:
|
||||
if args.distribution in ZYPPER_BASED_DISTROS:
|
||||
# fix jsoncpp pkg-config bug, remove when jsoncpp package bumped
|
||||
environ['JSONCPP_LIBS'] = "-ljsoncpp"
|
||||
if args.qt:
|
||||
install_args += ("-Q", args.qt)
|
||||
|
||||
command = ['extras/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"]}']
|
||||
else:
|
||||
print('info: consider setting the TARBALLS environment variable '
|
||||
'to a stable writable location to avoid loosing '
|
||||
'cached tarballs')
|
||||
# Note: we must expose /gnu/store because /etc/ssl/certs
|
||||
# contains certs that are symlinks to store items.
|
||||
command = ['guix', 'shell', '--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):
|
||||
execute_script(UNINSTALL_DAEMON_SCRIPT)
|
||||
|
||||
BUILD_DIR = 'build-global' if args.global_install else 'build'
|
||||
|
||||
if (os.path.exists(BUILD_DIR)):
|
||||
UNINSTALL_CLIENT_SCRIPT = [
|
||||
f'make -C {BUILD_DIR} uninstall',
|
||||
f'rm -rf {BUILD_DIR}'
|
||||
]
|
||||
execute_script(UNINSTALL_CLIENT_SCRIPT)
|
||||
|
||||
|
||||
def run_clean():
|
||||
execute_script(['git clean -xfd',
|
||||
'git submodule foreach git clean -xfd'])
|
||||
|
||||
|
||||
def run_run(args):
|
||||
run_env = os.environ
|
||||
try:
|
||||
if args.no_libwrap:
|
||||
jamid_log = open("daemon.log", 'a')
|
||||
jamid_log.write('=== Starting daemon (%s) ===' %
|
||||
time.strftime("%d/%m/%Y %H:%M:%S"))
|
||||
jamid_process = subprocess.Popen(
|
||||
["./install/libexec/jamid", "-c", "-d"],
|
||||
stdout=jamid_log,
|
||||
stderr=jamid_log)
|
||||
|
||||
with open('daemon.pid', 'w') as f:
|
||||
f.write(str(jamid_process.pid)+'\n')
|
||||
|
||||
client_log = open('jami.log', 'a')
|
||||
client_log.write('=== Starting client (%s) ===' %
|
||||
time.strftime("%d/%m/%Y %H:%M:%S"))
|
||||
client_process = subprocess.Popen(["./install/bin/jami", "-d"],
|
||||
stdout=client_log,
|
||||
stderr=client_log,
|
||||
env=run_env)
|
||||
|
||||
with open('jami.pid', 'w') as f:
|
||||
f.write(str(client_process.pid)+'\n')
|
||||
|
||||
if args.debug and args.no_libwrap:
|
||||
subprocess.call(['gdb', './install/libexec/jamid'])
|
||||
|
||||
if not args.background:
|
||||
if args.no_libwrap:
|
||||
jamid_process.wait()
|
||||
client_process.wait()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nCaught KeyboardInterrupt...")
|
||||
|
||||
finally:
|
||||
if args.background == False:
|
||||
try:
|
||||
# Only kill the processes if they are running, as they
|
||||
# could have been closed by the user.
|
||||
print("Killing processes...")
|
||||
if args.no_libwrap:
|
||||
jamid_log.close()
|
||||
if jamid_process.poll() is None:
|
||||
jamid_process.kill()
|
||||
client_log.close()
|
||||
if client_process.poll() is None:
|
||||
client_process.kill()
|
||||
except UnboundLocalError:
|
||||
# Its okay! We crashed before we could start a process
|
||||
# or open a file. All that matters is that we close
|
||||
# files and kill processes in the right order.
|
||||
pass
|
||||
return True
|
||||
|
||||
|
||||
def run_stop(args):
|
||||
STOP_SCRIPT = ['xargs kill < jami.pid',
|
||||
'xargs kill < daemon.pid']
|
||||
execute_script(STOP_SCRIPT)
|
||||
|
||||
|
||||
def execute_script(script, settings=None, fail=True):
|
||||
if settings is None:
|
||||
settings = {}
|
||||
for line in script:
|
||||
line = line % settings
|
||||
rv = os.system(line)
|
||||
if rv and fail:
|
||||
print('Error executing script! Exit code: %s' %
|
||||
rv, file=sys.stderr)
|
||||
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 = \
|
||||
[ OSX_DISTRIBUTION_NAME, WIN32_DISTRIBUTION_NAME, 'guix'] + \
|
||||
APT_BASED_DISTROS + DNF_BASED_DISTROS + PACMAN_BASED_DISTROS \
|
||||
+ ZYPPER_BASED_DISTROS + FLATPAK_BASED_RUNTIMES
|
||||
|
||||
if (parsed_args.distribution == 'no-check'
|
||||
or 'JAMI_BUILD_NO_CHECK' in os.environ):
|
||||
return
|
||||
|
||||
if parsed_args.distribution not in supported_distros:
|
||||
print(f'WARNING: Distribution \'{parsed_args.distribution}\' is not '
|
||||
f'supported. Choose one of: {", ".join(supported_distros)}. '
|
||||
'Alternatively, you may force execution of this script '
|
||||
'by providing the \'--distribution=no-check\' argument or by '
|
||||
'exporting the JAMI_BUILD_NO_CHECK environment variable.',
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# On Windows, version 10 or later is needed to build Jami.
|
||||
if parsed_args.distribution == WIN32_DISTRIBUTION_NAME:
|
||||
if hasattr(sys, 'getwindowsversion') and sys.getwindowsversion()[0] < 10:
|
||||
print('Windows 10 or later is needed to build Jami')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def parse_args():
|
||||
ap = argparse.ArgumentParser(description="Jami build tool")
|
||||
|
||||
ga = ap.add_mutually_exclusive_group(required=True)
|
||||
ga.add_argument(
|
||||
'--init', action='store_true',
|
||||
help='Init Jami repository')
|
||||
ga.add_argument(
|
||||
'--dependencies', action='store_true',
|
||||
help='Install Jami build dependencies')
|
||||
ga.add_argument(
|
||||
'--install', action='store_true',
|
||||
help='Build and install Jami')
|
||||
ga.add_argument(
|
||||
'--clean', action='store_true',
|
||||
help='Call "git clean" on every repository of the project'
|
||||
)
|
||||
ga.add_argument(
|
||||
'--uninstall', action='store_true',
|
||||
help='Uninstall Jami')
|
||||
ga.add_argument(
|
||||
'--run', action='store_true',
|
||||
help='Run the Jami daemon and client')
|
||||
ga.add_argument(
|
||||
'--stop', action='store_true',
|
||||
help='Stop the Jami processes')
|
||||
|
||||
ap.add_argument('--distribution')
|
||||
ap.add_argument('--prefix')
|
||||
ap.add_argument('--static', default=False, action='store_true')
|
||||
ap.add_argument('--global-install', default=False, action='store_true')
|
||||
ap.add_argument('--debug', default=False, action='store_true',
|
||||
help='Build with debug support; run in GDB')
|
||||
ap.add_argument('--background', default=False, action='store_true')
|
||||
ap.add_argument('--no-priv-install', dest='priv_install',
|
||||
default=True, action='store_false')
|
||||
ap.add_argument('--qt', type=str,
|
||||
help='Use the Qt path supplied')
|
||||
ap.add_argument('--no-libwrap', dest='no_libwrap',
|
||||
default=False, action='store_true',
|
||||
help='Disable libwrap. Also set --disable-shared option to daemon configure')
|
||||
ap.add_argument('-y', '--assume-yes', default=False, action='store_true',
|
||||
help='Assume yes (do not prompt user) for dependency installations through the system package manager')
|
||||
ap.add_argument('--no-webengine', dest='no_webengine',
|
||||
default=False, action='store_true',
|
||||
help='Do not use Qt WebEngine.')
|
||||
|
||||
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')
|
||||
|
||||
parsed_args = ap.parse_args()
|
||||
|
||||
if parsed_args.distribution:
|
||||
parsed_args.distribution = parsed_args.distribution.lower()
|
||||
else:
|
||||
parsed_args.distribution = dist
|
||||
|
||||
validate_args(parsed_args)
|
||||
|
||||
return parsed_args
|
||||
|
||||
|
||||
def choose_distribution():
|
||||
system = platform.system().lower()
|
||||
|
||||
if system == "linux" or system == "linux2":
|
||||
if os.path.isfile("/etc/arch-release"):
|
||||
return "arch"
|
||||
try:
|
||||
with open("/etc/os-release") as f:
|
||||
for line in f:
|
||||
k, v = line.split("=")
|
||||
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
|
||||
elif system == "windows":
|
||||
return WIN32_DISTRIBUTION_NAME
|
||||
|
||||
return 'Unknown'
|
||||
|
||||
|
||||
def main():
|
||||
parsed_args = parse_args()
|
||||
|
||||
if parsed_args.dependencies:
|
||||
run_dependencies(parsed_args)
|
||||
|
||||
elif parsed_args.init:
|
||||
run_init()
|
||||
elif parsed_args.clean:
|
||||
run_clean()
|
||||
|
||||
elif parsed_args.install:
|
||||
run_install(parsed_args)
|
||||
|
||||
elif parsed_args.uninstall:
|
||||
run_uninstall(parsed_args)
|
||||
|
||||
elif parsed_args.run:
|
||||
if (parsed_args.distribution == 'guix'
|
||||
and 'GUIX_ENVIRONMENT' not in os.environ):
|
||||
# Relaunch this script, this time in a pure Guix environment.
|
||||
guix_args = ['shell', '--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 shell 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)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
181
extras/scripts/commit-msg
Executable file
181
extras/scripts/commit-msg
Executable file
|
@ -0,0 +1,181 @@
|
|||
#!/bin/sh
|
||||
# From Gerrit Code Review 2.11.3
|
||||
#
|
||||
# Part of Gerrit Code Review (http://code.google.com/p/gerrit/)
|
||||
#
|
||||
# Copyright (C) 2009 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
unset GREP_OPTIONS
|
||||
|
||||
CHANGE_ID_AFTER="Bug|Issue"
|
||||
MSG="$1"
|
||||
|
||||
# Check for, and add if missing, a unique Change-Id
|
||||
#
|
||||
add_ChangeId() {
|
||||
clean_message=`sed -e '
|
||||
/^diff --git .*/{
|
||||
s///
|
||||
q
|
||||
}
|
||||
/^Signed-off-by:/d
|
||||
/^#/d
|
||||
' "$MSG" | git stripspace`
|
||||
if test -z "$clean_message"
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
if test "false" = "`git config --bool --get gerrit.createChangeId`"
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
# Does Change-Id: already exist? if so, exit (no change).
|
||||
if grep -i '^Change-Id:' "$MSG" >/dev/null
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
id=`_gen_ChangeId`
|
||||
T="$MSG.tmp.$$"
|
||||
AWK=awk
|
||||
if [ -x /usr/xpg4/bin/awk ]; then
|
||||
# Solaris AWK is just too broken
|
||||
AWK=/usr/xpg4/bin/awk
|
||||
fi
|
||||
|
||||
# How this works:
|
||||
# - parse the commit message as (textLine+ blankLine*)*
|
||||
# - assume textLine+ to be a footer until proven otherwise
|
||||
# - exception: the first block is not footer (as it is the title)
|
||||
# - read textLine+ into a variable
|
||||
# - then count blankLines
|
||||
# - once the next textLine appears, print textLine+ blankLine* as these
|
||||
# aren't footer
|
||||
# - in END, the last textLine+ block is available for footer parsing
|
||||
$AWK '
|
||||
BEGIN {
|
||||
# while we start with the assumption that textLine+
|
||||
# is a footer, the first block is not.
|
||||
isFooter = 0
|
||||
footerComment = 0
|
||||
blankLines = 0
|
||||
}
|
||||
|
||||
# Skip lines starting with "#" without any spaces before it.
|
||||
/^#/ { next }
|
||||
|
||||
# Skip the line starting with the diff command and everything after it,
|
||||
# up to the end of the file, assuming it is only patch data.
|
||||
# If more than one line before the diff was empty, strip all but one.
|
||||
/^diff --git / {
|
||||
blankLines = 0
|
||||
while (getline) { }
|
||||
next
|
||||
}
|
||||
|
||||
# Count blank lines outside footer comments
|
||||
/^$/ && (footerComment == 0) {
|
||||
blankLines++
|
||||
next
|
||||
}
|
||||
|
||||
# Catch footer comment
|
||||
/^\[[a-zA-Z0-9-]+:/ && (isFooter == 1) {
|
||||
footerComment = 1
|
||||
}
|
||||
|
||||
/]$/ && (footerComment == 1) {
|
||||
footerComment = 2
|
||||
}
|
||||
|
||||
# We have a non-blank line after blank lines. Handle this.
|
||||
(blankLines > 0) {
|
||||
print lines
|
||||
for (i = 0; i < blankLines; i++) {
|
||||
print ""
|
||||
}
|
||||
|
||||
lines = ""
|
||||
blankLines = 0
|
||||
isFooter = 1
|
||||
footerComment = 0
|
||||
}
|
||||
|
||||
# Detect that the current block is not the footer
|
||||
(footerComment == 0) && (!/^\[?[a-zA-Z0-9-]+:/ || /^[a-zA-Z0-9-]+:\/\//) {
|
||||
isFooter = 0
|
||||
}
|
||||
|
||||
{
|
||||
# We need this information about the current last comment line
|
||||
if (footerComment == 2) {
|
||||
footerComment = 0
|
||||
}
|
||||
if (lines != "") {
|
||||
lines = lines "\n";
|
||||
}
|
||||
lines = lines $0
|
||||
}
|
||||
|
||||
# Footer handling:
|
||||
# If the last block is considered a footer, splice in the Change-Id at the
|
||||
# right place.
|
||||
# Look for the right place to inject Change-Id by considering
|
||||
# CHANGE_ID_AFTER. Keys listed in it (case insensitive) come first,
|
||||
# then Change-Id, then everything else (eg. Signed-off-by:).
|
||||
#
|
||||
# Otherwise just print the last block, a new line and the Change-Id as a
|
||||
# block of its own.
|
||||
END {
|
||||
unprinted = 1
|
||||
if (isFooter == 0) {
|
||||
print lines "\n"
|
||||
lines = ""
|
||||
}
|
||||
changeIdAfter = "^(" tolower("'"$CHANGE_ID_AFTER"'") "):"
|
||||
numlines = split(lines, footer, "\n")
|
||||
for (line = 1; line <= numlines; line++) {
|
||||
if (unprinted && match(tolower(footer[line]), changeIdAfter) != 1) {
|
||||
unprinted = 0
|
||||
print "Change-Id: I'"$id"'"
|
||||
}
|
||||
print footer[line]
|
||||
}
|
||||
if (unprinted) {
|
||||
print "Change-Id: I'"$id"'"
|
||||
}
|
||||
}' "$MSG" > "$T" && mv "$T" "$MSG" || rm -f "$T"
|
||||
}
|
||||
_gen_ChangeIdInput() {
|
||||
echo "tree `git write-tree`"
|
||||
if parent=`git rev-parse "HEAD^0" 2>/dev/null`
|
||||
then
|
||||
echo "parent $parent"
|
||||
fi
|
||||
echo "author `git var GIT_AUTHOR_IDENT`"
|
||||
echo "committer `git var GIT_COMMITTER_IDENT`"
|
||||
echo
|
||||
printf '%s' "$clean_message"
|
||||
}
|
||||
_gen_ChangeId() {
|
||||
_gen_ChangeIdInput |
|
||||
git hash-object -t commit --stdin
|
||||
}
|
||||
|
||||
|
||||
add_ChangeId
|
103
extras/scripts/format.sh
Executable file
103
extras/scripts/format.sh
Executable file
|
@ -0,0 +1,103 @@
|
|||
#!/usr/bin/env bash
|
||||
# format.sh --- set up clang-format for source files
|
||||
|
||||
# Copyright (C) 2020-2022 Savoir-faire Linux Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
set -e
|
||||
|
||||
command_exists ()
|
||||
{
|
||||
type "$1" &> /dev/null ;
|
||||
}
|
||||
|
||||
CFVERSION="9"
|
||||
CLANGFORMAT=""
|
||||
if command_exists clang-format-${CFVERSION}; then
|
||||
CLANGFORMAT=clang-format-${CFVERSION}
|
||||
else
|
||||
if command_exists clang-format; then
|
||||
CLANGFORMAT=clang-format
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! command -v $CLANGFORMAT &> /dev/null; then
|
||||
echo "Required version of clang-format not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
format_file()
|
||||
{
|
||||
if [ -f "${1}" ]; then
|
||||
$CLANGFORMAT -i -style=file "${1}" || true
|
||||
fi
|
||||
}
|
||||
|
||||
format_files()
|
||||
{
|
||||
for file in $1; do
|
||||
echo -ne "Formatting: ${file}\\033[0K\\r"
|
||||
format_file "${file}"
|
||||
done
|
||||
}
|
||||
|
||||
exit_if_no_files()
|
||||
{
|
||||
echo No files to format
|
||||
exit 0
|
||||
}
|
||||
|
||||
install_hook()
|
||||
{
|
||||
hooks_path=$1
|
||||
if [ ! -d "$hooks_path" ]; then
|
||||
echo "$hooks_path" path does not exist
|
||||
exit 1
|
||||
fi
|
||||
echo Installing pre-commit hook in "$hooks_path"
|
||||
echo "$(realpath $0)" > "$hooks_path"/pre-commit
|
||||
chmod +x "$hooks_path"/pre-commit
|
||||
}
|
||||
|
||||
display_help()
|
||||
{
|
||||
echo "Usage: $0 [OPTION...] -- Clang format source files with a .clang-format file" >&2
|
||||
echo
|
||||
echo " --all format all files instead of only committed ones"
|
||||
echo " --install <path> install a pre-commit hook to run this script"
|
||||
echo
|
||||
}
|
||||
|
||||
if [ "$1" == "--help" ]; then
|
||||
display_help
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case "${1}" in
|
||||
--all )
|
||||
files=$(find src -regex '.*\.\(cpp\|hpp\|cc\|cxx\|h\)$') || true
|
||||
echo Formatting all source files...
|
||||
format_files "$files"
|
||||
;;
|
||||
--install )
|
||||
install_hook "${2}"
|
||||
;;
|
||||
* )
|
||||
files=$(git diff-index --cached --name-only HEAD | grep -iE '\.(cpp|cxx|cc|h|hpp)$') || exit_if_no_files
|
||||
echo Formatting committed source files...
|
||||
format_files "$files"
|
||||
;;
|
||||
esac
|
236
extras/scripts/install-deps-windows.ps1
Normal file
236
extras/scripts/install-deps-windows.ps1
Normal file
|
@ -0,0 +1,236 @@
|
|||
# Copyright (C) 2019-2022 Savoir-faire Linux Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
<#
|
||||
This script should install dependencies required for building the Jami
|
||||
Qt client on windows.
|
||||
|
||||
Required components not installed:
|
||||
- Visual Studio
|
||||
- build toolchains
|
||||
- SDKs
|
||||
- WiX + WiX Visual Studio extension
|
||||
- Qt + Qt Visual Studio extension
|
||||
#>
|
||||
|
||||
write-host "Installing jami-qt build dependencies for windows…" -ForegroundColor Green
|
||||
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||
|
||||
$global:installed_packages = $null
|
||||
Function choco_check_package([String] $package, [String] $version = "") {
|
||||
# Query a package listing once
|
||||
if ($null -eq $global:installed_packages) {
|
||||
write-host "Getting installed package list from Chocolatey…" -ForegroundColor DarkCyan
|
||||
$global:installed_packages = choco list -lo
|
||||
}
|
||||
# Check installed packages
|
||||
$result = $global:installed_packages | Where-object {
|
||||
$_.ToLower().StartsWith($package.ToLower())
|
||||
}
|
||||
if ($null -eq $result) {
|
||||
# We don't have the package
|
||||
write-host $package "not found." -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
if ("" -eq $version) {
|
||||
# We have the package and don't care what version it is
|
||||
write-host $package "found." -ForegroundColor Cyan
|
||||
return $true
|
||||
}
|
||||
# We now check the results for a package of the specified version
|
||||
$parts = $result.Split(' ')
|
||||
Foreach ($part in $parts) {
|
||||
if ($part -eq $version) {
|
||||
# We have the package of the specified version
|
||||
write-host $package $version "found." -ForegroundColor Cyan
|
||||
return $true
|
||||
}
|
||||
}
|
||||
# We don't have the package of the specified version
|
||||
write-host $package $version "not found." -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
Function install_chocolatey {
|
||||
# Install Chocolatey if not installed already
|
||||
if (!(Test-Path "$($env:ProgramData)\chocolatey\choco.exe")) {
|
||||
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString("https://chocolatey.org/install.ps1"))
|
||||
if ( $LASTEXITCODE -eq 0 ) {
|
||||
write-host "Chocolatey installation succeeded" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
write-host "Chocolatey installation failed" -ForegroundColor Red
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
}
|
||||
else {
|
||||
write-host "Chocolatey already installed" -ForegroundColor DarkGreen
|
||||
}
|
||||
}
|
||||
|
||||
Function choco_install_package([String] $package, [String] $version = "") {
|
||||
$package_installed = choco_check_package $package $version
|
||||
if ($true -eq $package_installed) {
|
||||
return
|
||||
}
|
||||
if ("" -ne $version) {
|
||||
write-host "Installing" $package "@" $version
|
||||
choco install -fy --allow-downgrade $package --version $version --acceptlicense
|
||||
}
|
||||
else {
|
||||
write-host "Installing" $package
|
||||
choco install -fy --allow-downgrade $package --acceptlicense
|
||||
}
|
||||
if ( $LASTEXITCODE -ne 0 ) {
|
||||
write-host "Choco Packages Installation Failed" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
Function install_choco_packages($packages) {
|
||||
Foreach ($i in $packages) {
|
||||
choco_install_package $i.pkg $i.ver
|
||||
}
|
||||
write-host "Choco Packages Installation Succeeded" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Function download_file_to_temp($download_name, $url, $output_name) {
|
||||
write-host "Downloading $download_name" -ForegroundColor DarkCyan
|
||||
$output = $env:TEMP + "\$output_name"
|
||||
(New-Object System.Net.WebClient).DownloadFile($url, $output)
|
||||
if ( $LASTEXITCODE -eq 0 ) {
|
||||
write-host "Download $download_name Succeeded" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
write-host "Download $download_name Failed" -ForegroundColor Red
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
}
|
||||
|
||||
Function unzip_file_from_temp($unzip_name, $zip_file_name, $unzip_file_output_name) {
|
||||
write-host "Unzipping $unzip_name" -ForegroundColor DarkCyan
|
||||
$zip_path = $env:TEMP + "\$zip_file_name"
|
||||
$unzip_path = $env:TEMP + "\$unzip_file_output_name"
|
||||
Invoke-Expression("unzip -o $zip_path -d '$unzip_path'") | Out-Null
|
||||
if ( $LASTEXITCODE -eq 0 ) {
|
||||
write-host "Unzip $unzip_name Succeeded" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
write-host "Unzip $unzip_name Failed" -ForegroundColor Red
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
}
|
||||
|
||||
Function run_batch($batch_cmd, $task_name) {
|
||||
write-host $task_name -ForegroundColor DarkCyan
|
||||
Start-Process "cmd.exe" $batch_cmd -Wait -NoNewWindow | Out-Null
|
||||
if ( $LASTEXITCODE -eq 0 ) {
|
||||
write-host "$task_name Succeeded" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
write-host "$task_name Failed" -ForegroundColor Red
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
}
|
||||
|
||||
Function move_file_from_temp_to_msys64($file_name, $task_name) {
|
||||
write-host $task_name -ForegroundColor DarkCyan
|
||||
$file_path = $env:TEMP + "\$file_name"
|
||||
Move-item -Path $file_path -Destination $msys2_path -Force
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
write-host "$task_name Succeeded" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
write-host "$task_name Failed" -ForegroundColor Red
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
}
|
||||
|
||||
Function install_msys2_packages($packages) {
|
||||
Foreach ($i in $packages) {
|
||||
Invoke-Expression ("pacman -Q '$i'") | out-null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
write-host $i "already installed" -ForegroundColor Cyan
|
||||
continue
|
||||
}
|
||||
Invoke-Expression ("pacman -S '$i' --noconfirm")
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
write-host "Pacman Packages Installation Failed" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
write-host "Pacman Packages Installation Succeeded" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Web installed msys2_64 bit to install make, gcc, perl, diffutils
|
||||
$msys_packages = @("make", "gcc", "perl", "diffutils")
|
||||
|
||||
# Install 7zip, unzip, wget --version 1.19.4, cmake, git --version 2.10.2, pandoc, strawberryperl, msys2
|
||||
$choco_packages = @(
|
||||
[pscustomobject]@{pkg = "wget"; ver = "1.19.4" }
|
||||
[pscustomobject]@{pkg = "git.install"; ver = "2.10.2" }
|
||||
[pscustomobject]@{pkg = "7zip"; ver = "" }
|
||||
[pscustomobject]@{pkg = "unzip"; ver = "" }
|
||||
[pscustomobject]@{pkg = "cmake"; ver = "" }
|
||||
[pscustomobject]@{pkg = "pandoc"; ver = "" }
|
||||
[pscustomobject]@{pkg = "strawberryperl"; ver = "" }
|
||||
[pscustomobject]@{pkg = "msys2"; ver = "" }
|
||||
)
|
||||
|
||||
install_chocolatey
|
||||
|
||||
# Check for an existing msys2 install
|
||||
# Note that choco installs msys2 in C:/tools/
|
||||
if (!(Test-Path -Path "C:\msys64")) {
|
||||
$Env:Path += ";C:\tools\msys64\usr\bin"
|
||||
$msys2_path = "C:\tools\msys64\usr\bin"
|
||||
if ((Test-Path -Path "C:\tools\msys64")) {
|
||||
write-host "MSYS2 64 already installed" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
$choco_packages.Add([pscustomobject]@{pkg = "msys2"; ver = "" })
|
||||
}
|
||||
}
|
||||
else {
|
||||
write-host "MSYS2 64 already installed" -ForegroundColor Green
|
||||
$Env:Path += ";C:\msys64\usr\bin"
|
||||
$msys2_path = "C:\msys64\usr\bin"
|
||||
}
|
||||
|
||||
install_choco_packages $choco_packages
|
||||
install_msys2_packages $msys_packages
|
||||
|
||||
# Install VSNASM
|
||||
download_file_to_temp 'VSNASM' "https://github.com/ShiftMediaProject/VSNASM/releases/download/0.5/VSNASM.zip" 'VSNASM.zip'
|
||||
unzip_file_from_temp 'VSNASM' 'VSNASM.zip' 'VSNASM_UNZIP'
|
||||
$batch_path = "/c set ISINSTANCE=1 &&" + $env:TEMP + "\VSNASM_UNZIP\install_script.bat"
|
||||
run_batch $batch_path "Install VSNASM"
|
||||
|
||||
# Install VSYASM
|
||||
download_file_to_temp 'VSYASM' "https://github.com/ShiftMediaProject/VSYASM/releases/download/0.4/VSYASM.zip" 'VSYASM.zip'
|
||||
unzip_file_from_temp 'VSYASM' 'VSYASM.zip' 'VSYASM_UNZIP'
|
||||
$batch_path = "/c set ISINSTANCE=1 &&" + $env:TEMP + "\VSYASM_UNZIP\install_script.bat"
|
||||
run_batch $batch_path "Install VSYASM"
|
||||
|
||||
# Install yasm.exe (win64)
|
||||
download_file_to_temp 'yasm.exe (win64)' "http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe" 'yasm.exe'
|
||||
move_file_from_temp_to_msys64 'yasm.exe' 'Move yasm.exe (win64) to msys64 folder'
|
||||
|
||||
# Install gas-preprocessor.pl
|
||||
download_file_to_temp 'gas-preprocessor.pl' "https://github.com/FFmpeg/gas-preprocessor/blob/master/gas-preprocessor.pl" 'gas-preprocessor.pl'
|
||||
move_file_from_temp_to_msys64 'gas-preprocessor.pl' 'Move gas-preprocessor.pl to msys64 folder'
|
||||
|
||||
write-host "Done" -ForegroundColor Green
|
187
extras/scripts/install.sh
Executable file
187
extras/scripts/install.sh
Executable file
|
@ -0,0 +1,187 @@
|
|||
#!/usr/bin/env bash
|
||||
# install.sh --- build and install Jami daemon and client
|
||||
|
||||
# Copyright (C) 2016-2022 Savoir-faire Linux Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
# Build and install to a local prefix under this repository.
|
||||
export OSTYPE
|
||||
|
||||
# Flags:
|
||||
|
||||
# -g: install globally instead for all users
|
||||
# -s: link everything statically, no D-Bus communication. More likely to work!
|
||||
# -p: number of processors to use
|
||||
# -u: disable use of privileges (sudo) during install
|
||||
# -W: disable libwrap and shared library
|
||||
# -w: do not use Qt WebEngine
|
||||
|
||||
set -ex
|
||||
|
||||
# Qt_MIN_VER required for client-qt
|
||||
QT_MIN_VER="6.2"
|
||||
|
||||
debug=
|
||||
global=false
|
||||
static=''
|
||||
qtpath=''
|
||||
proc='1'
|
||||
priv_install=true
|
||||
enable_libwrap=true
|
||||
enable_webengine=true
|
||||
|
||||
while getopts gsc:dQ:P:p:uWw OPT; do
|
||||
case "$OPT" in
|
||||
g)
|
||||
global='true'
|
||||
;;
|
||||
s)
|
||||
static='-DENABLE_STATIC=true'
|
||||
;;
|
||||
d)
|
||||
debug=true
|
||||
;;
|
||||
Q)
|
||||
qtpath="${OPTARG}"
|
||||
;;
|
||||
P)
|
||||
prefix="${OPTARG}"
|
||||
;;
|
||||
p)
|
||||
proc="${OPTARG}"
|
||||
;;
|
||||
u)
|
||||
priv_install='false'
|
||||
;;
|
||||
W)
|
||||
enable_libwrap='false'
|
||||
;;
|
||||
w)
|
||||
enable_webengine='false'
|
||||
;;
|
||||
\?)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# $1: global-install?
|
||||
# $2: private-install?
|
||||
make_install() {
|
||||
if [ "$1" = "true" ] && [ "$2" != "false" ]; then
|
||||
sudo make install
|
||||
# Or else the next non-sudo install will fail, because this generates some
|
||||
# root owned files like install_manifest.txt under the build directory.
|
||||
sudo chown -R "$USER" .
|
||||
else
|
||||
make install
|
||||
fi
|
||||
}
|
||||
|
||||
TOP="$(pwd)"
|
||||
INSTALL_DIR="${TOP}/install" # local install directory
|
||||
|
||||
if [ "${global}" = "true" ]; then
|
||||
BUILD_DIR="build-global"
|
||||
else
|
||||
BUILD_DIR="build"
|
||||
fi
|
||||
|
||||
# jamid
|
||||
DAEMON="${TOP}/daemon"
|
||||
cd "$DAEMON"
|
||||
|
||||
# Build the contribs.
|
||||
mkdir -p contrib/native
|
||||
(
|
||||
cd contrib/native
|
||||
../bootstrap ${prefix:+"--prefix=$prefix"}
|
||||
make -j"${proc}"
|
||||
)
|
||||
|
||||
if [[ "${enable_libwrap}" != "true" ]]; then
|
||||
# Disable shared if requested
|
||||
if [[ "$OSTYPE" != "darwin"* ]]; then
|
||||
CONFIGURE_FLAGS+=" --disable-shared"
|
||||
fi
|
||||
fi
|
||||
|
||||
BUILD_TYPE="Release"
|
||||
if [ "${debug}" = "true" ]; then
|
||||
BUILD_TYPE="Debug"
|
||||
CONFIGURE_FLAGS+=" --enable-debug"
|
||||
fi
|
||||
|
||||
# Build the daemon itself.
|
||||
test -f configure || ./autogen.sh
|
||||
|
||||
if [ "${global}" = "true" ]; then
|
||||
./configure ${CONFIGURE_FLAGS} ${prefix:+"--prefix=$prefix"}
|
||||
else
|
||||
./configure ${CONFIGURE_FLAGS} --prefix="${INSTALL_DIR}"
|
||||
fi
|
||||
make -j"${proc}" V=1
|
||||
make_install "${global}" "${priv_install}"
|
||||
|
||||
# Verify system's version if no path provided.
|
||||
if [ -z "$qtpath" ]; then
|
||||
sys_qtver=""
|
||||
if command -v qmake6 &> /dev/null; then
|
||||
sys_qtver=$(qmake6 -v)
|
||||
elif command -v qmake-qt6 &> /dev/null; then
|
||||
sys_qtver=$(qmake-qt6 -v) # Fedora
|
||||
elif command -v qmake &> /dev/null; then
|
||||
sys_qtver=$(qmake -v)
|
||||
else
|
||||
echo "No valid Qt found"; exit 1;
|
||||
fi
|
||||
|
||||
sys_qtver=${sys_qtver#*Qt version}
|
||||
sys_qtver=${sys_qtver%\ in\ *}
|
||||
|
||||
installed_qtver=$(echo "$sys_qtver" | cut -d'.' -f 2)
|
||||
required_qtver=$(echo $QT_MIN_VER | cut -d'.' -f 2)
|
||||
|
||||
if [[ $installed_qtver -ge $required_qtver ]] ; then
|
||||
# Set qtpath to empty in order to use system's Qt.
|
||||
qtpath=""
|
||||
else
|
||||
echo "No valid Qt found"; exit 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
# client
|
||||
cd "${TOP}"
|
||||
mkdir -p "${BUILD_DIR}"
|
||||
cd "${BUILD_DIR}"
|
||||
|
||||
client_cmake_flags=(-DCMAKE_BUILD_TYPE="${BUILD_TYPE}"
|
||||
-DCMAKE_PREFIX_PATH="${qtpath}"
|
||||
-DENABLE_LIBWRAP="${enable_libwrap}"
|
||||
-DWITH_WEBENGINE="${enable_webengine}")
|
||||
|
||||
if [ "${global}" = "true" ]; then
|
||||
client_cmake_flags+=(${prefix:+"-DCMAKE_INSTALL_PREFIX=$prefix"}
|
||||
$static)
|
||||
else
|
||||
client_cmake_flags+=(-DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}"
|
||||
-DLIBJAMI_BUILD_DIR="${DAEMON}/src")
|
||||
fi
|
||||
|
||||
echo "info: Configuring $client client with flags: ${client_cmake_flags[*]}"
|
||||
cmake .. "${client_cmake_flags[@]}"
|
||||
make -j"${proc}" V=1
|
||||
make_install "${global}" "${priv_install}"
|
Loading…
Add table
Reference in a new issue