2022-04-18 10:37:35 +03:00
#!/usr/bin/env python3
import os
import platform
2022-05-28 13:42:38 +03:00
import zipfile
import urllib . request
import shutil
2022-04-18 10:37:35 +03:00
import hashlib
2022-05-28 13:42:38 +03:00
import argparse
2022-04-18 10:37:35 +03:00
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
def get_version ( ) :
with open ( " Cargo.toml " ) as fh :
for line in fh :
if line . startswith ( " version " ) :
return line . replace ( " version " , " " ) . replace ( " = " , " " ) . replace ( ' " ' , ' ' ) . strip ( )
return ' '
2022-07-22 07:41:49 +03:00
def parse_rc_features ( feature ) :
2022-05-28 13:42:38 +03:00
available_features = {
' IddDriver ' : {
' zip_url ' : ' https://github.com/fufesou/RustDeskIddDriver/releases/download/v0.1/RustDeskIddDriver_x64.zip ' ,
' checksum_url ' : ' https://github.com/fufesou/RustDeskIddDriver/releases/download/v0.1 '
' /RustDeskIddDriver_x64.zip.checksum_md5 ' ,
} ,
' PrivacyMode ' : {
' zip_url ' : ' https://github.com/fufesou/RustDeskTempTopMostWindow/releases/download/v0.1 '
' /TempTopMostWindow_x64.zip ' ,
' checksum_url ' : ' https://github.com/fufesou/RustDeskTempTopMostWindow/releases/download/v0.1 '
' /TempTopMostWindow_x64.zip.checksum_md5 ' ,
}
}
apply_features = { }
if not feature :
return apply_features
elif isinstance ( feature , str ) and feature . upper ( ) == ' ALL ' :
return available_features
elif isinstance ( feature , list ) :
for feat in feature :
if isinstance ( feat , str ) and feat . upper ( ) == ' ALL ' :
return available_features
if feat in available_features :
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. ' )
2022-06-14 10:01:07 +03:00
parser . add_argument (
' --hwcodec ' ,
action = ' store_true ' ,
help = ' Enable feature hwcodec, windows only. '
)
2022-05-28 13:42:38 +03:00
return parser
def download_extract_features ( features , res_dir ) :
for ( feat , feat_info ) in features . items ( ) :
print ( f ' { feat } download begin ' )
checksum_md5_response = urllib . request . urlopen ( feat_info [ ' checksum_url ' ] )
checksum_md5 = checksum_md5_response . read ( ) . decode ( ' utf-8 ' ) . split ( ) [ 0 ]
download_filename = feat_info [ ' zip_url ' ] . split ( ' / ' ) [ - 1 ]
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 :
zip_file . extract ( f , res_dir )
zip_file . close ( )
os . remove ( download_filename )
print ( f ' { feat } extract end ' )
2022-07-22 04:14:18 +03:00
def get_rc_features ( args ) :
2022-07-22 07:41:49 +03:00
features = parse_rc_features ( args . feature )
2022-06-14 10:01:07 +03:00
if features :
2022-05-28 13:42:38 +03:00
print ( f ' Build with features { list ( features . keys ( ) ) } ' )
res_dir = ' resources '
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 )
2022-07-22 04:14:18 +03:00
return [ ' with_rc ' ] if features else [ ]
2022-05-28 13:42:38 +03:00
2022-07-22 04:14:18 +03:00
def get_features ( args ) :
features = [ ' inline ' ]
if windows :
features . extend ( get_rc_features ( args ) )
if args . hwcodec :
features . append ( ' hwcodec ' )
print ( " features: " , features )
return features
2022-05-28 13:42:38 +03:00
2022-04-18 10:37:35 +03:00
def main ( ) :
2022-05-28 13:42:38 +03:00
parser = make_parser ( )
args = parser . parse_args ( )
2022-04-18 10:37:35 +03:00
os . system ( " cp Cargo.toml Cargo.toml.bk " )
os . system ( " cp src/main.rs src/main.rs.bk " )
if windows :
txt = open ( ' src/main.rs ' , encoding = ' utf8 ' ) . read ( )
with open ( ' src/main.rs ' , ' wt ' , encoding = ' utf8 ' ) as fh :
fh . write ( txt . replace (
' //#![windows_subsystem ' , ' #![windows_subsystem ' ) )
if os . path . exists ( exe_path ) :
os . unlink ( exe_path )
os . system ( ' python3 inline-sciter.py ' )
if os . path . isfile ( ' /usr/bin/pacman ' ) :
os . system ( ' git checkout src/ui/common.tis ' )
version = get_version ( )
2022-07-22 04:14:18 +03:00
features = " , " . join ( get_features ( args ) )
2022-04-18 10:37:35 +03:00
if windows :
2022-07-22 04:14:18 +03:00
os . system ( ' cargo build --release --features ' + features )
2022-04-18 10:37:35 +03:00
# os.system('upx.exe target/release/rustdesk.exe')
os . system ( ' mv target/release/rustdesk.exe target/release/RustDesk.exe ' )
2022-05-01 18:39:03 +03:00
pa = os . environ . get ( ' P ' )
if pa :
2022-05-28 13:42:38 +03:00
os . system ( f ' signtool sign /a /v /p { pa } /debug /f . \\ cert.pfx /t http://timestamp.digicert.com '
' target \\ release \\ rustdesk.exe ' )
2022-05-01 18:39:03 +03:00
else :
2022-05-28 13:42:38 +03:00
print ( ' Not signed ' )
2022-06-12 10:14:21 +03:00
os . system ( f ' cp -rf target/release/RustDesk.exe rustdesk- { version } -setdown.exe ' )
2022-05-23 06:59:56 +03:00
elif os . path . isfile ( ' /usr/bin/pacman ' ) :
2022-07-22 04:14:18 +03:00
os . system ( ' cargo build --release --features ' + features )
2022-05-23 06:59:56 +03:00
os . system ( ' git checkout src/ui/common.tis ' )
os . system ( ' strip target/release/rustdesk ' )
2022-05-28 13:42:38 +03:00
os . system ( " sed -i ' s/pkgver=.*/pkgver= %s /g ' PKGBUILD " % version )
2022-05-23 06:59:56 +03:00
# pacman -S -needed base-devel
os . system ( ' HBB=`pwd` makepkg -f ' )
2022-05-28 13:42:38 +03:00
os . system ( ' mv rustdesk- %s -0-x86_64.pkg.tar.zst rustdesk- %s -manjaro-arch.pkg.tar.zst ' % ( version , version ) )
2022-05-23 06:59:56 +03:00
# pacman -U ./rustdesk.pkg.tar.zst
elif os . path . isfile ( ' /usr/bin/yum ' ) :
2022-07-22 04:14:18 +03:00
os . system ( ' cargo build --release --features ' + features )
2022-05-23 06:59:56 +03:00
os . system ( ' strip target/release/rustdesk ' )
2022-05-28 13:42:38 +03:00
os . system ( " sed -i ' s/Version: .*/Version: %s /g ' rpm.spec " % version )
2022-05-23 06:59:56 +03:00
os . system ( ' HBB=`pwd` rpmbuild -ba rpm.spec ' )
2022-05-28 13:42:38 +03:00
os . system ( ' mv $HOME/rpmbuild/RPMS/x86_64/rustdesk- %s -0.x86_64.rpm ./rustdesk- %s -fedora28-centos8.rpm ' % (
version , version ) )
2022-05-23 06:59:56 +03:00
# yum localinstall rustdesk.rpm
elif os . path . isfile ( ' /usr/bin/zypper ' ) :
2022-07-22 04:14:18 +03:00
os . system ( ' cargo build --release --features ' + features )
2022-05-23 06:59:56 +03:00
os . system ( ' strip target/release/rustdesk ' )
2022-05-28 13:42:38 +03:00
os . system ( " sed -i ' s/Version: .*/Version: %s /g ' rpm-suse.spec " % version )
2022-05-23 06:59:56 +03:00
os . system ( ' HBB=`pwd` rpmbuild -ba rpm-suse.spec ' )
2022-05-28 13:42:38 +03:00
os . system ( ' mv $HOME/rpmbuild/RPMS/x86_64/rustdesk- %s -0.x86_64.rpm ./rustdesk- %s -suse.rpm ' % ( version , version ) )
2022-05-23 06:59:56 +03:00
# yum localinstall rustdesk.rpm
2022-04-18 10:37:35 +03:00
else :
2022-07-22 04:14:18 +03:00
os . system ( ' cargo bundle --release --features ' + features )
2022-04-18 10:37:35 +03:00
if osx :
os . system (
' strip target/release/bundle/osx/RustDesk.app/Contents/MacOS/rustdesk ' )
os . system (
' cp libsciter.dylib target/release/bundle/osx/RustDesk.app/Contents/MacOS/ ' )
# https://github.com/sindresorhus/create-dmg
os . system ( ' /bin/rm -rf *.dmg ' )
2022-05-01 18:39:03 +03:00
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> " , """
2022-05-28 13:42:38 +03:00
< key > LSUIElement < / key >
< string > 1 < / string >
2022-05-01 18:39:03 +03:00
< / dict > """ ))
pa = os . environ . get ( ' P ' )
if pa :
2022-05-28 13:42:38 +03:00
os . system ( '''
2022-05-01 23:41:45 +03:00
# buggy: rcodesign sign ... path/*, have to sign one by one
#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
2022-05-01 18:39:03 +03:00
# goto "Keychain Access" -> "My Certificates" for below id which starts with "Developer ID Application:"
2022-05-01 22:03:15 +03:00
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))
2022-04-18 10:37:35 +03:00
os . system ( ' create-dmg target/release/bundle/osx/RustDesk.app ' )
2022-05-28 13:42:38 +03:00
os . rename ( ' RustDesk %s .dmg ' % version , ' rustdesk- %s .dmg ' % version )
2022-05-01 18:39:03 +03:00
if pa :
2022-05-28 13:42:38 +03:00
os . system ( '''
2022-05-01 23:41:45 +03:00
#rcodesign sign --p12-file ~/.p12/rustdesk-developer-id.p12 --p12-password-file ~/.p12/.cert-pass --code-signature-flags runtime ./rustdesk-{1}.dmg
2022-05-01 22:03:15 +03:00
codesign - s " Developer ID Application: {0} " - - force - - options runtime . / rustdesk - { 1 } . dmg
2022-05-01 18:39:03 +03:00
# https://pyoxidizer.readthedocs.io/en/latest/apple_codesign_rcodesign.html
2022-05-01 22:03:15 +03:00
rcodesign notarize - - api - issuer 69 a6de7d - 2907 - 47e3 - e053 - 5 b8c7c11a4d1 - - api - key 9 JBRHG3JHT - - staple . / rustdesk - { 1 } . dmg
2022-05-01 18:39:03 +03:00
# verify: spctl -a -t exec -v /Applications/RustDesk.app
2022-05-01 22:03:15 +03:00
''' .format(pa, version))
2022-05-01 18:39:03 +03:00
else :
2022-05-28 13:42:38 +03:00
print ( ' Not signed ' )
2022-04-18 10:37:35 +03:00
else :
os . system ( ' mv target/release/bundle/deb/rustdesk*.deb ./rustdesk.deb ' )
os . system ( ' dpkg-deb -R rustdesk.deb tmpdeb ' )
os . system ( ' mkdir -p tmpdeb/usr/share/rustdesk/files/systemd/ ' )
os . system (
' cp rustdesk.service tmpdeb/usr/share/rustdesk/files/systemd/ ' )
2022-07-06 20:27:21 +03:00
os . system (
' cp rustdesk.service.user tmpdeb/usr/share/rustdesk/files/systemd/ ' )
2022-04-18 10:37:35 +03:00
os . system ( ' cp pynput_service.py tmpdeb/usr/share/rustdesk/files/ ' )
2022-07-06 20:27:21 +03:00
os . system ( ' cp -a DEBIAN/* tmpdeb/DEBIAN/ ' )
2022-04-18 10:37:35 +03:00
os . system ( ' strip tmpdeb/usr/bin/rustdesk ' )
os . system ( ' mkdir -p tmpdeb/usr/lib/rustdesk ' )
os . system ( ' cp libsciter-gtk.so tmpdeb/usr/lib/rustdesk/ ' )
md5_file ( ' usr/share/rustdesk/files/systemd/rustdesk.service ' )
2022-07-06 20:27:21 +03:00
md5_file ( ' usr/share/rustdesk/files/systemd/rustdesk.service.user ' )
2022-04-18 10:37:35 +03:00
md5_file ( ' usr/share/rustdesk/files/pynput_service.py ' )
md5_file ( ' usr/lib/rustdesk/libsciter-gtk.so ' )
os . system ( ' dpkg-deb -b tmpdeb rustdesk.deb; /bin/rm -rf tmpdeb/ ' )
2022-05-28 13:42:38 +03:00
os . rename ( ' rustdesk.deb ' , ' rustdesk- %s .deb ' % version )
2022-04-18 10:37:35 +03:00
os . system ( " mv Cargo.toml.bk Cargo.toml " )
os . system ( " mv src/main.rs.bk src/main.rs " )
def md5_file ( fn ) :
md5 = hashlib . md5 ( open ( ' tmpdeb/ ' + fn , ' rb ' ) . read ( ) ) . hexdigest ( )
os . system ( ' echo " %s %s " >> tmpdeb/DEBIAN/md5sums ' % ( md5 , fn ) )
if __name__ == " __main__ " :
main ( )