mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-06-09 18:04:53 +03:00
Debian 13 Trixie and Ubuntu 24.04 Noble come with time64 transitioned packages: https://wiki.debian.org/ReleaseGoals/64bit-time This means, all packages with use the time_t syscall on 32-bit do now use the time64 syscall instead, to get 64-bit year 2038 prove UNIX time values. Those packages get a "t64" suffix for their name, also for 64-bit architectures for consistency. Since time_t values on 64-bit are 64-bit already, no actual change happened there, and a package dependency without the t64 suffix is still satisfied by the packages with t64 suffix, via "Provides" attribute. This however is not he case for 32-bit. The rustdesk package currently depends on libgtk-3-0 and libasound2, while Debian Trixie and Ubuntu Noble serve libgtk-3-0t64 and libasound2t64. On 64-bit architectures (amd64 and arm64), the available packages satisfy the dependency, but on 32-bit (armhf) this is not the case. In turn the rustdesk armv7-sciter.deb package cannot be installed on recent distro versions. This commit solves the issue by adding the respective t64 packages are alternative dependency. If available, the t64 package is installed, else (on older distro versions), the one without t64 suffix. Signed-off-by: MichaIng <micha@dietpi.com>
648 lines
26 KiB
Python
Executable File
648 lines
26 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import pathlib
|
|
import platform
|
|
import zipfile
|
|
import urllib.request
|
|
import shutil
|
|
import hashlib
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
windows = platform.platform().startswith('Windows')
|
|
osx = platform.platform().startswith(
|
|
'Darwin') or platform.platform().startswith("macOS")
|
|
hbb_name = 'rustdesk' + ('.exe' if windows else '')
|
|
exe_path = 'target/release/' + hbb_name
|
|
if windows:
|
|
flutter_build_dir = 'build/windows/x64/runner/Release/'
|
|
elif osx:
|
|
flutter_build_dir = 'build/macos/Build/Products/Release/'
|
|
else:
|
|
flutter_build_dir = 'build/linux/x64/release/bundle/'
|
|
flutter_build_dir_2 = f'flutter/{flutter_build_dir}'
|
|
skip_cargo = False
|
|
|
|
|
|
def get_deb_arch() -> str:
|
|
custom_arch = os.environ.get("DEB_ARCH")
|
|
if custom_arch is None:
|
|
return "amd64"
|
|
return custom_arch
|
|
|
|
def get_deb_extra_depends() -> str:
|
|
custom_arch = os.environ.get("DEB_ARCH")
|
|
if custom_arch == "armhf": # for arm32v7 libsciter-gtk.so
|
|
return ", libatomic1"
|
|
return ""
|
|
|
|
def system2(cmd):
|
|
exit_code = os.system(cmd)
|
|
if exit_code != 0:
|
|
sys.stderr.write(f"Error occurred when executing: `{cmd}`. Exiting.\n")
|
|
sys.exit(-1)
|
|
|
|
|
|
def get_version():
|
|
with open("Cargo.toml", encoding="utf-8") as fh:
|
|
for line in fh:
|
|
if line.startswith("version"):
|
|
return line.replace("version", "").replace("=", "").replace('"', '').strip()
|
|
return ''
|
|
|
|
|
|
def parse_rc_features(feature):
|
|
available_features = {}
|
|
apply_features = {}
|
|
if not feature:
|
|
feature = []
|
|
|
|
def platform_check(platforms):
|
|
if windows:
|
|
return 'windows' in platforms
|
|
elif osx:
|
|
return 'osx' in platforms
|
|
else:
|
|
return 'linux' in platforms
|
|
|
|
def get_all_features():
|
|
features = []
|
|
for (feat, feat_info) in available_features.items():
|
|
if platform_check(feat_info['platform']):
|
|
features.append(feat)
|
|
return features
|
|
|
|
if isinstance(feature, str) and feature.upper() == 'ALL':
|
|
return get_all_features()
|
|
elif isinstance(feature, list):
|
|
if windows:
|
|
# download third party is deprecated, we use github ci instead.
|
|
# feature.append('PrivacyMode')
|
|
pass
|
|
for feat in feature:
|
|
if isinstance(feat, str) and feat.upper() == 'ALL':
|
|
return get_all_features()
|
|
if feat in available_features:
|
|
if platform_check(available_features[feat]['platform']):
|
|
apply_features[feat] = available_features[feat]
|
|
else:
|
|
print(f'Unrecognized feature {feat}')
|
|
return apply_features
|
|
else:
|
|
raise Exception(f'Unsupported features param {feature}')
|
|
|
|
|
|
def make_parser():
|
|
parser = argparse.ArgumentParser(description='Build script.')
|
|
parser.add_argument(
|
|
'-f',
|
|
'--feature',
|
|
dest='feature',
|
|
metavar='N',
|
|
type=str,
|
|
nargs='+',
|
|
default='',
|
|
help='Integrate features, windows only.'
|
|
'Available: [Not used for now]. Special value is "ALL" and empty "". Default is empty.')
|
|
parser.add_argument('--flutter', action='store_true',
|
|
help='Build flutter package', default=False)
|
|
parser.add_argument(
|
|
'--hwcodec',
|
|
action='store_true',
|
|
help='Enable feature hwcodec' + (
|
|
'' if windows or osx else ', need libva-dev.')
|
|
)
|
|
parser.add_argument(
|
|
'--vram',
|
|
action='store_true',
|
|
help='Enable feature vram, only available on windows now.'
|
|
)
|
|
parser.add_argument(
|
|
'--portable',
|
|
action='store_true',
|
|
help='Build windows portable'
|
|
)
|
|
parser.add_argument(
|
|
'--unix-file-copy-paste',
|
|
action='store_true',
|
|
help='Build with unix file copy paste feature'
|
|
)
|
|
parser.add_argument(
|
|
'--skip-cargo',
|
|
action='store_true',
|
|
help='Skip cargo build process, only flutter version + Linux supported currently'
|
|
)
|
|
if windows:
|
|
parser.add_argument(
|
|
'--skip-portable-pack',
|
|
action='store_true',
|
|
help='Skip packing, only flutter version + Windows supported'
|
|
)
|
|
parser.add_argument(
|
|
"--package",
|
|
type=str
|
|
)
|
|
if osx:
|
|
parser.add_argument(
|
|
'--screencapturekit',
|
|
action='store_true',
|
|
help='Enable feature screencapturekit'
|
|
)
|
|
return parser
|
|
|
|
|
|
# Generate build script for docker
|
|
#
|
|
# it assumes all build dependencies are installed in environments
|
|
# Note: do not use it in bare metal, or may break build environments
|
|
def generate_build_script_for_docker():
|
|
with open("/tmp/build.sh", "w") as f:
|
|
f.write('''
|
|
#!/bin/bash
|
|
# environment
|
|
export CPATH="$(clang -v 2>&1 | grep "Selected GCC installation: " | cut -d' ' -f4-)/include"
|
|
# flutter
|
|
pushd /opt
|
|
wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.0.5-stable.tar.xz
|
|
tar -xvf flutter_linux_3.0.5-stable.tar.xz
|
|
export PATH=`pwd`/flutter/bin:$PATH
|
|
popd
|
|
# flutter_rust_bridge
|
|
dart pub global activate ffigen --version 5.0.1
|
|
pushd /tmp && git clone https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge --depth=1 && popd
|
|
pushd /tmp/flutter_rust_bridge/frb_codegen && cargo install --path . --locked && popd
|
|
pushd flutter && flutter pub get && popd
|
|
~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
|
|
# install vcpkg
|
|
pushd /opt
|
|
export VCPKG_ROOT=`pwd`/vcpkg
|
|
git clone https://github.com/microsoft/vcpkg
|
|
vcpkg/bootstrap-vcpkg.sh
|
|
popd
|
|
$VCPKG_ROOT/vcpkg install --x-install-root="$VCPKG_ROOT/installed"
|
|
# build rustdesk
|
|
./build.py --flutter --hwcodec
|
|
''')
|
|
system2("chmod +x /tmp/build.sh")
|
|
system2("bash /tmp/build.sh")
|
|
|
|
|
|
# Downloading third party resources is deprecated.
|
|
# We can use this function in an offline build environment.
|
|
# Even in an online environment, we recommend building third-party resources yourself.
|
|
def download_extract_features(features, res_dir):
|
|
import re
|
|
|
|
proxy = ''
|
|
|
|
def req(url):
|
|
if not proxy:
|
|
return url
|
|
else:
|
|
r = urllib.request.Request(url)
|
|
r.set_proxy(proxy, 'http')
|
|
r.set_proxy(proxy, 'https')
|
|
return r
|
|
|
|
for (feat, feat_info) in features.items():
|
|
includes = feat_info['include'] if 'include' in feat_info and feat_info['include'] else []
|
|
includes = [re.compile(p) for p in includes]
|
|
excludes = feat_info['exclude'] if 'exclude' in feat_info and feat_info['exclude'] else []
|
|
excludes = [re.compile(p) for p in excludes]
|
|
|
|
print(f'{feat} download begin')
|
|
download_filename = feat_info['zip_url'].split('/')[-1]
|
|
checksum_md5_response = urllib.request.urlopen(
|
|
req(feat_info['checksum_url']))
|
|
for line in checksum_md5_response.read().decode('utf-8').splitlines():
|
|
if line.split()[1] == download_filename:
|
|
checksum_md5 = line.split()[0]
|
|
filename, _headers = urllib.request.urlretrieve(feat_info['zip_url'],
|
|
download_filename)
|
|
md5 = hashlib.md5(open(filename, 'rb').read()).hexdigest()
|
|
if checksum_md5 != md5:
|
|
raise Exception(f'{feat} download failed')
|
|
print(f'{feat} download end. extract bein')
|
|
zip_file = zipfile.ZipFile(filename)
|
|
zip_list = zip_file.namelist()
|
|
for f in zip_list:
|
|
file_exclude = False
|
|
for p in excludes:
|
|
if p.match(f) is not None:
|
|
file_exclude = True
|
|
break
|
|
if file_exclude:
|
|
continue
|
|
|
|
file_include = False if includes else True
|
|
for p in includes:
|
|
if p.match(f) is not None:
|
|
file_include = True
|
|
break
|
|
if file_include:
|
|
print(f'extract file {f}')
|
|
zip_file.extract(f, res_dir)
|
|
zip_file.close()
|
|
os.remove(download_filename)
|
|
print(f'{feat} extract end')
|
|
|
|
|
|
def external_resources(flutter, args, res_dir):
|
|
features = parse_rc_features(args.feature)
|
|
if not features:
|
|
return
|
|
|
|
print(f'Build with features {list(features.keys())}')
|
|
if os.path.isdir(res_dir) and not os.path.islink(res_dir):
|
|
shutil.rmtree(res_dir)
|
|
elif os.path.exists(res_dir):
|
|
raise Exception(f'Find file {res_dir}, not a directory')
|
|
os.makedirs(res_dir, exist_ok=True)
|
|
download_extract_features(features, res_dir)
|
|
if flutter:
|
|
os.makedirs(flutter_build_dir_2, exist_ok=True)
|
|
for f in pathlib.Path(res_dir).iterdir():
|
|
print(f'{f}')
|
|
if f.is_file():
|
|
shutil.copy2(f, flutter_build_dir_2)
|
|
else:
|
|
shutil.copytree(f, f'{flutter_build_dir_2}{f.stem}')
|
|
|
|
|
|
def get_features(args):
|
|
features = ['inline'] if not args.flutter else []
|
|
if args.hwcodec:
|
|
features.append('hwcodec')
|
|
if args.vram:
|
|
features.append('vram')
|
|
if args.flutter:
|
|
features.append('flutter')
|
|
if args.unix_file_copy_paste:
|
|
features.append('unix-file-copy-paste')
|
|
if osx:
|
|
if args.screencapturekit:
|
|
features.append('screencapturekit')
|
|
print("features:", features)
|
|
return features
|
|
|
|
|
|
def generate_control_file(version):
|
|
control_file_path = "../res/DEBIAN/control"
|
|
system2('/bin/rm -rf %s' % control_file_path)
|
|
|
|
content = """Package: rustdesk
|
|
Section: net
|
|
Priority: optional
|
|
Version: %s
|
|
Architecture: %s
|
|
Maintainer: rustdesk <info@rustdesk.com>
|
|
Homepage: https://rustdesk.com
|
|
Depends: libgtk-3-0t64 | libgtk-3-0, libxcb-randr0, libxdo3 | libxdo4, libxfixes3, libxcb-shape0, libxcb-xfixes0, libasound2t64 | libasound2, libsystemd0, curl, libva2, libva-drm2, libva-x11-2, libgstreamer-plugins-base1.0-0, libpam0g, gstreamer1.0-pipewire%s
|
|
Recommends: libayatana-appindicator3-1
|
|
Description: A remote control software.
|
|
|
|
""" % (version, get_deb_arch(), get_deb_extra_depends())
|
|
file = open(control_file_path, "w")
|
|
file.write(content)
|
|
file.close()
|
|
|
|
|
|
def ffi_bindgen_function_refactor():
|
|
# workaround ffigen
|
|
system2(
|
|
'sed -i "s/ffi.NativeFunction<ffi.Bool Function(DartPort/ffi.NativeFunction<ffi.Uint8 Function(DartPort/g" flutter/lib/generated_bridge.dart')
|
|
|
|
|
|
def build_flutter_deb(version, features):
|
|
if not skip_cargo:
|
|
system2(f'cargo build --locked --features {features} --lib --release')
|
|
ffi_bindgen_function_refactor()
|
|
os.chdir('flutter')
|
|
system2('flutter build linux --release')
|
|
system2('mkdir -p tmpdeb/usr/bin/')
|
|
system2('mkdir -p tmpdeb/usr/share/rustdesk')
|
|
system2('mkdir -p tmpdeb/etc/rustdesk/')
|
|
system2('mkdir -p tmpdeb/etc/pam.d/')
|
|
system2('mkdir -p tmpdeb/usr/share/rustdesk/files/systemd/')
|
|
system2('mkdir -p tmpdeb/usr/share/icons/hicolor/256x256/apps/')
|
|
system2('mkdir -p tmpdeb/usr/share/icons/hicolor/scalable/apps/')
|
|
system2('mkdir -p tmpdeb/usr/share/applications/')
|
|
system2('mkdir -p tmpdeb/usr/share/polkit-1/actions')
|
|
system2('rm tmpdeb/usr/bin/rustdesk || true')
|
|
system2(
|
|
f'cp -r {flutter_build_dir}/* tmpdeb/usr/share/rustdesk/')
|
|
system2(
|
|
'cp ../res/rustdesk.service tmpdeb/usr/share/rustdesk/files/systemd/')
|
|
system2(
|
|
'cp ../res/128x128@2x.png tmpdeb/usr/share/icons/hicolor/256x256/apps/rustdesk.png')
|
|
system2(
|
|
'cp ../res/scalable.svg tmpdeb/usr/share/icons/hicolor/scalable/apps/rustdesk.svg')
|
|
system2(
|
|
'cp ../res/rustdesk.desktop tmpdeb/usr/share/applications/rustdesk.desktop')
|
|
system2(
|
|
'cp ../res/rustdesk-link.desktop tmpdeb/usr/share/applications/rustdesk-link.desktop')
|
|
system2(
|
|
'cp ../res/startwm.sh tmpdeb/etc/rustdesk/')
|
|
system2(
|
|
'cp ../res/xorg.conf tmpdeb/etc/rustdesk/')
|
|
system2(
|
|
'cp ../res/pam.d/rustdesk.debian tmpdeb/etc/pam.d/rustdesk')
|
|
system2(
|
|
"echo \"#!/bin/sh\" >> tmpdeb/usr/share/rustdesk/files/polkit && chmod a+x tmpdeb/usr/share/rustdesk/files/polkit")
|
|
|
|
system2('mkdir -p tmpdeb/DEBIAN')
|
|
generate_control_file(version)
|
|
system2('cp -a ../res/DEBIAN/* tmpdeb/DEBIAN/')
|
|
md5_file_folder("tmpdeb/")
|
|
system2('dpkg-deb -b tmpdeb rustdesk.deb;')
|
|
|
|
system2('/bin/rm -rf tmpdeb/')
|
|
system2('/bin/rm -rf ../res/DEBIAN/control')
|
|
os.rename('rustdesk.deb', '../rustdesk-%s.deb' % version)
|
|
os.chdir("..")
|
|
|
|
|
|
def build_deb_from_folder(version, binary_folder):
|
|
os.chdir('flutter')
|
|
system2('mkdir -p tmpdeb/usr/bin/')
|
|
system2('mkdir -p tmpdeb/usr/share/rustdesk')
|
|
system2('mkdir -p tmpdeb/usr/share/rustdesk/files/systemd/')
|
|
system2('mkdir -p tmpdeb/usr/share/icons/hicolor/256x256/apps/')
|
|
system2('mkdir -p tmpdeb/usr/share/icons/hicolor/scalable/apps/')
|
|
system2('mkdir -p tmpdeb/usr/share/applications/')
|
|
system2('mkdir -p tmpdeb/usr/share/polkit-1/actions')
|
|
system2('rm tmpdeb/usr/bin/rustdesk || true')
|
|
system2(
|
|
f'cp -r ../{binary_folder}/* tmpdeb/usr/share/rustdesk/')
|
|
system2(
|
|
'cp ../res/rustdesk.service tmpdeb/usr/share/rustdesk/files/systemd/')
|
|
system2(
|
|
'cp ../res/128x128@2x.png tmpdeb/usr/share/icons/hicolor/256x256/apps/rustdesk.png')
|
|
system2(
|
|
'cp ../res/scalable.svg tmpdeb/usr/share/icons/hicolor/scalable/apps/rustdesk.svg')
|
|
system2(
|
|
'cp ../res/rustdesk.desktop tmpdeb/usr/share/applications/rustdesk.desktop')
|
|
system2(
|
|
'cp ../res/rustdesk-link.desktop tmpdeb/usr/share/applications/rustdesk-link.desktop')
|
|
system2(
|
|
"echo \"#!/bin/sh\" >> tmpdeb/usr/share/rustdesk/files/polkit && chmod a+x tmpdeb/usr/share/rustdesk/files/polkit")
|
|
|
|
system2('mkdir -p tmpdeb/DEBIAN')
|
|
generate_control_file(version)
|
|
system2('cp -a ../res/DEBIAN/* tmpdeb/DEBIAN/')
|
|
md5_file_folder("tmpdeb/")
|
|
system2('dpkg-deb -b tmpdeb rustdesk.deb;')
|
|
|
|
system2('/bin/rm -rf tmpdeb/')
|
|
system2('/bin/rm -rf ../res/DEBIAN/control')
|
|
os.rename('rustdesk.deb', '../rustdesk-%s.deb' % version)
|
|
os.chdir("..")
|
|
|
|
|
|
def build_flutter_dmg(version, features):
|
|
if not skip_cargo:
|
|
# set minimum osx build target, now is 10.14, which is the same as the flutter xcode project
|
|
system2(
|
|
f'MACOSX_DEPLOYMENT_TARGET=10.14 cargo build --locked --features {features} --release')
|
|
# copy dylib
|
|
system2(
|
|
"cp target/release/liblibrustdesk.dylib target/release/librustdesk.dylib")
|
|
os.chdir('flutter')
|
|
system2('flutter build macos --release')
|
|
system2('cp -rf ../target/release/service ./build/macos/Build/Products/Release/RustDesk.app/Contents/MacOS/')
|
|
'''
|
|
system2(
|
|
"create-dmg --volname \"RustDesk Installer\" --window-pos 200 120 --window-size 800 400 --icon-size 100 --app-drop-link 600 185 --icon RustDesk.app 200 190 --hide-extension RustDesk.app rustdesk.dmg ./build/macos/Build/Products/Release/RustDesk.app")
|
|
os.rename("rustdesk.dmg", f"../rustdesk-{version}.dmg")
|
|
'''
|
|
os.chdir("..")
|
|
|
|
|
|
def build_flutter_arch_manjaro(version, features):
|
|
if not skip_cargo:
|
|
system2(f'cargo build --locked --features {features} --lib --release')
|
|
ffi_bindgen_function_refactor()
|
|
os.chdir('flutter')
|
|
system2('flutter build linux --release')
|
|
system2(f'strip {flutter_build_dir}/lib/librustdesk.so')
|
|
os.chdir('../res')
|
|
system2('HBB=`pwd`/.. FLUTTER=1 makepkg -f')
|
|
|
|
|
|
def build_flutter_windows(version, features, skip_portable_pack):
|
|
if not skip_cargo:
|
|
system2(f'cargo build --locked --features {features} --lib --release')
|
|
if not os.path.exists("target/release/librustdesk.dll"):
|
|
print("cargo build failed, please check rust source code.")
|
|
exit(-1)
|
|
os.chdir('flutter')
|
|
system2('flutter build windows --release')
|
|
os.chdir('..')
|
|
shutil.copy2('target/release/deps/dylib_virtual_display.dll',
|
|
flutter_build_dir_2)
|
|
if skip_portable_pack:
|
|
return
|
|
os.chdir('libs/portable')
|
|
system2('pip3 install -r requirements.txt')
|
|
system2(
|
|
f'python3 ./generate.py -f ../../{flutter_build_dir_2} -o . -e ../../{flutter_build_dir_2}/rustdesk.exe')
|
|
os.chdir('../..')
|
|
if os.path.exists('./rustdesk_portable.exe'):
|
|
os.replace('./target/release/rustdesk-portable-packer.exe',
|
|
'./rustdesk_portable.exe')
|
|
else:
|
|
os.rename('./target/release/rustdesk-portable-packer.exe',
|
|
'./rustdesk_portable.exe')
|
|
print(
|
|
f'output location: {os.path.abspath(os.curdir)}/rustdesk_portable.exe')
|
|
os.rename('./rustdesk_portable.exe', f'./rustdesk-{version}-install.exe')
|
|
print(
|
|
f'output location: {os.path.abspath(os.curdir)}/rustdesk-{version}-install.exe')
|
|
|
|
|
|
def main():
|
|
global skip_cargo
|
|
parser = make_parser()
|
|
args = parser.parse_args()
|
|
|
|
if os.path.exists(exe_path):
|
|
os.unlink(exe_path)
|
|
if os.path.isfile('/usr/bin/pacman'):
|
|
system2('git checkout src/ui/common.tis')
|
|
version = get_version()
|
|
features = ','.join(get_features(args))
|
|
flutter = args.flutter
|
|
if not flutter:
|
|
system2('python3 res/inline-sciter.py')
|
|
print(args.skip_cargo)
|
|
if args.skip_cargo:
|
|
skip_cargo = True
|
|
portable = args.portable
|
|
package = args.package
|
|
if package:
|
|
build_deb_from_folder(version, package)
|
|
return
|
|
res_dir = 'resources'
|
|
external_resources(flutter, args, res_dir)
|
|
if windows:
|
|
# build virtual display dynamic library
|
|
os.chdir('libs/virtual_display/dylib')
|
|
system2('cargo build --locked --release')
|
|
os.chdir('../../..')
|
|
|
|
if flutter:
|
|
build_flutter_windows(version, features, args.skip_portable_pack)
|
|
return
|
|
system2('cargo build --locked --release --features ' + features)
|
|
# system2('upx.exe target/release/rustdesk.exe')
|
|
system2('mv target/release/rustdesk.exe target/release/RustDesk.exe')
|
|
pa = os.environ.get('P')
|
|
if pa:
|
|
# https://certera.com/kb/tutorial-guide-for-safenet-authentication-client-for-code-signing/
|
|
system2(
|
|
f'signtool sign /a /v /p {pa} /debug /f .\\cert.pfx /t http://timestamp.digicert.com '
|
|
'target\\release\\rustdesk.exe')
|
|
else:
|
|
print('Not signed')
|
|
system2(
|
|
f'cp -rf target/release/RustDesk.exe {res_dir}')
|
|
os.chdir('libs/portable')
|
|
system2('pip3 install -r requirements.txt')
|
|
system2(
|
|
f'python3 ./generate.py -f ../../{res_dir} -o . -e ../../{res_dir}/rustdesk-{version}-win7-install.exe')
|
|
system2(f'mv ../../{res_dir}/rustdesk-{version}-win7-install.exe ../..')
|
|
elif os.path.isfile('/usr/bin/pacman'):
|
|
# pacman -S -needed base-devel
|
|
system2("sed -i 's/pkgver=.*/pkgver=%s/g' res/PKGBUILD" % version)
|
|
if flutter:
|
|
build_flutter_arch_manjaro(version, features)
|
|
else:
|
|
system2('cargo build --locked --release --features ' + features)
|
|
system2('git checkout src/ui/common.tis')
|
|
system2('strip target/release/rustdesk')
|
|
system2('ln -s res/pacman_install && ln -s res/PKGBUILD')
|
|
system2('HBB=`pwd` makepkg -f')
|
|
system2('mv rustdesk-%s-0-x86_64.pkg.tar.zst rustdesk-%s-manjaro-arch.pkg.tar.zst' % (
|
|
version, version))
|
|
# pacman -U ./rustdesk.pkg.tar.zst
|
|
elif os.path.isfile('/usr/bin/yum'):
|
|
system2('cargo build --locked --release --features ' + features)
|
|
system2('strip target/release/rustdesk')
|
|
system2(
|
|
"sed -i 's/Version: .*/Version: %s/g' res/rpm.spec" % version)
|
|
system2('HBB=`pwd` rpmbuild -ba res/rpm.spec')
|
|
system2(
|
|
'mv $HOME/rpmbuild/RPMS/x86_64/rustdesk-%s-0.x86_64.rpm ./rustdesk-%s-fedora28-centos8.rpm' % (
|
|
version, version))
|
|
# yum localinstall rustdesk.rpm
|
|
elif os.path.isfile('/usr/bin/zypper'):
|
|
system2('cargo build --locked --release --features ' + features)
|
|
system2('strip target/release/rustdesk')
|
|
system2(
|
|
"sed -i 's/Version: .*/Version: %s/g' res/rpm-suse.spec" % version)
|
|
system2('HBB=`pwd` rpmbuild -ba res/rpm-suse.spec')
|
|
system2(
|
|
'mv $HOME/rpmbuild/RPMS/x86_64/rustdesk-%s-0.x86_64.rpm ./rustdesk-%s-suse.rpm' % (
|
|
version, version))
|
|
# yum localinstall rustdesk.rpm
|
|
else:
|
|
if flutter:
|
|
if osx:
|
|
build_flutter_dmg(version, features)
|
|
pass
|
|
else:
|
|
# system2(
|
|
# 'mv target/release/bundle/deb/rustdesk*.deb ./flutter/rustdesk.deb')
|
|
build_flutter_deb(version, features)
|
|
else:
|
|
system2('cargo --locked bundle --release --features ' + features)
|
|
if osx:
|
|
system2(
|
|
'strip target/release/bundle/osx/RustDesk.app/Contents/MacOS/rustdesk')
|
|
system2(
|
|
'cp libsciter.dylib target/release/bundle/osx/RustDesk.app/Contents/MacOS/')
|
|
# https://github.com/sindresorhus/create-dmg
|
|
system2('/bin/rm -rf *.dmg')
|
|
pa = os.environ.get('P')
|
|
if pa:
|
|
system2('''
|
|
# buggy: rcodesign sign ... path/*, have to sign one by one
|
|
# install rcodesign via cargo install apple-codesign
|
|
#rcodesign sign --p12-file ~/.p12/rustdesk-developer-id.p12 --p12-password-file ~/.p12/.cert-pass --code-signature-flags runtime ./target/release/bundle/osx/RustDesk.app/Contents/MacOS/rustdesk
|
|
#rcodesign sign --p12-file ~/.p12/rustdesk-developer-id.p12 --p12-password-file ~/.p12/.cert-pass --code-signature-flags runtime ./target/release/bundle/osx/RustDesk.app/Contents/MacOS/libsciter.dylib
|
|
#rcodesign sign --p12-file ~/.p12/rustdesk-developer-id.p12 --p12-password-file ~/.p12/.cert-pass --code-signature-flags runtime ./target/release/bundle/osx/RustDesk.app
|
|
# goto "Keychain Access" -> "My Certificates" for below id which starts with "Developer ID Application:"
|
|
codesign -s "Developer ID Application: {0}" --force --options runtime ./target/release/bundle/osx/RustDesk.app/Contents/MacOS/*
|
|
codesign -s "Developer ID Application: {0}" --force --options runtime ./target/release/bundle/osx/RustDesk.app
|
|
'''.format(pa))
|
|
system2(
|
|
'create-dmg "RustDesk %s.dmg" "target/release/bundle/osx/RustDesk.app"' % version)
|
|
os.rename('RustDesk %s.dmg' %
|
|
version, 'rustdesk-%s.dmg' % version)
|
|
if pa:
|
|
system2('''
|
|
# https://pyoxidizer.readthedocs.io/en/apple-codesign-0.14.0/apple_codesign.html
|
|
# https://pyoxidizer.readthedocs.io/en/stable/tugger_code_signing.html
|
|
# https://developer.apple.com/developer-id/
|
|
# goto xcode and login with apple id, manager certificates (Developer ID Application and/or Developer ID Installer) online there (only download and double click (install) cer file can not export p12 because no private key)
|
|
#rcodesign sign --p12-file ~/.p12/rustdesk-developer-id.p12 --p12-password-file ~/.p12/.cert-pass --code-signature-flags runtime ./rustdesk-{1}.dmg
|
|
codesign -s "Developer ID Application: {0}" --force --options runtime ./rustdesk-{1}.dmg
|
|
# https://appstoreconnect.apple.com/access/api
|
|
# https://gregoryszorc.com/docs/apple-codesign/stable/apple_codesign_getting_started.html#apple-codesign-app-store-connect-api-key
|
|
# p8 file is generated when you generate api key (can download only once)
|
|
rcodesign notary-submit --api-key-path ../.p12/api-key.json --staple rustdesk-{1}.dmg
|
|
# verify: spctl -a -t exec -v /Applications/RustDesk.app
|
|
'''.format(pa, version))
|
|
else:
|
|
print('Not signed')
|
|
else:
|
|
# build deb package
|
|
system2(
|
|
'mv target/release/bundle/deb/rustdesk*.deb ./rustdesk.deb')
|
|
system2('dpkg-deb -R rustdesk.deb tmpdeb')
|
|
system2('mkdir -p tmpdeb/usr/share/rustdesk/files/systemd/')
|
|
system2('mkdir -p tmpdeb/usr/share/icons/hicolor/256x256/apps/')
|
|
system2('mkdir -p tmpdeb/usr/share/icons/hicolor/scalable/apps/')
|
|
system2(
|
|
'cp res/rustdesk.service tmpdeb/usr/share/rustdesk/files/systemd/')
|
|
system2(
|
|
'cp res/128x128@2x.png tmpdeb/usr/share/icons/hicolor/256x256/apps/rustdesk.png')
|
|
system2(
|
|
'cp res/scalable.svg tmpdeb/usr/share/icons/hicolor/scalable/apps/rustdesk.svg')
|
|
system2(
|
|
'cp res/rustdesk.desktop tmpdeb/usr/share/applications/rustdesk.desktop')
|
|
system2(
|
|
'cp res/rustdesk-link.desktop tmpdeb/usr/share/applications/rustdesk-link.desktop')
|
|
os.system('mkdir -p tmpdeb/etc/rustdesk/')
|
|
os.system('cp -a res/startwm.sh tmpdeb/etc/rustdesk/')
|
|
os.system('mkdir -p tmpdeb/etc/X11/rustdesk/')
|
|
os.system('cp res/xorg.conf tmpdeb/etc/X11/rustdesk/')
|
|
os.system('cp -a DEBIAN/* tmpdeb/DEBIAN/')
|
|
os.system('mkdir -p tmpdeb/etc/pam.d/')
|
|
os.system('cp pam.d/rustdesk.debian tmpdeb/etc/pam.d/rustdesk')
|
|
system2('strip tmpdeb/usr/bin/rustdesk')
|
|
system2('mkdir -p tmpdeb/usr/share/rustdesk')
|
|
system2('mv tmpdeb/usr/bin/rustdesk tmpdeb/usr/share/rustdesk/')
|
|
system2('cp libsciter-gtk.so tmpdeb/usr/share/rustdesk/')
|
|
md5_file_folder("tmpdeb/")
|
|
system2('dpkg-deb -b tmpdeb rustdesk.deb; /bin/rm -rf tmpdeb/')
|
|
os.rename('rustdesk.deb', 'rustdesk-%s.deb' % version)
|
|
|
|
|
|
def md5_file(fn):
|
|
md5 = hashlib.md5(open('tmpdeb/' + fn, 'rb').read()).hexdigest()
|
|
system2('echo "%s /%s" >> tmpdeb/DEBIAN/md5sums' % (md5, fn))
|
|
|
|
def md5_file_folder(base_dir):
|
|
base_path = Path(base_dir)
|
|
for file in base_path.rglob('*'):
|
|
if file.is_file() and 'DEBIAN' not in file.parts:
|
|
relative_path = file.relative_to(base_path)
|
|
md5_file(str(relative_path))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|