018f551d13
because it occurs since fedora 33, and since fedora 34, it was installed with the system by default
619 lines
26 KiB
Python
Executable File
619 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
|
|
|
|
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/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_arch() -> str:
|
|
custom_arch = os.environ.get("ARCH")
|
|
if custom_arch is None:
|
|
return "amd64"
|
|
return custom_arch
|
|
|
|
def system2(cmd):
|
|
err = os.system(cmd)
|
|
if err != 0:
|
|
print(f"Error occurred when executing: {cmd}. Exiting.")
|
|
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 = {
|
|
'IddDriver': {
|
|
'platform': ['windows'],
|
|
'zip_url': 'https://github.com/fufesou/RustDeskIddDriver/releases/download/v0.3/RustDeskIddDriver_x64.zip',
|
|
'checksum_url': 'https://github.com/fufesou/RustDeskIddDriver/releases/download/v0.3/checksum_md5',
|
|
'exclude': ['README.md', 'certmgr.exe', 'install_cert_runas_admin.bat', 'RustDeskIddApp.exe'],
|
|
},
|
|
'PrivacyMode': {
|
|
'platform': ['windows'],
|
|
'zip_url': 'https://github.com/fufesou/RustDeskTempTopMostWindow/releases/download/v0.1'
|
|
'/TempTopMostWindow_x64_pic_en.zip',
|
|
'checksum_url': 'https://github.com/fufesou/RustDeskTempTopMostWindow/releases/download/v0.1/checksum_md5',
|
|
'include': ['WindowInjection.dll'],
|
|
}
|
|
}
|
|
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:
|
|
# force add PrivacyMode
|
|
feature.append('PrivacyMode')
|
|
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: IddDriver, PrivacyMode. 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, libvdpau-dev.')
|
|
)
|
|
parser.add_argument(
|
|
'--portable',
|
|
action='store_true',
|
|
help='Build windows portable'
|
|
)
|
|
parser.add_argument(
|
|
'--flatpak',
|
|
action='store_true',
|
|
help='Build rustdesk libs with the flatpak feature enabled'
|
|
)
|
|
parser.add_argument(
|
|
'--appimage',
|
|
action='store_true',
|
|
help='Build rustdesk libs with the appimage feature enabled'
|
|
)
|
|
parser.add_argument(
|
|
'--skip-cargo',
|
|
action='store_true',
|
|
help='Skip cargo build process, only flutter version + Linux supported currently'
|
|
)
|
|
parser.add_argument(
|
|
"--package",
|
|
type=str
|
|
)
|
|
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 . && 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
|
|
vcpkg/vcpkg install libvpx libyuv opus
|
|
popd
|
|
# build rustdesk
|
|
./build.py --flutter --hwcodec
|
|
''')
|
|
system2("chmod +x /tmp/build.sh")
|
|
system2("bash /tmp/build.sh")
|
|
|
|
|
|
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 windows:
|
|
features.append('virtual_display_driver')
|
|
if args.hwcodec:
|
|
features.append('hwcodec')
|
|
if args.flutter:
|
|
features.append('flutter')
|
|
features.append('flutter_texture_render')
|
|
if args.flatpak:
|
|
features.append('flatpak')
|
|
if args.appimage:
|
|
features.append('appimage')
|
|
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
|
|
Version: %s
|
|
Architecture: %s
|
|
Maintainer: rustdesk <info@rustdesk.com>
|
|
Homepage: https://rustdesk.com
|
|
Depends: libgtk-3-0, libxcb-randr0, libxdo3, libxfixes3, libxcb-shape0, libxcb-xfixes0, libasound2, libsystemd0, curl, libva-drm2, libva-x11-2, libvdpau1, libgstreamer-plugins-base1.0-0, libpam0g, libappindicator3-1, gstreamer1.0-pipewire
|
|
Description: A remote control software.
|
|
|
|
""" % (version, get_arch())
|
|
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 --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/lib/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/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/lib/rustdesk/')
|
|
system2(
|
|
'cp ../res/rustdesk.service tmpdeb/usr/share/rustdesk/files/systemd/')
|
|
system2(
|
|
'cp ../res/128x128@2x.png tmpdeb/usr/share/rustdesk/files/rustdesk.png')
|
|
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/com.rustdesk.RustDesk.policy tmpdeb/usr/share/polkit-1/actions/')
|
|
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('usr/share/rustdesk/files/systemd/rustdesk.service')
|
|
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/lib/rustdesk')
|
|
system2('mkdir -p tmpdeb/usr/share/rustdesk/files/systemd/')
|
|
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/lib/rustdesk/')
|
|
system2(
|
|
'cp ../res/rustdesk.service tmpdeb/usr/share/rustdesk/files/systemd/')
|
|
system2(
|
|
'cp ../res/128x128@2x.png tmpdeb/usr/share/rustdesk/files/rustdesk.png')
|
|
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/com.rustdesk.RustDesk.policy tmpdeb/usr/share/polkit-1/actions/')
|
|
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('usr/share/rustdesk/files/systemd/rustdesk.service')
|
|
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 --features {features} --lib --release')
|
|
# copy dylib
|
|
system2(
|
|
"cp target/release/liblibrustdesk.dylib target/release/librustdesk.dylib")
|
|
os.chdir('flutter')
|
|
system2('flutter build macos --release')
|
|
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 --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):
|
|
if not skip_cargo:
|
|
system2(f'cargo build --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)
|
|
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 --release')
|
|
os.chdir('../../..')
|
|
|
|
if flutter:
|
|
build_flutter_windows(version, features)
|
|
return
|
|
system2('cargo build --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:
|
|
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('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 --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 --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 --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 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')
|
|
plist = "target/release/bundle/osx/RustDesk.app/Contents/Info.plist"
|
|
txt = open(plist).read()
|
|
with open(plist, "wt") as fh:
|
|
fh.write(txt.replace("</dict>", """
|
|
<key>LSUIElement</key>
|
|
<string>1</string>
|
|
</dict>"""))
|
|
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 target/release/bundle/osx/RustDesk.app')
|
|
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:
|
|
# buid 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(
|
|
'cp res/rustdesk.service tmpdeb/usr/share/rustdesk/files/systemd/')
|
|
system2(
|
|
'cp res/128x128@2x.png tmpdeb/usr/share/rustdesk/files/rustdesk.png')
|
|
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/lib/rustdesk')
|
|
system2('mv tmpdeb/usr/bin/rustdesk tmpdeb/usr/lib/rustdesk/')
|
|
system2('cp libsciter-gtk.so tmpdeb/usr/lib/rustdesk/')
|
|
md5_file('usr/share/rustdesk/files/systemd/rustdesk.service')
|
|
md5_file('etc/rustdesk/startwm.sh')
|
|
md5_file('etc/X11/rustdesk/xorg.conf')
|
|
md5_file('etc/pam.d/rustdesk')
|
|
md5_file('usr/lib/rustdesk/libsciter-gtk.so')
|
|
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))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|