Fixed Mac installer.
This commit is contained in:
parent
3a2d692aa3
commit
be30112a27
12 changed files with 117 additions and 439 deletions
|
@ -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
0
ChangeLog
Normal 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++
|
||||
|
|
12
appveyor.yml
12
appveyor.yml
|
@ -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:
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,)))
|
||||
|
|
|
@ -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@");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue