You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

396 lines
13 KiB

#!/usr/bin/env python3
import glob, os, platform, re, shutil, sys, tempfile
assert sys.version_info >= ( 3, 8 )
from Detail.Config import config
import Detail.Utility as utility
class Build:
platformString = ""
productVersion = "x.y.z"
productStage = "stage"
productBaseName = "Synergy"
productPackageName = ""
def __init__( self ):
self.configure()
def __configureSubmodules( self ):
utility.printHeading( "Updating Git submodules..." )
os.chdir( config.toplevelPath() )
utility.runCommand( "git submodule update --init --remote --recursive" )
def __configureCMake( self ):
utility.printHeading( "Configuring CMake..." )
command = ( "cmake"
' -S "' + config.synergyCorePath() + '" '
' -B "' + config.synergyBuildPath() + '" '
" -D CMAKE_BUILD_TYPE=Release "
" -D CMAKE_CONFIGURATION_TYPES=Release "
" -D SYNERGY_ENTERPRISE=ON "
)
if platform.system() == "Darwin":
command += " -D CMAKE_OSX_DEPLOYMENT_TARGET=10.12 "
command += " -D CMAKE_OSX_ARCHITECTURES=x86_64 "
if config.libQtPath() != "":
command += ' -D CMAKE_PREFIX_PATH="' + config.libQtPath() +'" '
if config.cmakeGenerator() != "":
command += ' -G "' + config.cmakeGenerator() + '" '
if config.vcvarsallPath() != "":
command = 'call "' + config.vcvarsallPath() + '" x64 && ' + command
utility.runCommand( command )
def __configureVersion( self ):
utility.printHeading( "Configuring version information..." )
def makePlatformString():
if platform.system() == "Windows":
return "-".join( [ platform.system(), platform.release(), platform.machine() ] )
import distro # TODO: Move this to global scope when distro supports Windows
platformInfo = list( distro.linux_distribution( full_distribution_name = False ) );
while "" in platformInfo:
platformInfo.remove( "" )
platformInfo.append( platform.machine() )
return "-".join( platformInfo )
def makeProductVersion():
versionFile = open( config.synergyVersionPath(), "r" )
versionData = versionFile.read();
versionFile.close()
versionParts = re.findall( r" *(?:SET|export) +SYNERGY_VERSION_\w+ *= *\"?(\w+)\"?", versionData )
if len( versionParts ) != 4:
printError( "Failed to extract version information." )
raise SystemExit( 1 )
return versionParts
self.platformString = makePlatformString()
versionParts = makeProductVersion()
self.productVersion = ".".join( versionParts[ 0:3 ] )
self.productStage = versionParts[ 3 ]
self.productPackageName = "-".join( [ self.productBaseName, self.productVersion, self.productStage, self.platformString ] ).lower()
utility.printItem( "platformString: ", self.platformString )
utility.printItem( "productVersion: ", self.productVersion )
utility.printItem( "productStage: ", self.productStage )
utility.printItem( "productPackageName: ", self.productPackageName )
def configure( self ):
self.__configureSubmodules()
self.__configureCMake()
self.__configureVersion()
# Windows builds
def __windowsMakeBinaries( self ):
utility.printHeading( "Building binaries..." )
os.chdir( config.synergyBuildPath() )
utility.runCommand(
'call "' + config.vcvarsallPath() + '" x64 && '
'msbuild synergy-core.sln /p:Platform="x64" /p:Configuration=Release /m ')
def __windowsMakeMSI( self ):
utility.printHeading( "Building MSI package..." )
installerPath = utility.joinPath( config.synergyBuildPath(), "installer" )
os.chdir( installerPath )
utility.runCommand(
'call "' + config.vcvarsallPath() + '" x64 && '
"msbuild Synergy.sln /p:Configuration=Release " )
sourcePath = utility.joinPath( installerPath, "bin/Release/Synergy.msi" )
targetPath = utility.joinPath( config.binariesPath(), self.productPackageName + ".msi" )
shutil.move( sourcePath, targetPath )
def __windowsMakeZIP( self ):
utility.printHeading( "Building standalone ZIP package..." )
def copySynergyBinaries( sourcePath, productPath ):
fileList = [
"libEGL.dll",
"libGLESv2.dll",
"Qt5Core.dll",
"Qt5Gui.dll",
"Qt5Network.dll",
"Qt5Svg.dll",
"Qt5Widgets.dll",
"synergy.exe",
"synergyc.exe",
"synergyd.exe",
"synergys.exe",
"syntool.exe"
]
if not os.path.exists( productPath ):
os.mkdir( productPath )
for fileName in fileList:
filePath = utility.joinPath( sourcePath, fileName )
shutil.copy2( filePath, productPath )
shutil.copytree( utility.joinPath( sourcePath, "Platforms" ), utility.joinPath( productPath, "Platforms" ), dirs_exist_ok = True )
shutil.copytree( utility.joinPath( sourcePath, "Styles" ), utility.joinPath( productPath, "Styles" ), dirs_exist_ok = True )
def copyOpenSSLBinaries( sourceOpenSSLPath, productPath ):
productOpenSSLPath = utility.joinPath( productPath, "OpenSSL" )
if not os.path.exists( productOpenSSLPath ):
os.mkdir( productOpenSSLPath )
for filePath in glob.glob( sourceOpenSSLPath + "/*" ):
shutil.copy2( filePath, productOpenSSLPath )
for filePath in glob.glob( sourceOpenSSLPath + "/*.dll" ):
shutil.copy2( filePath, productPath )
def makeZipArchive( productPath, zipPath ):
rootPath = utility.joinPath( productPath, ".." )
basePath = os.path.relpath( productPath, rootPath )
shutil.make_archive( zipPath, 'zip', rootPath, basePath )
sourcePath = utility.joinPath( config.synergyBuildPath(), "bin/Release" )
productPath = utility.joinPath( config.synergyBuildPath(), "bin", self.productPackageName )
copySynergyBinaries( sourcePath, productPath )
sourceOpenSSLPath = utility.joinPath( config.synergyCorePath(), "ext/openssl/windows/x64/bin" )
copyOpenSSLBinaries( sourceOpenSSLPath, productPath )
zipPath = utility.joinPath( config.binariesPath(), self.productPackageName )
makeZipArchive( productPath, zipPath )
# Darwin builds
def __darwinMakeApplication( self ):
utility.printHeading( "Building application bundle..." )
os.chdir( config.synergyBuildPath() )
# utility.runCommand( "make -j && make install/strip" )
appBundlePath = utility.joinPath( config.synergyBuildPath(), "bundle/Synergy.app" )
# utility.runCommand( 'macdeployqt "' + appBundlePath + '"' )
shutil.copytree( appBundlePath, utility.joinPath( config.binariesPath(), self.productBaseName + ".app" ), dirs_exist_ok = True )
def __darwinMakeDMG( self ):
utility.printHeading( "Building DMG disk image file..." )
targetSymlinkPath = utility.joinPath( config.synergyBuildPath(), "bundle/Applications" )
if not os.path.exists( targetSymlinkPath ):
os.symlink( "/Applications", targetSymlinkPath, target_is_directory = True )
volumeLabel = self.productBaseName + ' ' + self.productVersion;
bundlePath = utility.joinPath( config.synergyBuildPath(), "bundle" )
packagePath = utility.joinPath( config.binariesPath(), self.productPackageName + ".dmg" )
utility.runCommand( "hdiutil create "
'-volname "' + volumeLabel + '" '
'-srcfolder "' + bundlePath + '" '
'-ov -format UDZO ' + packagePath )
# Linux builds
def __linuxMakeBinaries( self ):
utility.printHeading( "Building binaries..." )
utility.runCommand( 'cmake --build "' + config.synergyBuildPath() + '" --parallel' )
def __linuxMakeAppImage( self ):
utility.printHeading( "Building AppImage package..." )
os.chdir( config.toolsPath() )
utility.runCommand( "wget -O linuxdeploy -c " + config.linuxdeployURL() + " && chmod a+x linuxdeploy" )
appImagePath = utility.joinPath( config.synergyBuildPath(), self.productPackageName + ".AppDir" )
# Needed by linuxdeploy
os.environ[ "VERSION" ] = "-".join( [ self.productVersion, self.productStage ] ).lower()
utility.runCommand( "./linuxdeploy "
'--appdir "' + appImagePath + '" '
'--executable "' + utility.joinPath( config.synergyBuildPath(), "bin/synergy" ) + '" '
'--executable "' + utility.joinPath( config.synergyBuildPath(), "bin/synergyc" ) + '" '
'--executable "' + utility.joinPath( config.synergyBuildPath(), "bin/synergyd" ) + '" '
'--executable "' + utility.joinPath( config.synergyBuildPath(), "bin/synergys" ) + '" '
'--executable "' + utility.joinPath( config.synergyBuildPath(), "bin/syntool" ) + '" '
'--create-desktop-file '
'--icon-file "' + utility.joinPath( config.synergyCorePath(), "res/synergy.svg" ) + '" '
'--output appimage' )
os.unsetenv( "VERSION" )
for fileName in glob.glob( "*.AppImage" ):
shutil.move(
utility.joinPath( config.toolsPath(), fileName ),
utility.joinPath( config.binariesPath(), self.productPackageName + ".AppImage" ) )
def __linuxMakeDebian( self ):
utility.printHeading( "Building Debian package..." )
def makeChangeLog():
if not os.path.exists( "./debian/changelog" ):
os.environ[ "SYNERGY_ENTERPRISE" ] = "1"
utility.runCommand( 'dch '
'--create '
'--package "' + self.productBaseName.lower() + '" '
'--controlmaint '
'--distribution unstable '
'--newversion ' + self.productVersion.lower() + ' '
'"Snapshot release."' )
def buildDebianPackage():
os.environ[ "DEB_BUILD_OPTIONS" ] = "parallel=8"
utility.runCommand( "debuild --preserve-envvar SYNERGY_* -us -uc" )
def moveDebianPackage():
for fileName in glob.glob( "../" + self.productBaseName.lower() + "*.deb" ):
shutil.move(
utility.joinPath( config.synergyCorePath(), fileName ),
utility.joinPath( config.binariesPath(), self.productPackageName + ".deb" ) )
for fileName in glob.glob( "../" + self.productBaseName.lower() + "*" ):
shutil.move(
utility.joinPath( config.synergyCorePath(), fileName ),
config.synergyBuildPath() )
os.chdir( config.synergyCorePath() )
makeChangeLog()
buildDebianPackage()
moveDebianPackage()
os.unsetenv( "SYNERGY_ENTERPRISE" )
os.unsetenv( "DEB_BUILD_OPTIONS" )
def __linuxMakeRPM( self ):
utility.printHeading( "Building RPM package..." )
def makeSymlinkPath( temporaryPath ):
sourceSymlinkPath = utility.joinPath( config.synergyBuildPath(), "rpm" )
targetSymlinkPath = utility.joinPath( temporaryPath, "rpm" )
os.symlink( sourceSymlinkPath, targetSymlinkPath, target_is_directory = True )
return targetSymlinkPath
def installBinaries( installPath ):
utility.runCommand( "cmake"
' -S "' + config.synergyCorePath() + '" '
' -B "' + config.synergyBuildPath() + '" '
" -D CMAKE_BUILD_TYPE=Release "
" -D SYNERGY_ENTERPRISE=ON "
' -D CMAKE_INSTALL_PREFIX:PATH="' + installPath + '" ' )
os.chdir( config.synergyBuildPath() )
utility.runCommand( "make -j && make install/strip" )
def makeRpmPackage( rpmToplevelPath, rpmBuildrootPath ):
if " " in rpmToplevelPath:
printError( "RPM top-level path contained spaces:\n\t", rpmToplevelPath )
raise SystemExit( 1 )
os.chdir( rpmToplevelPath )
utility.runCommand( 'rpmbuild -bb '
'--define "_topdir ' + rpmToplevelPath + '" '
'--buildroot ' + rpmBuildrootPath + ' '
"synergy.spec" )
def moveRpmPackage( rpmToplevelPath ):
os.chdir( rpmToplevelPath )
for fileName in glob.glob( "RPMS/x86_64/*.rpm" ):
shutil.move( fileName, utility.joinPath( config.binariesPath(), self.productPackageName + ".rpm" ) )
# rpmbuild can't handle spaces in paths so we operate inside a temporary path
with tempfile.TemporaryDirectory() as temporaryPath:
utility.printInfo( "Created: ", temporaryPath )
rpmToplevelPath = makeSymlinkPath( temporaryPath )
rpmBuildrootPath = utility.joinPath( rpmToplevelPath, "BUILDROOT" )
installPath = utility.joinPath( rpmBuildrootPath, "usr" )
installBinaries( installPath )
makeRpmPackage( rpmToplevelPath, rpmBuildrootPath )
moveRpmPackage( rpmToplevelPath )
def make( self ):
if platform.system() == "Windows":
self.__windowsMakeBinaries()
self.__windowsMakeMSI()
self.__windowsMakeZIP()
elif platform.system() == "Darwin":
self.__darwinMakeApplication()
self.__darwinMakeDMG()
elif platform.system() == "Linux":
self.__linuxMakeBinaries()
self.__linuxMakeAppImage()
self.__linuxMakeDebian()
self.__linuxMakeRPM()
build = Build()
build.make()