Fixed Mac installer.

This commit is contained in:
Gonzalo Exequiel Pedone 2020-06-11 17:38:57 -03:00
parent 3a2d692aa3
commit be30112a27
No known key found for this signature in database
GPG key ID: B8B09E63E9B85BAF
12 changed files with 117 additions and 439 deletions

View file

@ -94,9 +94,9 @@ script:
- chmod +x ports/ci/travis/build.sh
- ports/ci/travis/build.sh
#after_success:
# - chmod +x ports/ci/travis/deploy.sh
# - ports/ci/travis/deploy.sh
after_success:
- chmod +x ports/ci/travis/deploy.sh
- ports/ci/travis/deploy.sh
# - chmod +x ports/ci/travis/upload.sh
# - ports/ci/travis/upload.sh

0
ChangeLog Normal file
View file

View file

@ -64,7 +64,7 @@ macx: LIBS += \
-framework IOKit \
-framework IOSurface
LIBS += \
-L$${OUT_PWD}/VCamUtils/$${BIN_DIR} -lVCamUtils
-L$${OUT_PWD}/../VCamUtils/$${BIN_DIR} -lVCamUtils
isEmpty(STATIC_BUILD) | isEqual(STATIC_BUILD, 0) {
win32-g++: QMAKE_LFLAGS = -static -static-libgcc -static-libstdc++

View file

@ -62,12 +62,12 @@ build_script:
C:\msys64\usr\bin\bash -lc "cd /c/projects/akvirtualcamera && ./ports/ci/appveyor/build.sh '%INSTALL_PREFIX%'"
)
#after_build:
# - if "%MSYS2_BUILD%" == "" (
# ports\ci\appveyor\deploy.bat
# ) else (
# C:\msys64\usr\bin\bash -lc "cd /c/projects/akvirtualcamera && ./ports/ci/appveyor/deploy.sh"
# )
after_build:
- if "%MSYS2_BUILD%" == "" (
ports\ci\appveyor\deploy.bat
) else (
C:\msys64\usr\bin\bash -lc "cd /c/projects/akvirtualcamera && ./ports/ci/appveyor/deploy.sh"
)
# - ports\ci\appveyor\push_artifacts.bat
#
#deploy_script:

View file

@ -38,7 +38,7 @@ win32 {
DEFAULT_PREFIX = C:/
}
}
macx: DEFAULT_PREFIX = /Library/CoreMediaIO/Plug-Ins/DAL
macx: DEFAULT_PREFIX = /Applications
isEmpty(PREFIX): PREFIX = $${DEFAULT_PREFIX}

View file

@ -17,19 +17,12 @@ REM
REM Web-Site: http://webcamoid.github.io/
if "%PLATFORM%" == "x86" (
set FF_ARCH=win32
set GST_ARCH=x86
set VC_ARGS=x86
set PYTHON_PATH=C:\%PYTHON_VERSION%
) else (
set FF_ARCH=win64
set GST_ARCH=x86_64
set VC_ARGS=amd64
set PYTHON_PATH=C:\%PYTHON_VERSION%-x64
)
set MAKE_PATH=%TOOLSDIR%\bin\%MAKETOOL%.exe
set GSTREAMER_DEV_PATH=C:\gstreamer\1.0\%GST_ARCH%
set PATH=%QTDIR%\bin;%TOOLSDIR%\bin;%CD%\ffmpeg-%FFMPEG_VERSION%-%FF_ARCH%-shared\bin;%GSTREAMER_DEV_PATH%\bin;%PATH%
set PATH=%QTDIR%\bin;%TOOLSDIR%\bin;%PATH%
%PYTHON_PATH%\python.exe ports\deploy\deploy.py

View file

@ -18,73 +18,13 @@
#
# Web-Site: http://webcamoid.github.io/
if [ "${ARCH_ROOT_BUILD}" = 1 ]; then
if [ "${TRAVIS_OS_NAME}" = linux ]; then
EXEC='sudo ./root.x86_64/bin/arch-chroot root.x86_64'
elif [ "${TRAVIS_OS_NAME}" = linux ] && [ -z "${ANDROID_BUILD}" ]; then
if [ -z "${DAILY_BUILD}" ]; then
EXEC="docker exec ${DOCKERSYS}"
else
EXEC="docker exec -e DAILY_BUILD=1 ${DOCKERSYS}"
fi
fi
DEPLOYSCRIPT=deployscript.sh
if [ "${ANDROID_BUILD}" = 1 ]; then
export JAVA_HOME=$(readlink -f /usr/bin/java | sed 's:bin/java::')
export ANDROID_HOME="${PWD}/build/android-sdk"
export ANDROID_NDK="${PWD}/build/android-ndk"
export ANDROID_NDK_HOME=${ANDROID_NDK}
export ANDROID_NDK_PLATFORM=android-${ANDROID_PLATFORM}
export ANDROID_NDK_ROOT=${ANDROID_NDK}
export ANDROID_SDK_ROOT=${ANDROID_HOME}
export PATH="${JAVA_HOME}/bin/java:${PATH}"
export PATH="$PATH:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin"
export PATH="${PATH}:${ANDROID_HOME}/platform-tools"
export PATH="${PATH}:${ANDROID_HOME}/emulator"
export PATH="${PATH}:${ANDROID_NDK}"
export ORIG_PATH="${PATH}"
export KEYSTORE_PATH="${PWD}/keystores/debug.keystore"
nArchs=$(echo "${TARGET_ARCH}" | tr ':' ' ' | wc -w)
lastArch=$(echo "${TARGET_ARCH}" | awk -F: '{print $NF}')
if [ "${nArchs}" = 1 ]; then
export PATH="${PWD}/build/Qt/${QTVER}/android/bin:${PWD}/.local/bin:${ORIG_PATH}"
export BUILD_PATH=${PWD}/build-webcamoid-${lastArch}
python3 ports/deploy/deploy.py
else
pkgMerge=
for arch_ in $(echo "${TARGET_ARCH}" | tr ":" "\n"); do
if [ ! -z "${pkgMerge}" ]; then
pkgMerge=${pkgMerge}:
fi
pkgMerge=${pkgMerge}${PWD}/build-webcamoid-${arch_}
done
for arch_ in $(echo "${TARGET_ARCH}" | tr ":" "\n"); do
export PATH="${PWD}/build/Qt/${QTVER}/android/bin:${PWD}/.local/bin:${ORIG_PATH}"
export BUILD_PATH=${PWD}/build-webcamoid-${arch_}
if [ "${arch_}" = "${lastArch}" ]; then
export PACKAGES_PREPARE_ONLY=0
export PACKAGES_MERGE="${pkgMerge}"
else
export PACKAGES_PREPARE_ONLY=1
fi
export NO_SHOW_PKG_DATA_INFO=1
python3 ports/deploy/deploy.py
done
fi
mkdir -p "${PWD}/ports/deploy/packages_auto"
cp -rvf "${PWD}/build-webcamoid-${lastArch}/ports/deploy/packages_auto"/* \
"${PWD}/ports/deploy/packages_auto"
elif [ "${ARCH_ROOT_BUILD}" = 1 ]; then
if [ "${TRAVIS_OS_NAME}" = linux ]; then
sudo mount --bind root.x86_64 root.x86_64
sudo mount --bind $HOME root.x86_64/$HOME
@ -113,17 +53,6 @@ EOF
${EXEC} bash $HOME/${DEPLOYSCRIPT}
sudo umount root.x86_64/$HOME
sudo umount root.x86_64
elif [ "${TRAVIS_OS_NAME}" = linux ]; then
cat << EOF > ${DEPLOYSCRIPT}
#!/bin/sh
export PATH="\$PWD/.local/bin:\$PATH"
xvfb-run --auto-servernum python3 ports/deploy/deploy.py
EOF
chmod +x ${DEPLOYSCRIPT}
${EXEC} bash ${DEPLOYSCRIPT}
elif [ "${TRAVIS_OS_NAME}" = osx ]; then
${EXEC} python3 ports/deploy/deploy.py
fi

View file

@ -38,34 +38,23 @@ class Deploy(deploy_base.DeployBase, tools.qt5.DeployToolsQt):
super().__init__()
self.installDir = os.path.join(self.buildDir, 'ports/deploy/temp_priv')
self.pkgsDir = os.path.join(self.buildDir, 'ports/deploy/packages_auto', self.targetSystem)
self.detectQt(os.path.join(self.buildDir, 'StandAlone'))
self.detectQt(os.path.join(self.buildDir, 'Manager'))
self.rootInstallDir = os.path.join(self.installDir, 'Applications')
self.programName = 'webcamoid'
self.appBundleDir = os.path.join(self.rootInstallDir, self.programName + '.app')
self.programName = 'AkVirtualCamera'
self.appBundleDir = os.path.join(self.rootInstallDir, self.programName + '.plugin')
self.execPrefixDir = os.path.join(self.appBundleDir, 'Contents')
self.binaryInstallDir = os.path.join(self.execPrefixDir, 'MacOS')
self.libInstallDir = os.path.join(self.execPrefixDir, 'Frameworks')
self.qmlInstallDir = os.path.join(self.execPrefixDir, 'Resources/qml')
self.pluginsInstallDir = os.path.join(self.execPrefixDir, 'Plugins')
self.qtConf = os.path.join(self.execPrefixDir, 'Resources/qt.conf')
self.qmlRootDirs = ['StandAlone/share/qml', 'libAvKys/Plugins']
self.mainBinary = os.path.join(self.binaryInstallDir, self.programName)
self.programVersion = self.detectVersion(os.path.join(self.rootDir, 'commons.pri'))
self.detectMake()
xspec = self.qmakeQuery(var='QMAKE_XSPEC')
if 'android' in xspec:
self.targetSystem = 'android'
self.binarySolver = tools.binary_mach.DeployToolsBinary()
self.binarySolver.readExcludeList(os.path.join(self.rootDir, 'ports/deploy/exclude.{}.{}.txt'.format(os.name, sys.platform)))
self.packageConfig = os.path.join(self.rootDir, 'ports/deploy/package_info.conf')
self.dependencies = []
self.installerConfig = os.path.join(self.installDir, 'installer/config')
self.installerPackages = os.path.join(self.installDir, 'installer/packages')
self.appIcon = os.path.join(self.execPrefixDir, 'Resources/{0}.icns'.format(self.programName))
self.appIcon = os.path.join(self.rootDir, 'share/TestFrame/webcamoid.png')
self.licenseFile = os.path.join(self.rootDir, 'COPYING')
self.installerRunProgram = '@TargetDir@/{0}.app/Contents/MacOS/{0}'.format(self.programName)
self.installerTargetDir = '@ApplicationsDir@/' + self.programName
self.installerScript = os.path.join(self.rootDir, 'ports/deploy/installscript.mac.qs')
self.changeLog = os.path.join(self.rootDir, 'ChangeLog')
@ -77,160 +66,14 @@ class Deploy(deploy_base.DeployBase, tools.qt5.DeployToolsQt):
print('Executing make install')
self.makeInstall(self.buildDir, self.installDir)
self.detectTargetArch()
print('Copying Qml modules\n')
self.solvedepsQml()
print('\nCopying required plugins\n')
self.solvedepsPlugins()
print('\nCopying required libs\n')
self.solvedepsLibs()
print('\nWritting qt.conf file')
self.writeQtConf()
print('Stripping symbols')
self.binarySolver.stripSymbols(self.installDir)
print('Resetting file permissions')
self.binarySolver.resetFilePermissions(self.rootInstallDir,
self.binaryInstallDir)
print('Removing unnecessary files')
self.removeUnneededFiles(self.libInstallDir)
print('Fixing rpaths\n')
self.fixRpaths()
print('\nWritting build system information\n')
self.writeBuildInfo()
def solvedepsLibs(self):
deps = sorted(self.binarySolver.scanDependencies(self.installDir))
for dep in deps:
depPath = os.path.join(self.libInstallDir, os.path.basename(dep))
if dep != depPath:
print(' {} -> {}'.format(dep, depPath))
self.copy(dep, depPath, not dep.endswith('.framework'))
self.dependencies.append(dep)
@staticmethod
def removeUnneededFiles(path):
adirs = set()
afiles = set()
for root, dirs, files in os.walk(path):
for d in dirs:
if d == 'Headers':
adirs.add(os.path.join(root, d))
for f in files:
if f == 'Headers' or f.endswith('.prl'):
afiles.add(os.path.join(root, f))
for adir in adirs:
try:
shutil.rmtree(adir, True)
except:
pass
for afile in afiles:
try:
if os.path.islink(afile):
os.unlink(afile)
else:
os.remove(afile)
except:
pass
def fixLibRpath(self, mutex, mach):
rpath = os.path.join('@executable_path',
os.path.relpath(self.libInstallDir,
self.binaryInstallDir))
log = '\tFixed {}\n\n'.format(mach)
machInfo = self.binarySolver.dump(mach)
# Change rpath
if mach.startswith(self.binaryInstallDir):
log += '\t\tChanging rpath to {}\n'.format(rpath)
for oldRpath in machInfo['rpaths']:
process = subprocess.Popen(['install_name_tool', # nosec
'-delete_rpath', oldRpath, mach],
stdout=subprocess.PIPE)
process.communicate()
process = subprocess.Popen(['install_name_tool', # nosec
'-add_rpath', rpath, mach],
stdout=subprocess.PIPE)
process.communicate()
# Change ID
if mach.startswith(self.binaryInstallDir):
newMachId = machInfo['id']
elif mach.startswith(self.libInstallDir):
newMachId = mach.replace(self.libInstallDir, rpath)
else:
newMachId = os.path.basename(mach)
if newMachId != machInfo['id']:
log += '\t\tChanging ID to {}\n'.format(newMachId)
process = subprocess.Popen(['install_name_tool', # nosec
'-id', newMachId, mach],
stdout=subprocess.PIPE)
process.communicate()
# Change library links
for dep in machInfo['imports']:
if dep.startswith(rpath):
continue
if self.binarySolver.isExcluded(dep):
continue
basename = os.path.basename(dep)
framework = ''
inFrameworkPath = ''
if not basename.endswith('.dylib'):
frameworkPath = dep[: dep.rfind('.framework')] + '.framework'
framework = os.path.basename(frameworkPath)
inFrameworkPath = os.path.join(framework, dep.replace(frameworkPath + '/', ''))
newDepPath = os.path.join(rpath, basename if len(framework) < 1 else inFrameworkPath)
if dep != newDepPath:
log += '\t\t{} -> {}\n'.format(dep, newDepPath)
process = subprocess.Popen(['install_name_tool', # nosec
'-change', dep, newDepPath, mach],
stdout=subprocess.PIPE)
process.communicate()
mutex.acquire()
print(log)
mutex.release()
def fixRpaths(self):
path = os.path.join(self.execPrefixDir)
mutex = threading.Lock()
threads = []
for mach in self.binarySolver.find(path):
thread = threading.Thread(target=self.fixLibRpath, args=(mutex, mach,))
threads.append(thread)
while threading.active_count() >= self.njobs:
time.sleep(0.25)
thread.start()
for thread in threads:
thread.join()
@staticmethod
def searchPackageFor(cellarPath, path):
if not path.startswith(cellarPath):
return ''
return ' '.join(path.replace(cellarPath + os.sep, '').split(os.sep)[0: 2])
def commitHash(self):
try:
process = subprocess.Popen(['git', 'rev-parse', 'HEAD'], # nosec
@ -256,8 +99,18 @@ class Deploy(deploy_base.DeployBase, tools.qt5.DeployToolsQt):
return stdout.decode(sys.getdefaultencoding()).strip()
def writeBuildInfo(self):
try:
os.makedirs(self.pkgsDir)
except:
pass
resourcesDir = os.path.join(self.execPrefixDir, 'Resources')
os.makedirs(self.pkgsDir)
try:
os.makedirs(resourcesDir)
except:
pass
depsInfoFile = os.path.join(resourcesDir, 'build-info.txt')
# Write repository info.
@ -300,35 +153,6 @@ class Deploy(deploy_base.DeployBase, tools.qt5.DeployToolsQt):
print()
f.write('\n')
os.environ['LC_ALL'] = 'C'
brew = self.whereBin('brew')
if len(brew) < 1:
return
process = subprocess.Popen([brew, '--cellar'], # nosec
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, _ = process.communicate()
cellarPath = stdout.decode(sys.getdefaultencoding()).strip()
# Write binary dependencies info.
packages = set()
for dep in self.dependencies:
packageInfo = self.searchPackageFor(cellarPath, dep)
if len(packageInfo) > 0:
packages.add(packageInfo)
packages = sorted(packages)
with open(depsInfoFile, 'a') as f:
for packge in packages:
print(' ' + packge)
f.write(packge + '\n')
@staticmethod
def hrSize(size):
i = int(math.log(size) // math.log(1024))
@ -365,109 +189,6 @@ class Deploy(deploy_base.DeployBase, tools.qt5.DeployToolsQt):
return size
# https://asmaloney.com/2013/07/howto/packaging-a-mac-os-x-application-using-a-dmg/
def createPortable(self, mutex):
staggingDir = os.path.join(self.installDir, 'stagging')
if not os.path.exists(staggingDir):
os.makedirs(staggingDir)
self.copy(self.appBundleDir,
os.path.join(staggingDir, self.programName + '.app'))
imageSize = self.dirSize(staggingDir)
tmpDmg = os.path.join(self.installDir, self.programName + '_tmp.dmg')
volumeName = "{}-portable-{}".format(self.programName,
self.programVersion)
process = subprocess.Popen(['hdiutil', 'create', # nosec
'-srcfolder', staggingDir,
'-volname', volumeName,
'-fs', 'HFS+',
'-fsargs', '-c c=64,a=16,e=16',
'-format', 'UDRW',
'-size', str(math.ceil(imageSize * 1.1)),
tmpDmg],
stdout=subprocess.PIPE)
process.communicate()
process = subprocess.Popen(['hdiutil', # nosec
'attach',
'-readwrite',
'-noverify',
tmpDmg],
stdout=subprocess.PIPE)
stdout, _ = process.communicate()
device = ''
for line in stdout.split(b'\n'):
line = line.strip()
if len(line) < 1:
continue
dev = line.split()
if len(dev) > 2:
device = dev[0].decode(sys.getdefaultencoding())
break
time.sleep(2)
volumePath = os.path.join('/Volumes', volumeName)
volumeIcon = os.path.join(volumePath, '.VolumeIcon.icns')
self.copy(self.appIcon, volumeIcon)
process = subprocess.Popen(['SetFile', # nosec
'-c', 'icnC',
volumeIcon],
stdout=subprocess.PIPE)
process.communicate()
process = subprocess.Popen(['SetFile', # nosec
'-a', 'C',
volumePath],
stdout=subprocess.PIPE)
process.communicate()
appsShortcut = os.path.join(volumePath, 'Applications')
if not os.path.exists(appsShortcut):
os.symlink('/Applications', appsShortcut)
os.sync()
process = subprocess.Popen(['hdiutil', # nosec
'detach',
device],
stdout=subprocess.PIPE)
process.communicate()
packagePath = \
os.path.join(self.pkgsDir,
'{}-portable-{}-{}.dmg'.format(self.programName,
self.programVersion,
platform.machine()))
if not os.path.exists(self.pkgsDir):
os.makedirs(self.pkgsDir)
if os.path.exists(packagePath):
os.remove(packagePath)
process = subprocess.Popen(['hdiutil', # nosec
'convert',
tmpDmg,
'-format', 'UDZO',
'-imagekey', 'zlib-level=9',
'-o', packagePath],
stdout=subprocess.PIPE)
process.communicate()
mutex.acquire()
print('Created portable package:')
self.printPackageInfo(packagePath)
mutex.release()
def createAppInstaller(self, mutex):
packagePath = self.createInstaller()
@ -481,9 +202,8 @@ class Deploy(deploy_base.DeployBase, tools.qt5.DeployToolsQt):
def package(self):
mutex = threading.Lock()
threads = [threading.Thread(target=self.createPortable, args=(mutex,))]
packagingTools = ['dmg']
threads = []
packagingTools = []
if self.qtIFW != '':
threads.append(threading.Thread(target=self.createAppInstaller, args=(mutex,)))

View file

@ -10,4 +10,77 @@ Component.prototype.beginInstallation = function()
Component.prototype.createOperations = function()
{
component.createOperations();
// Remove old plugin
if (installer.isInstaller()) {
component.addOperation("ConsumeOutput",
"AkPluginSymlink",
"/usr/bin/readlink",
"/Library/CoreMediaIO/Plug-Ins/DAL/@Name@.plugin");
if (installer.value("AkPluginSymlink") == "")
component.addElevatedOperation("Execute",
"rm",
"-rf",
"/Library/CoreMediaIO/Plug-Ins/DAL/@Name@.plugin");
}
// Create a symlink to the plugin.
component.addElevatedOperation("Execute",
"ln",
"-s",
"@TargetDir@/@Name@.plugin",
"/Library/CoreMediaIO/Plug-Ins/DAL/@Name@.plugin",
"UNDOEXECUTE",
"rm",
"-f",
"/Library/CoreMediaIO/Plug-Ins/DAL/@Name@.plugin");
// Set assistant daemon.
let daemonPlist = "/Library/LaunchAgents/org.webcamoid.cmio.AkVCam.Assistant.plist"
let plistContents = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
+ "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+ "<plist version=\"1.0\">\n"
+ " <dict>\n"
+ " <key>Label</key>\n"
+ " <string>org.webcamoid.cmio.AkVCam.Assistant</string>\n"
+ " <key>ProgramArguments</key>\n"
+ " <array>\n"
+ " <string>"
+ installer.value("TargetDir")
+ "/AkVirtualCamera.plugin/Contents/Resources/AkVCamAssistant"
+ "</string>\n"
+ " <string>--timeout</string>\n"
+ " <string>300.0</string>\n"
+ " </array>\n"
+ " <key>MachServices</key>\n"
+ " <dict>\n"
+ " <key>org.webcamoid.cmio.AkVCam.Assistant</key>\n"
+ " <true/>\n"
+ " </dict>\n"
+ " </dict>\n"
+ "</plist>\n";
component.addElevatedOperation("Delete", daemonPlist);
component.addElevatedOperation("AppendFile", daemonPlist, plistContents);
// Load assistant daemon.
component.addElevatedOperation("Execute",
"launchctl", "load", "-w", daemonPlist,
"UNDOEXECUTE",
"launchctl", "unload", "-w", daemonPlist);
if (installer.isUninstaller())
component.addElevatedOperation("Delete", daemonPlist);
if (installer.value("TargetDir") != "/Applications/" + installer.value("Name"))
component.addElevatedOperation("Execute",
"ln",
"-s",
"@TargetDir@",
"/Applications/@Name@",
"UNDOEXECUTE",
"rm",
"-f",
"/Applications/@Name@");
}

View file

@ -10,44 +10,4 @@ Component.prototype.beginInstallation = function()
Component.prototype.createOperations = function()
{
component.createOperations();
component.addOperation("InstallIcons", "@TargetDir@/share/icons" );
component.addOperation("CreateDesktopEntry",
"Webcamoid.desktop",
"Name=Webcamoid\n"
+ "GenericName=Webcam Capture Software\n"
+ "GenericName[ca]=Programari de Captura de Càmera web\n"
+ "GenericName[de]=Webcam-Capture-Software\n"
+ "GenericName[el]=κάμερα συλλαμβάνει το λογισμικό\n"
+ "GenericName[es]=Programa para Captura de la Webcam\n"
+ "GenericName[fr]=Logiciel de Capture Webcam\n"
+ "GenericName[gl]=Programa de Captura de Webcam\n"
+ "GenericName[it]=Webcam Capture Software\n"
+ "GenericName[ja]=ウェブカメラのキャプチャソフトウェア\n"
+ "GenericName[ko]=웹캠 캡처 소프트웨어\n"
+ "GenericName[pt]=Software de Captura de Webcam\n"
+ "GenericName[ru]=Веб-камера захвата программного обеспечения\n"
+ "GenericName[zh_CN]=摄像头捕捉软件\n"
+ "GenericName[zh_TW]=攝像頭捕捉軟件\n"
+ "Comment=Take photos and record videos with your webcam\n"
+ "Comment[ca]=Fer fotos i gravar vídeos amb la seva webcam\n"
+ "Comment[de]=Maak foto's en video's opnemen met uw webcam\n"
+ "Comment[el]=Τραβήξτε φωτογραφίες και εγγραφή βίντεο με την κάμερα σας\n"
+ "Comment[es]=Tome fotos y grabe videos con su camara web\n"
+ "Comment[fr]=Prenez des photos et enregistrer des vidéos avec votre webcam\n"
+ "Comment[gl]=Facer fotos e gravar vídeos coa súa cámara web\n"
+ "Comment[it]=Scatta foto e registrare video con la tua webcam\n"
+ "Comment[ja]=ウェブカメラで写真や記録ビデオを撮影\n"
+ "Comment[ko]=웹캠으로 사진과 기록 비디오를 촬영\n"
+ "Comment[pt]=Tirar fotos e gravar vídeos com sua webcam\n"
+ "Comment[ru]=Возьмите фотографии и записывать видео с веб-камеры\n"
+ "Comment[zh_CN]=拍摄照片和录制视频与您的摄像头\n"
+ "Comment[zh_TW]=拍攝照片和錄製視頻與您的攝像頭\n"
+ "Keywords=photo;video;webcam;\n"
+ "Exec=" + installer.value("RunProgram") + "\n"
+ "Icon=webcamoid\n"
+ "Terminal=false\n"
+ "Type=Application\n"
+ "Categories=AudioVideo;Player;Qt;\n"
+ "StartupNotify=true\n");
}

View file

@ -1,7 +1,6 @@
[Package]
appName = Webcamoid
description = Webcamoid, The ultimate webcam suite!
url = https://webcamoid.github.io/
appName = AkVirtualCamera
description = AkVirtualCamera, virtual camera for Mac and Windows
url = https://github.com/webcamoid/akvirtualcamera
titleColor = #3F1F7F
runMessage = Launch Webcamoid now!
licenseDescription = GNU General Public License v3.0

View file

@ -47,6 +47,7 @@ class DeployToolsQt(tools.utils.DeployToolsUtils):
self.dependencies = []
self.binarySolver = None
self.installerConfig = ''
self.installerRunProgram = ''
def detectQt(self, path=''):
self.detectQmake(path)
@ -495,7 +496,7 @@ class DeployToolsQt(tools.utils.DeployToolsUtils):
packageConf.read(self.packageConfig, 'utf-8')
# Create layout
componentName = 'com.{0}prj.{0}'.format(self.programName)
componentName = 'com.webcamoidprj.{0}'.format(self.programName)
packageDir = os.path.join(self.installerPackages, componentName)
if not os.path.exists(self.installerConfig):
@ -541,11 +542,13 @@ class DeployToolsQt(tools.utils.DeployToolsUtils):
config.write(' <InstallerWindowIcon>{}</InstallerWindowIcon>\n'.format(iconName))
config.write(' <InstallerApplicationIcon>{}</InstallerApplicationIcon>\n'.format(iconName))
config.write(' <Logo>{}</Logo>\n'.format(iconName))
config.write(' <TitleColor>{}</TitleColor>\n'.format(packageConf['Package']['titleColor'].strip()))
config.write(' <RunProgram>{}</RunProgram>\n'.format(self.installerRunProgram))
config.write(' <RunProgramDescription>{}</RunProgramDescription>\n'.format(packageConf['Package']['runMessage'].strip()))
config.write(' <StartMenuDir>{}</StartMenuDir>\n'.format(appName))
config.write(' <MaintenanceToolName>{}MaintenanceTool</MaintenanceToolName>\n'.format(appName))
if self.installerRunProgram != '':
config.write(' <RunProgram>{}</RunProgram>\n'.format(self.installerRunProgram))
config.write(' <RunProgramDescription>{}</RunProgramDescription>\n'.format(packageConf['Package']['runMessage'].strip()))
config.write(' <StartMenuDir>{}</StartMenuDir>\n'.format(appName))
config.write(' <MaintenanceToolName>Uninstall</MaintenanceToolName>\n')
config.write(' <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>\n')
config.write(' <TargetDir>{}</TargetDir>\n'.format(self.installerTargetDir))
config.write('</Installer>\n')
@ -582,6 +585,7 @@ class DeployToolsQt(tools.utils.DeployToolsUtils):
f.write(' <Default>true</Default>\n')
f.write(' <ForcedInstallation>true</ForcedInstallation>\n')
f.write(' <Essential>false</Essential>\n')
f.write(' <RequiresAdminRights>true</RequiresAdminRights>\n')
f.write('</Package>\n')
# Remove old file