123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634 |
- #!/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/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, libvdpau-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
- )
- 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
- 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')
- 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-0, libxcb-randr0, libxdo3, libxfixes3, libxcb-shape0, libxcb-xfixes0, libasound2, libsystemd0, curl, libva-drm2, libva-x11-2, libvdpau1, 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 --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/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/lib/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('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/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/lib/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('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, skip_portable_pack):
- 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)
- 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 --release')
- os.chdir('../../..')
- if flutter:
- build_flutter_windows(version, features, args.skip_portable_pack)
- 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:
- # 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('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')
- 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/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()
|