Generate package_info.conf from input file. Fixed install paths in Windows. Force static build when using GCC. Removed deploy scripts from sources tree.
This commit is contained in:
parent
3735240225
commit
b572a8cede
13 changed files with 65 additions and 1247 deletions
|
@ -26,24 +26,23 @@ add_subdirectory(VCamUtils)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
add_subdirectory(cmio)
|
add_subdirectory(cmio)
|
||||||
|
set(TARGET_PLATFORM mac)
|
||||||
|
set(BUILD_INFO_FILE AkVirtualCamera.plugin/Contents/Resources/build-info.txt)
|
||||||
|
set(APP_LIBDIR AkVirtualCamera.plugin/Contents/Frameworks)
|
||||||
|
set(QTIFW_TARGET_DIR "\@ApplicationsDir\@/AkVirtualCamera")
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
add_subdirectory(dshow)
|
add_subdirectory(dshow)
|
||||||
|
set(TARGET_PLATFORM windows)
|
||||||
|
set(BUILD_INFO_FILE share/build-info.txt)
|
||||||
|
set(APP_LIBDIR ${TARGET_ARCH})
|
||||||
|
|
||||||
|
if (IS_64BITS_TARGET)
|
||||||
|
set(QTIFW_TARGET_DIR "\@ApplicationsDirX64\@/AkVirtualCamera")
|
||||||
|
else ()
|
||||||
|
set(QTIFW_TARGET_DIR "\@ApplicationsDirX86\@/AkVirtualCamera")
|
||||||
|
endif()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_subdirectory(Manager)
|
add_subdirectory(Manager)
|
||||||
|
|
||||||
if (APPLE)
|
configure_file(package_info.conf.in package_info.conf)
|
||||||
set(TARGET_PLATFORM mac)
|
|
||||||
elseif (WIN32)
|
|
||||||
set(TARGET_PLATFORM windows)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
file(WRITE ${CMAKE_BINARY_DIR}/package_info.conf
|
|
||||||
"[Package]\n"
|
|
||||||
"appName = AkVirtualCamera\n"
|
|
||||||
"packageName = akvirtualcamera\n"
|
|
||||||
"version = ${VERSION}\n"
|
|
||||||
"description = AkVirtualCamera, virtual camera for Mac and Windows\n"
|
|
||||||
"url = https://github.com/webcamoid/akvirtualcamera\n"
|
|
||||||
"licenseDescription = GNU General Public License v3.0\n"
|
|
||||||
"targetPlatform = ${TARGET_PLATFORM}\n")
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ if (APPLE)
|
||||||
set(INSTALLPATH ${CMIO_PLUGIN_NAME}.plugin/Contents/Resources)
|
set(INSTALLPATH ${CMIO_PLUGIN_NAME}.plugin/Contents/Resources)
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
include(../dshow/dshow.cmake)
|
include(../dshow/dshow.cmake)
|
||||||
set(INSTALLPATH ${DSHOW_PLUGIN_NAME}.plugin/${TARGET_ARCH})
|
set(INSTALLPATH ${TARGET_ARCH})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_executable(Manager
|
add_executable(Manager
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
if (NOT APPLE AND NOT WIN32)
|
||||||
|
message(FATAL_ERROR "This driver only works in Mac an Windows. For Linux check 'akvcam' instead.")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
include(CheckCXXSourceCompiles)
|
||||||
|
|
||||||
set(COMMONS_APPNAME AkVirtualCamera)
|
set(COMMONS_APPNAME AkVirtualCamera)
|
||||||
string(TOLOWER ${COMMONS_APPNAME} COMMONS_TARGET)
|
string(TOLOWER ${COMMONS_APPNAME} COMMONS_TARGET)
|
||||||
|
|
||||||
|
@ -32,9 +38,17 @@ add_definitions(-DCOMMONS_APPNAME="\\"${COMMONS_APPNAME}\\""
|
||||||
-DCOMMONS_VERSION="\\"${VERSION}\\""
|
-DCOMMONS_VERSION="\\"${VERSION}\\""
|
||||||
-DPREFIX="\\"${PREFIX}\\"")
|
-DPREFIX="\\"${PREFIX}\\"")
|
||||||
|
|
||||||
if (WIN32)
|
if (APPLE)
|
||||||
include(CheckCXXSourceCompiles)
|
check_cxx_source_compiles("
|
||||||
|
#ifndef __x86_64__
|
||||||
|
#error Not x64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}" IS_64BITS_TARGET)
|
||||||
|
elseif (WIN32)
|
||||||
check_cxx_source_compiles("
|
check_cxx_source_compiles("
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
#error Not x64
|
#error Not x64
|
||||||
|
@ -43,17 +57,17 @@ if (WIN32)
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}" IS_WIN64_TARGET)
|
}" IS_64BITS_TARGET)
|
||||||
|
|
||||||
if (IS_WIN64_TARGET)
|
|
||||||
set(TARGET_ARCH x64 CACHE INTERNAL "")
|
|
||||||
else ()
|
|
||||||
set(TARGET_ARCH x86 CACHE INTERNAL "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_definitions(-DUNICODE -D_UNICODE)
|
add_definitions(-DUNICODE -D_UNICODE)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT APPLE AND NOT WIN32)
|
if (IS_64BITS_TARGET)
|
||||||
message(FATAL_ERROR "This driver only works in Mac an Windows. For Linux check 'akvcam' instead.")
|
set(TARGET_ARCH x64 CACHE INTERNAL "")
|
||||||
endif ()
|
else ()
|
||||||
|
set(TARGET_ARCH x86 CACHE INTERNAL "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static -static-libgcc -static-libstdc++")
|
||||||
|
endif()
|
||||||
|
|
|
@ -24,7 +24,7 @@ set(CMAKE_CXX_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
include(../dshow.cmake)
|
include(../dshow.cmake)
|
||||||
set(INSTALLPATH ${DSHOW_PLUGIN_NAME}.plugin/${TARGET_ARCH})
|
set(INSTALLPATH ${TARGET_ARCH})
|
||||||
|
|
||||||
add_executable(Assistant
|
add_executable(Assistant
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
|
|
|
@ -25,7 +25,7 @@ set(CMAKE_CXX_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
include(../dshow.cmake)
|
include(../dshow.cmake)
|
||||||
set(INSTALLPATH ${DSHOW_PLUGIN_NAME}.plugin/${TARGET_ARCH})
|
set(INSTALLPATH ${TARGET_ARCH})
|
||||||
|
|
||||||
add_library(VirtualCamera SHARED
|
add_library(VirtualCamera SHARED
|
||||||
src/basefilter.cpp
|
src/basefilter.cpp
|
||||||
|
|
22
package_info.conf.in
Normal file
22
package_info.conf.in
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
[Package]
|
||||||
|
name = akvirtualcamera
|
||||||
|
targetPlatform = @TARGET_PLATFORM@
|
||||||
|
sourcesDir = @CMAKE_SOURCE_DIR@
|
||||||
|
libDir = @APP_LIBDIR@
|
||||||
|
buildInfoFile = @BUILD_INFO_FILE@
|
||||||
|
targetArch = @TARGET_ARCH@
|
||||||
|
version = @VERSION@
|
||||||
|
outputFormats = QtIFW
|
||||||
|
hideArch = true
|
||||||
|
|
||||||
|
[QtIFW]
|
||||||
|
organization = org.webcamoidprj
|
||||||
|
appName = AkVirtualCamera
|
||||||
|
title = AkVirtualCamera, virtual camera for Mac and Windows
|
||||||
|
description = Install AkVirtualCamera
|
||||||
|
url = https://github.com/webcamoid/akvirtualcamera
|
||||||
|
targetDir = @QTIFW_TARGET_DIR@
|
||||||
|
license = COPYING
|
||||||
|
licenseName = GNU General Public License v3.0
|
||||||
|
script = ports/deploy/installscript.@TARGET_PLATFORM@.qs
|
||||||
|
changeLog = ChangeLog
|
|
@ -1,44 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Webcamoid, webcam capture application.
|
|
||||||
# Copyright (C) 2017 Gonzalo Exequiel Pedone
|
|
||||||
#
|
|
||||||
# Webcamoid is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Webcamoid is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Webcamoid. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# Web-Site: http://webcamoid.github.io/
|
|
||||||
|
|
||||||
import os
|
|
||||||
from WebcamoidDeployTools import DTUtils
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ =='__main__':
|
|
||||||
system = DTUtils.Utils().system
|
|
||||||
scriptDir = os.path.dirname(os.path.realpath(__file__))
|
|
||||||
|
|
||||||
while True:
|
|
||||||
scriptPath = os.path.join(scriptDir, 'deploy_{}.py'.format(system))
|
|
||||||
|
|
||||||
if not os.path.exists(scriptPath):
|
|
||||||
print('No valid deploy script found')
|
|
||||||
exit()
|
|
||||||
|
|
||||||
deploy = __import__('deploy_' + system).Deploy()
|
|
||||||
|
|
||||||
if system == deploy.targetSystem:
|
|
||||||
deploy.run()
|
|
||||||
|
|
||||||
exit()
|
|
||||||
|
|
||||||
system = deploy.targetSystem
|
|
|
@ -1,214 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Webcamoid, webcam capture application.
|
|
||||||
# Copyright (C) 2017 Gonzalo Exequiel Pedone
|
|
||||||
#
|
|
||||||
# Webcamoid is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Webcamoid is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Webcamoid. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# Web-Site: http://webcamoid.github.io/
|
|
||||||
|
|
||||||
import math
|
|
||||||
import os
|
|
||||||
import platform
|
|
||||||
import shutil
|
|
||||||
import subprocess # nosec
|
|
||||||
import sys
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
|
|
||||||
from WebcamoidDeployTools import DTDeployBase
|
|
||||||
from WebcamoidDeployTools import DTQt5
|
|
||||||
from WebcamoidDeployTools import DTBinaryMach
|
|
||||||
|
|
||||||
|
|
||||||
class Deploy(DTDeployBase.DeployBase, DTQt5.Qt5Tools):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
rootDir = os.path.normpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../..'))
|
|
||||||
self.setRootDir(rootDir)
|
|
||||||
self.pkgsDir = os.path.join(self.buildDir, 'ports/deploy/packages_auto', self.targetSystem)
|
|
||||||
self.detectQtIFW()
|
|
||||||
self.detectQtIFWVersion()
|
|
||||||
self.programName = 'AkVirtualCamera'
|
|
||||||
self.adminRights = True
|
|
||||||
self.packageConfig = os.path.join(self.buildDir, 'package_info.conf')
|
|
||||||
self.appBundleDir = os.path.join(self.installDir, self.programName + '.plugin')
|
|
||||||
self.execPrefixDir = os.path.join(self.appBundleDir, 'Contents')
|
|
||||||
self.binaryInstallDir = os.path.join(self.execPrefixDir, 'MacOS')
|
|
||||||
self.mainBinary = os.path.join(self.binaryInstallDir, self.programName)
|
|
||||||
self.detectMake()
|
|
||||||
self.binarySolver = DTBinaryMach.MachBinaryTools()
|
|
||||||
self.binarySolver.readExcludes(os.name, sys.platform)
|
|
||||||
self.dependencies = []
|
|
||||||
self.installerConfig = os.path.join(self.installDir, 'installer/config')
|
|
||||||
self.installerPackages = os.path.join(self.installDir, 'installer/packages')
|
|
||||||
self.licenseFile = os.path.join(self.rootDir, 'COPYING')
|
|
||||||
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')
|
|
||||||
self.outPackage = os.path.join(self.pkgsDir,
|
|
||||||
'{}-{}.dmg'.format(self.programName,
|
|
||||||
self.programVersion()))
|
|
||||||
|
|
||||||
def prepare(self):
|
|
||||||
self.detectTargetArch()
|
|
||||||
print('Stripping symbols')
|
|
||||||
self.binarySolver.stripSymbols(self.installDir)
|
|
||||||
print('Resetting file permissions')
|
|
||||||
self.binarySolver.resetFilePermissions(self.installDir,
|
|
||||||
self.binaryInstallDir)
|
|
||||||
print('\nWritting build system information\n')
|
|
||||||
self.writeBuildInfo()
|
|
||||||
print('\nSigning bundle\n')
|
|
||||||
self.signPackage(self.appBundleDir)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def sysInfo():
|
|
||||||
process = subprocess.Popen(['sw_vers'], # nosec
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, _ = process.communicate()
|
|
||||||
|
|
||||||
return stdout.decode(sys.getdefaultencoding()).strip()
|
|
||||||
|
|
||||||
def writeBuildInfo(self):
|
|
||||||
try:
|
|
||||||
os.makedirs(self.pkgsDir)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
resourcesDir = os.path.join(self.execPrefixDir, 'Resources')
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.makedirs(resourcesDir)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
depsInfoFile = os.path.join(resourcesDir, 'build-info.txt')
|
|
||||||
|
|
||||||
# Write repository info.
|
|
||||||
|
|
||||||
with open(depsInfoFile, 'w') as f:
|
|
||||||
commitHash = self.gitCommitHash(self.rootDir)
|
|
||||||
|
|
||||||
if len(commitHash) < 1:
|
|
||||||
commitHash = 'Unknown'
|
|
||||||
|
|
||||||
print(' Commit hash: ' + commitHash)
|
|
||||||
f.write('Commit hash: ' + commitHash + '\n')
|
|
||||||
|
|
||||||
buildLogUrl = ''
|
|
||||||
|
|
||||||
if 'TRAVIS_BUILD_WEB_URL' in os.environ:
|
|
||||||
buildLogUrl = os.environ['TRAVIS_BUILD_WEB_URL']
|
|
||||||
elif 'APPVEYOR_ACCOUNT_NAME' in os.environ and 'APPVEYOR_PROJECT_NAME' in os.environ and 'APPVEYOR_JOB_ID' in os.environ:
|
|
||||||
buildLogUrl = 'https://ci.appveyor.com/project/{}/{}/build/job/{}'.format(os.environ['APPVEYOR_ACCOUNT_NAME'],
|
|
||||||
os.environ['APPVEYOR_PROJECT_SLUG'],
|
|
||||||
os.environ['APPVEYOR_JOB_ID'])
|
|
||||||
|
|
||||||
if len(buildLogUrl) > 0:
|
|
||||||
print(' Build log URL: ' + buildLogUrl)
|
|
||||||
f.write('Build log URL: ' + buildLogUrl + '\n')
|
|
||||||
|
|
||||||
print()
|
|
||||||
f.write('\n')
|
|
||||||
|
|
||||||
# Write host info.
|
|
||||||
|
|
||||||
info = self.sysInfo()
|
|
||||||
|
|
||||||
with open(depsInfoFile, 'a') as f:
|
|
||||||
for line in info.split('\n'):
|
|
||||||
if len(line) > 0:
|
|
||||||
print(' ' + line)
|
|
||||||
f.write(line + '\n')
|
|
||||||
|
|
||||||
print()
|
|
||||||
f.write('\n')
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def hrSize(size):
|
|
||||||
i = int(math.log(size) // math.log(1024))
|
|
||||||
|
|
||||||
if i < 1:
|
|
||||||
return '{} B'.format(size)
|
|
||||||
|
|
||||||
units = ['KiB', 'MiB', 'GiB', 'TiB']
|
|
||||||
sizeKiB = size / (1024 ** i)
|
|
||||||
|
|
||||||
return '{:.2f} {}'.format(sizeKiB, units[i - 1])
|
|
||||||
|
|
||||||
def printPackageInfo(self, path):
|
|
||||||
if os.path.exists(path):
|
|
||||||
print(' ',
|
|
||||||
os.path.basename(path),
|
|
||||||
self.hrSize(os.path.getsize(path)))
|
|
||||||
print(' sha256sum:', Deploy.sha256sum(path))
|
|
||||||
else:
|
|
||||||
print(' ',
|
|
||||||
os.path.basename(path),
|
|
||||||
'FAILED')
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def dirSize(path):
|
|
||||||
size = 0
|
|
||||||
|
|
||||||
for root, _, files in os.walk(path):
|
|
||||||
for f in files:
|
|
||||||
fpath = os.path.join(root, f)
|
|
||||||
|
|
||||||
if not os.path.islink(fpath):
|
|
||||||
size += os.path.getsize(fpath)
|
|
||||||
|
|
||||||
return size
|
|
||||||
|
|
||||||
def signPackage(self, package):
|
|
||||||
process = subprocess.Popen(['codesign', # nosec
|
|
||||||
'--force',
|
|
||||||
'--sign',
|
|
||||||
'-',
|
|
||||||
package],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
process.communicate()
|
|
||||||
|
|
||||||
def createAppInstaller(self, mutex):
|
|
||||||
packagePath = self.createInstaller()
|
|
||||||
|
|
||||||
if not packagePath:
|
|
||||||
return
|
|
||||||
|
|
||||||
mutex.acquire()
|
|
||||||
print('Created installable package:')
|
|
||||||
self.printPackageInfo(self.outPackage)
|
|
||||||
mutex.release()
|
|
||||||
|
|
||||||
def package(self):
|
|
||||||
mutex = threading.Lock()
|
|
||||||
threads = []
|
|
||||||
packagingTools = []
|
|
||||||
|
|
||||||
if self.qtIFW != '':
|
|
||||||
threads.append(threading.Thread(target=self.createAppInstaller, args=(mutex,)))
|
|
||||||
packagingTools += ['Qt Installer Framework']
|
|
||||||
|
|
||||||
if len(packagingTools) > 0:
|
|
||||||
print('Detected packaging tools: {}\n'.format(', '.join(packagingTools)))
|
|
||||||
|
|
||||||
for thread in threads:
|
|
||||||
thread.start()
|
|
||||||
|
|
||||||
for thread in threads:
|
|
||||||
thread.join()
|
|
|
@ -1,468 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Webcamoid, webcam capture application.
|
|
||||||
# Copyright (C) 2017 Gonzalo Exequiel Pedone
|
|
||||||
#
|
|
||||||
# Webcamoid is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Webcamoid is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Webcamoid. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# Web-Site: http://webcamoid.github.io/
|
|
||||||
|
|
||||||
import configparser
|
|
||||||
import math
|
|
||||||
import os
|
|
||||||
import platform
|
|
||||||
import subprocess # nosec
|
|
||||||
import sys
|
|
||||||
import tarfile
|
|
||||||
import threading
|
|
||||||
|
|
||||||
from WebcamoidDeployTools import DTDeployBase
|
|
||||||
from WebcamoidDeployTools import DTQt5
|
|
||||||
from WebcamoidDeployTools import DTBinaryElf
|
|
||||||
|
|
||||||
|
|
||||||
class Deploy(DTDeployBase.DeployBase, DTQt5.Qt5Tools):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
rootDir = os.path.normpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../..'))
|
|
||||||
self.setRootDir(rootDir)
|
|
||||||
self.pkgsDir = os.path.join(self.buildDir, 'ports/deploy/packages_auto', sys.platform)
|
|
||||||
self.detectQtIFW()
|
|
||||||
self.detectQtIFWVersion()
|
|
||||||
self.rootInstallDir = os.path.join(self.installDir, self.qmakeQuery(var='QT_INSTALL_PREFIX')[1:])
|
|
||||||
self.packageConfig = os.path.join(self.buildDir, 'package_info.conf')
|
|
||||||
self.binaryInstallDir = os.path.join(self.rootInstallDir, 'bin')
|
|
||||||
self.mainBinary = os.path.join(self.binaryInstallDir, 'webcamoid')
|
|
||||||
self.programName = os.path.basename(self.mainBinary)
|
|
||||||
self.detectMake()
|
|
||||||
targetPlatform = self.targetPlatform()
|
|
||||||
|
|
||||||
if targetPlatform == 'windows':
|
|
||||||
self.targetSystem = 'posix_windows'
|
|
||||||
elif targetPlatform == 'android':
|
|
||||||
self.targetSystem = 'android'
|
|
||||||
|
|
||||||
self.binarySolver = DTBinaryElf.ElfBinaryTools()
|
|
||||||
self.binarySolver.readExcludes(os.name, sys.platform)
|
|
||||||
self.dependencies = []
|
|
||||||
self.installerConfig = os.path.join(self.installDir, 'installer/config')
|
|
||||||
self.installerPackages = os.path.join(self.installDir, 'installer/packages')
|
|
||||||
self.installerIconSize = 128
|
|
||||||
self.appIcon = os.path.join(self.installDir,
|
|
||||||
'usr/share/icons/hicolor/{1}x{1}/apps/{0}.png'.format(self.programName,
|
|
||||||
self.installerIconSize))
|
|
||||||
self.licenseFile = os.path.join(self.rootDir, 'COPYING')
|
|
||||||
self.installerRunProgram = '@TargetDir@/' + self.programName + '.sh'
|
|
||||||
self.installerTargetDir = '@HomeDir@/' + self.programName
|
|
||||||
self.installerScript = os.path.join(self.rootDir, 'ports/deploy/installscript.posix.qs')
|
|
||||||
self.changeLog = os.path.join(self.rootDir, 'ChangeLog')
|
|
||||||
self.outPackage = os.path.join(self.pkgsDir,
|
|
||||||
'{}-installer-{}-{}.run'.format(self.programName,
|
|
||||||
self.programVersion(),
|
|
||||||
platform.machine()))
|
|
||||||
|
|
||||||
def detectAppImage(self):
|
|
||||||
if 'APPIMAGETOOL' in os.environ:
|
|
||||||
return os.environ['APPIMAGETOOL']
|
|
||||||
|
|
||||||
appimagetool = self.whereBin('appimagetool')
|
|
||||||
|
|
||||||
if len(appimagetool) > 0:
|
|
||||||
return appimagetool
|
|
||||||
|
|
||||||
if self.targetArch == '32bit':
|
|
||||||
return self.whereBin('appimagetool-i686.AppImage')
|
|
||||||
|
|
||||||
return self.whereBin('appimagetool-x86_64.AppImage')
|
|
||||||
|
|
||||||
def solvedepsLibs(self):
|
|
||||||
qtLibsPath = self.qmakeQuery(var='QT_INSTALL_LIBS')
|
|
||||||
self.binarySolver.ldLibraryPath.append(qtLibsPath)
|
|
||||||
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, True)
|
|
||||||
self.dependencies.append(dep)
|
|
||||||
|
|
||||||
def prepare(self):
|
|
||||||
self.detectTargetArch()
|
|
||||||
self.appImage = self.detectAppImage()
|
|
||||||
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('Writting launcher file')
|
|
||||||
self.createLauncher()
|
|
||||||
print('\nWritting build system information\n')
|
|
||||||
self.writeBuildInfo()
|
|
||||||
|
|
||||||
def searchPackageFor(self, path):
|
|
||||||
os.environ['LC_ALL'] = 'C'
|
|
||||||
pacman = self.whereBin('pacman')
|
|
||||||
|
|
||||||
if len(pacman) > 0:
|
|
||||||
process = subprocess.Popen([pacman, '-Qo', path], # nosec
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, _ = process.communicate()
|
|
||||||
|
|
||||||
if process.returncode != 0:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
info = stdout.decode(sys.getdefaultencoding()).split(' ')
|
|
||||||
|
|
||||||
if len(info) < 2:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
package, version = info[-2:]
|
|
||||||
|
|
||||||
return ' '.join([package.strip(), version.strip()])
|
|
||||||
|
|
||||||
dpkg = self.whereBin('dpkg')
|
|
||||||
|
|
||||||
if len(dpkg) > 0:
|
|
||||||
process = subprocess.Popen([dpkg, '-S', path], # nosec
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, _ = process.communicate()
|
|
||||||
|
|
||||||
if process.returncode != 0:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
package = stdout.split(b':')[0].decode(sys.getdefaultencoding()).strip()
|
|
||||||
|
|
||||||
process = subprocess.Popen([dpkg, '-s', package], # nosec
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, _ = process.communicate()
|
|
||||||
|
|
||||||
if process.returncode != 0:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
for line in stdout.decode(sys.getdefaultencoding()).split('\n'):
|
|
||||||
line = line.strip()
|
|
||||||
|
|
||||||
if line.startswith('Version:'):
|
|
||||||
return ' '.join([package, line.split()[1].strip()])
|
|
||||||
|
|
||||||
return ''
|
|
||||||
|
|
||||||
rpm = self.whereBin('rpm')
|
|
||||||
|
|
||||||
if len(rpm) > 0:
|
|
||||||
process = subprocess.Popen([rpm, '-qf', path], # nosec
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, _ = process.communicate()
|
|
||||||
|
|
||||||
if process.returncode != 0:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
return stdout.decode(sys.getdefaultencoding()).strip()
|
|
||||||
|
|
||||||
pkg = self.whereBin('pkg')
|
|
||||||
|
|
||||||
if len(pkg) > 0:
|
|
||||||
process = subprocess.Popen([pkg, 'which', '-q', path], # nosec
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, _ = process.communicate()
|
|
||||||
|
|
||||||
if process.returncode != 0:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
return stdout.decode(sys.getdefaultencoding()).strip()
|
|
||||||
|
|
||||||
return ''
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def sysInfo():
|
|
||||||
info = ''
|
|
||||||
|
|
||||||
for f in os.listdir('/etc'):
|
|
||||||
if f.endswith('-release'):
|
|
||||||
with open(os.path.join('/etc' , f)) as releaseFile:
|
|
||||||
info += releaseFile.read()
|
|
||||||
|
|
||||||
if len(info) < 1:
|
|
||||||
info = ' '.join(platform.uname())
|
|
||||||
|
|
||||||
return info
|
|
||||||
|
|
||||||
def writeBuildInfo(self):
|
|
||||||
shareDir = os.path.join(self.rootInstallDir, 'share')
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.makedirs(self.pkgsDir)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
depsInfoFile = os.path.join(shareDir, 'build-info.txt')
|
|
||||||
|
|
||||||
if not os.path.exists(shareDir):
|
|
||||||
os.makedirs(shareDir)
|
|
||||||
|
|
||||||
# Write repository info.
|
|
||||||
|
|
||||||
with open(depsInfoFile, 'w') as f:
|
|
||||||
commitHash = self.gitCommitHash(self.rootDir)
|
|
||||||
|
|
||||||
if len(commitHash) < 1:
|
|
||||||
commitHash = 'Unknown'
|
|
||||||
|
|
||||||
print(' Commit hash: ' + commitHash)
|
|
||||||
f.write('Commit hash: ' + commitHash + '\n')
|
|
||||||
|
|
||||||
buildLogUrl = ''
|
|
||||||
|
|
||||||
if 'TRAVIS_BUILD_WEB_URL' in os.environ:
|
|
||||||
buildLogUrl = os.environ['TRAVIS_BUILD_WEB_URL']
|
|
||||||
elif 'APPVEYOR_ACCOUNT_NAME' in os.environ and 'APPVEYOR_PROJECT_NAME' in os.environ and 'APPVEYOR_JOB_ID' in os.environ:
|
|
||||||
buildLogUrl = 'https://ci.appveyor.com/project/{}/{}/build/job/{}'.format(os.environ['APPVEYOR_ACCOUNT_NAME'],
|
|
||||||
os.environ['APPVEYOR_PROJECT_SLUG'],
|
|
||||||
os.environ['APPVEYOR_JOB_ID'])
|
|
||||||
|
|
||||||
if len(buildLogUrl) > 0:
|
|
||||||
print(' Build log URL: ' + buildLogUrl)
|
|
||||||
f.write('Build log URL: ' + buildLogUrl + '\n')
|
|
||||||
|
|
||||||
print()
|
|
||||||
f.write('\n')
|
|
||||||
|
|
||||||
# Write host info.
|
|
||||||
|
|
||||||
info = self.sysInfo()
|
|
||||||
|
|
||||||
with open(depsInfoFile, 'a') as f:
|
|
||||||
for line in info.split('\n'):
|
|
||||||
if len(line) > 0:
|
|
||||||
print(' ' + line)
|
|
||||||
f.write(line + '\n')
|
|
||||||
|
|
||||||
print()
|
|
||||||
f.write('\n')
|
|
||||||
|
|
||||||
# Write binary dependencies info.
|
|
||||||
|
|
||||||
packages = set()
|
|
||||||
|
|
||||||
for dep in self.dependencies:
|
|
||||||
packageInfo = self.searchPackageFor(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')
|
|
||||||
|
|
||||||
def createLauncher(self):
|
|
||||||
path = os.path.join(self.rootInstallDir, self.programName) + '.sh'
|
|
||||||
libDir = self.qmakeQuery(var='QT_INSTALL_LIBS') \
|
|
||||||
.replace(self.qmakeQuery(var='QT_INSTALL_PREFIX'),
|
|
||||||
'${ROOTDIR}')
|
|
||||||
|
|
||||||
with open(path, 'w') as launcher:
|
|
||||||
launcher.write('#!/bin/sh\n')
|
|
||||||
launcher.write('\n')
|
|
||||||
launcher.write('path=$(realpath "$0")\n')
|
|
||||||
launcher.write('ROOTDIR=$(dirname "$path")\n')
|
|
||||||
launcher.write('export PATH="${ROOTDIR}/bin:$PATH"\n')
|
|
||||||
launcher.write('export LD_LIBRARY_PATH="{}:$LD_LIBRARY_PATH"\n'.format(libDir))
|
|
||||||
launcher.write('#export QT_DEBUG_PLUGINS=1\n')
|
|
||||||
launcher.write('{} "$@"\n'.format(self.programName))
|
|
||||||
|
|
||||||
os.chmod(path, 0o744)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def hrSize(size):
|
|
||||||
i = int(math.log(size) // math.log(1024))
|
|
||||||
|
|
||||||
if i < 1:
|
|
||||||
return '{} B'.format(size)
|
|
||||||
|
|
||||||
units = ['KiB', 'MiB', 'GiB', 'TiB']
|
|
||||||
sizeKiB = size / (1024 ** i)
|
|
||||||
|
|
||||||
return '{:.2f} {}'.format(sizeKiB, units[i - 1])
|
|
||||||
|
|
||||||
def printPackageInfo(self, path):
|
|
||||||
if os.path.exists(path):
|
|
||||||
print(' ',
|
|
||||||
os.path.basename(path),
|
|
||||||
self.hrSize(os.path.getsize(path)))
|
|
||||||
print(' sha256sum:', Deploy.sha256sum(path))
|
|
||||||
else:
|
|
||||||
print(' ',
|
|
||||||
os.path.basename(path),
|
|
||||||
'FAILED')
|
|
||||||
|
|
||||||
def createPortable(self, mutex):
|
|
||||||
packagePath = \
|
|
||||||
os.path.join(self.pkgsDir,
|
|
||||||
'{}-portable-{}-{}.tar.xz'.format(self.programName,
|
|
||||||
self.programVersion(),
|
|
||||||
platform.machine()))
|
|
||||||
|
|
||||||
if not os.path.exists(self.pkgsDir):
|
|
||||||
os.makedirs(self.pkgsDir)
|
|
||||||
|
|
||||||
with tarfile.open(packagePath, 'w:xz') as tar:
|
|
||||||
tar.add(self.rootInstallDir, self.programName)
|
|
||||||
|
|
||||||
mutex.acquire()
|
|
||||||
print('Created portable package:')
|
|
||||||
self.printPackageInfo(packagePath)
|
|
||||||
mutex.release()
|
|
||||||
|
|
||||||
def createAppInstaller(self, mutex):
|
|
||||||
packagePath = self.createInstaller()
|
|
||||||
|
|
||||||
if not packagePath:
|
|
||||||
return
|
|
||||||
|
|
||||||
mutex.acquire()
|
|
||||||
print('Created installable package:')
|
|
||||||
self.printPackageInfo(self.outPackage)
|
|
||||||
mutex.release()
|
|
||||||
|
|
||||||
def createAppImage(self, mutex):
|
|
||||||
if not os.path.exists(self.appImage):
|
|
||||||
return
|
|
||||||
|
|
||||||
appDir = \
|
|
||||||
os.path.join(self.installDir,
|
|
||||||
'{}-{}-{}.AppDir'.format(self.programName,
|
|
||||||
self.programVersion(),
|
|
||||||
platform.machine()))
|
|
||||||
|
|
||||||
usrDir = os.path.join(appDir, 'usr')
|
|
||||||
|
|
||||||
if not os.path.exists(usrDir):
|
|
||||||
os.makedirs(usrDir)
|
|
||||||
|
|
||||||
self.copy(self.rootInstallDir, usrDir)
|
|
||||||
launcher = os.path.join(appDir, 'AppRun')
|
|
||||||
|
|
||||||
if not os.path.exists(launcher):
|
|
||||||
os.symlink('./usr/webcamoid.sh', launcher)
|
|
||||||
|
|
||||||
desktopFile = os.path.join(appDir, 'webcamoid.desktop')
|
|
||||||
|
|
||||||
if os.path.exists(desktopFile):
|
|
||||||
os.remove(desktopFile)
|
|
||||||
|
|
||||||
self.copy(os.path.join(usrDir, 'share/applications/webcamoid.desktop'), desktopFile)
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config.optionxform=str
|
|
||||||
config.read(desktopFile, 'utf-8')
|
|
||||||
config['Desktop Entry']['Exec'] = 'webcamoid.sh'
|
|
||||||
del config['Desktop Entry']['Keywords']
|
|
||||||
|
|
||||||
with open(desktopFile, 'w', encoding='utf-8') as configFile:
|
|
||||||
config.write(configFile, space_around_delimiters=False)
|
|
||||||
|
|
||||||
icons = {'webcamoid.png': '256x256', '.DirIcon': '48x48'}
|
|
||||||
|
|
||||||
for icon in icons:
|
|
||||||
iconPath = os.path.join(appDir, icon)
|
|
||||||
|
|
||||||
if not os.path.exists(icon):
|
|
||||||
sourceIcon = os.path.join(usrDir,
|
|
||||||
'share/icons/hicolor/{}/apps/webcamoid.png'.format(icons[icon]))
|
|
||||||
self.copy(sourceIcon, iconPath)
|
|
||||||
|
|
||||||
# Remove old file
|
|
||||||
packagePath = \
|
|
||||||
os.path.join(self.pkgsDir,
|
|
||||||
'{}-{}-{}.AppImage'.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)
|
|
||||||
|
|
||||||
penv = os.environ.copy()
|
|
||||||
penv['ARCH'] = platform.machine()
|
|
||||||
|
|
||||||
libPaths = []
|
|
||||||
|
|
||||||
if 'LD_LIBRARY_PATH' in penv:
|
|
||||||
libPaths = penv['LD_LIBRARY_PATH'].split(':')
|
|
||||||
|
|
||||||
libDir = os.path.relpath(self.qmakeQuery(var='QT_INSTALL_LIBS'),
|
|
||||||
self.qmakeQuery(var='QT_INSTALL_PREFIX'))
|
|
||||||
penv['LD_LIBRARY_PATH'] = \
|
|
||||||
':'.join([os.path.abspath(os.path.join(self.appImage, '../..', libDir)),
|
|
||||||
os.path.abspath(os.path.join(self.appImage, '../../lib'))]
|
|
||||||
+ libPaths)
|
|
||||||
|
|
||||||
process = subprocess.Popen([self.appImage, # nosec
|
|
||||||
'-v',
|
|
||||||
'--no-appstream',
|
|
||||||
'--comp', 'xz',
|
|
||||||
appDir,
|
|
||||||
packagePath],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE,
|
|
||||||
env=penv)
|
|
||||||
process.communicate()
|
|
||||||
|
|
||||||
mutex.acquire()
|
|
||||||
print('Created AppImage package:')
|
|
||||||
self.printPackageInfo(packagePath)
|
|
||||||
mutex.release()
|
|
||||||
|
|
||||||
def package(self):
|
|
||||||
mutex = threading.Lock()
|
|
||||||
|
|
||||||
threads = [threading.Thread(target=self.createPortable, args=(mutex,))]
|
|
||||||
packagingTools = ['tar.xz']
|
|
||||||
|
|
||||||
if self.qtIFW != '':
|
|
||||||
threads.append(threading.Thread(target=self.createAppInstaller, args=(mutex,)))
|
|
||||||
packagingTools += ['Qt Installer Framework']
|
|
||||||
|
|
||||||
if self.appImage != '':
|
|
||||||
threads.append(threading.Thread(target=self.createAppImage, args=(mutex,)))
|
|
||||||
packagingTools += ['AppImage']
|
|
||||||
|
|
||||||
if len(packagingTools) > 0:
|
|
||||||
print('Detected packaging tools: {}\n'.format(', '.join(packagingTools)))
|
|
||||||
|
|
||||||
for thread in threads:
|
|
||||||
thread.start()
|
|
||||||
|
|
||||||
for thread in threads:
|
|
||||||
thread.join()
|
|
|
@ -1,249 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Webcamoid, webcam capture application.
|
|
||||||
# Copyright (C) 2017 Gonzalo Exequiel Pedone
|
|
||||||
#
|
|
||||||
# Webcamoid is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Webcamoid is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Webcamoid. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# Web-Site: http://webcamoid.github.io/
|
|
||||||
|
|
||||||
import math
|
|
||||||
import os
|
|
||||||
import subprocess # nosec
|
|
||||||
import sys
|
|
||||||
import threading
|
|
||||||
import zipfile
|
|
||||||
|
|
||||||
from WebcamoidDeployTools import DTDeployBase
|
|
||||||
from WebcamoidDeployTools import DTQt5
|
|
||||||
from WebcamoidDeployTools import DTBinaryPecoff
|
|
||||||
|
|
||||||
|
|
||||||
class Deploy(DTDeployBase.DeployBase, DTQt5.Qt5Tools):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
rootDir = os.path.normpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../..'))
|
|
||||||
self.setRootDir(rootDir)
|
|
||||||
self.targetSystem = 'posix_windows'
|
|
||||||
self.pkgsDir = os.path.join(self.buildDir, 'ports/deploy/packages_auto/windows')
|
|
||||||
self.detectQtIFW()
|
|
||||||
self.detectQtIFWVersion()
|
|
||||||
self.programName = 'AkVirtualCamera'
|
|
||||||
self.adminRights = True
|
|
||||||
self.packageConfig = os.path.join(self.buildDir, 'package_info.conf')
|
|
||||||
self.rootInstallDir = os.path.join(self.installDir, self.programName + '.plugin')
|
|
||||||
self.binaryInstallDir = os.path.join(self.rootInstallDir, 'bin')
|
|
||||||
self.mainBinary = os.path.join(self.binaryInstallDir, self.programName + '.exe')
|
|
||||||
self.programName = os.path.splitext(os.path.basename(self.mainBinary))[0]
|
|
||||||
self.detectMake()
|
|
||||||
self.binarySolver = DTBinaryPecoff.PecoffBinaryTools()
|
|
||||||
self.binarySolver.readExcludes(os.name, sys.platform)
|
|
||||||
self.dependencies = []
|
|
||||||
self.installerConfig = os.path.join(self.installDir, 'installer/config')
|
|
||||||
self.installerPackages = os.path.join(self.installDir, 'installer/packages')
|
|
||||||
self.licenseFile = os.path.join(self.rootDir, 'COPYING')
|
|
||||||
self.installerScript = os.path.join(self.rootDir, 'ports/deploy/installscript.windows.qs')
|
|
||||||
self.changeLog = os.path.join(self.rootDir, 'ChangeLog')
|
|
||||||
self.targetArch = '64bit' if 'x86_64' in self.qtInstallBins else '32bit'
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def removeUnneededFiles(path):
|
|
||||||
afiles = set()
|
|
||||||
|
|
||||||
for root, _, files in os.walk(path):
|
|
||||||
for f in files:
|
|
||||||
if f.endswith('.a') \
|
|
||||||
or f.endswith('.static.prl') \
|
|
||||||
or f.endswith('.pdb') \
|
|
||||||
or f.endswith('.lib'):
|
|
||||||
afiles.add(os.path.join(root, f))
|
|
||||||
|
|
||||||
for afile in afiles:
|
|
||||||
os.remove(afile)
|
|
||||||
|
|
||||||
def prepare(self):
|
|
||||||
if self.targetArch == '32bit':
|
|
||||||
self.binarySolver.sysBinsPath = ['/usr/i686-w64-mingw32/bin']
|
|
||||||
else:
|
|
||||||
self.binarySolver.sysBinsPath = ['/usr/x86_64-w64-mingw32/bin']
|
|
||||||
|
|
||||||
self.binarySolver.detectStrip()
|
|
||||||
|
|
||||||
if self.qtIFWVersion == '' or int(self.qtIFWVersion.split('.')[0]) < 3:
|
|
||||||
appsDir = '@ApplicationsDir@'
|
|
||||||
else:
|
|
||||||
if self.targetArch == '32bit':
|
|
||||||
appsDir = '@ApplicationsDirX86@'
|
|
||||||
else:
|
|
||||||
appsDir = '@ApplicationsDirX64@'
|
|
||||||
|
|
||||||
self.installerTargetDir = appsDir + '/' + self.programName + '.plugin'
|
|
||||||
arch = 'win32' if self.targetArch == '32bit' else 'win64'
|
|
||||||
self.outPackage = os.path.join(self.pkgsDir,
|
|
||||||
'{}-{}-{}.exe'.format(self.programName,
|
|
||||||
self.programVersion(),
|
|
||||||
arch))
|
|
||||||
|
|
||||||
print('Stripping symbols')
|
|
||||||
self.binarySolver.stripSymbols(self.installDir)
|
|
||||||
print('Removing unnecessary files')
|
|
||||||
self.removeUnneededFiles(self.installDir)
|
|
||||||
print('\nWritting build system information\n')
|
|
||||||
self.writeBuildInfo()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def sysInfo():
|
|
||||||
info = ''
|
|
||||||
|
|
||||||
for f in os.listdir('/etc'):
|
|
||||||
if f.endswith('-release'):
|
|
||||||
with open(os.path.join('/etc' , f)) as releaseFile:
|
|
||||||
info += releaseFile.read()
|
|
||||||
|
|
||||||
return info
|
|
||||||
|
|
||||||
def writeBuildInfo(self):
|
|
||||||
try:
|
|
||||||
os.makedirs(self.pkgsDir)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
shareDir = os.path.join(self.rootInstallDir, 'share')
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.makedirs(shareDir)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
depsInfoFile = os.path.join(shareDir, 'build-info.txt')
|
|
||||||
|
|
||||||
# Write repository info.
|
|
||||||
|
|
||||||
with open(depsInfoFile, 'w') as f:
|
|
||||||
commitHash = self.gitCommitHash(self.rootDir)
|
|
||||||
|
|
||||||
if len(commitHash) < 1:
|
|
||||||
commitHash = 'Unknown'
|
|
||||||
|
|
||||||
print(' Commit hash: ' + commitHash)
|
|
||||||
f.write('Commit hash: ' + commitHash + '\n')
|
|
||||||
|
|
||||||
buildLogUrl = ''
|
|
||||||
|
|
||||||
if 'TRAVIS_BUILD_WEB_URL' in os.environ:
|
|
||||||
buildLogUrl = os.environ['TRAVIS_BUILD_WEB_URL']
|
|
||||||
elif 'APPVEYOR_ACCOUNT_NAME' in os.environ and 'APPVEYOR_PROJECT_NAME' in os.environ and 'APPVEYOR_JOB_ID' in os.environ:
|
|
||||||
buildLogUrl = 'https://ci.appveyor.com/project/{}/{}/build/job/{}'.format(os.environ['APPVEYOR_ACCOUNT_NAME'],
|
|
||||||
os.environ['APPVEYOR_PROJECT_SLUG'],
|
|
||||||
os.environ['APPVEYOR_JOB_ID'])
|
|
||||||
|
|
||||||
if len(buildLogUrl) > 0:
|
|
||||||
print(' Build log URL: ' + buildLogUrl)
|
|
||||||
f.write('Build log URL: ' + buildLogUrl + '\n')
|
|
||||||
|
|
||||||
print()
|
|
||||||
f.write('\n')
|
|
||||||
|
|
||||||
# Write host info.
|
|
||||||
|
|
||||||
info = self.sysInfo()
|
|
||||||
|
|
||||||
with open(depsInfoFile, 'a') as f:
|
|
||||||
for line in info.split('\n'):
|
|
||||||
if len(line) > 0:
|
|
||||||
print(' ' + line)
|
|
||||||
f.write(line + '\n')
|
|
||||||
|
|
||||||
print()
|
|
||||||
f.write('\n')
|
|
||||||
|
|
||||||
# Write Wine version and emulated system info.
|
|
||||||
|
|
||||||
process = subprocess.Popen(['wine', '--version'], # nosec
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, _ = process.communicate()
|
|
||||||
wineVersion = stdout.decode(sys.getdefaultencoding()).strip()
|
|
||||||
|
|
||||||
with open(depsInfoFile, 'a') as f:
|
|
||||||
print(' Wine Version: {}'.format(wineVersion))
|
|
||||||
f.write('Wine Version: {}\n'.format(wineVersion))
|
|
||||||
|
|
||||||
process = subprocess.Popen(['wine', 'cmd', '/c', 'ver'], # nosec
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, _ = process.communicate()
|
|
||||||
fakeWindowsVersion = stdout.decode(sys.getdefaultencoding()).strip()
|
|
||||||
|
|
||||||
if len(fakeWindowsVersion) < 1:
|
|
||||||
fakeWindowsVersion = 'Unknown'
|
|
||||||
|
|
||||||
with open(depsInfoFile, 'a') as f:
|
|
||||||
print(' Windows Version: {}'.format(fakeWindowsVersion))
|
|
||||||
f.write('Windows Version: {}\n'.format(fakeWindowsVersion))
|
|
||||||
print()
|
|
||||||
f.write('\n')
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def hrSize(size):
|
|
||||||
i = int(math.log(size) // math.log(1024))
|
|
||||||
|
|
||||||
if i < 1:
|
|
||||||
return '{} B'.format(size)
|
|
||||||
|
|
||||||
units = ['KiB', 'MiB', 'GiB', 'TiB']
|
|
||||||
sizeKiB = size / (1024 ** i)
|
|
||||||
|
|
||||||
return '{:.2f} {}'.format(sizeKiB, units[i - 1])
|
|
||||||
|
|
||||||
def printPackageInfo(self, path):
|
|
||||||
if os.path.exists(path):
|
|
||||||
print(' ',
|
|
||||||
os.path.basename(path),
|
|
||||||
self.hrSize(os.path.getsize(path)))
|
|
||||||
print(' sha256sum:', Deploy.sha256sum(path))
|
|
||||||
else:
|
|
||||||
print(' ',
|
|
||||||
os.path.basename(path),
|
|
||||||
'FAILED')
|
|
||||||
|
|
||||||
def createAppInstaller(self, mutex):
|
|
||||||
packagePath = self.createInstaller()
|
|
||||||
|
|
||||||
if not packagePath:
|
|
||||||
return
|
|
||||||
|
|
||||||
mutex.acquire()
|
|
||||||
print('Created installable package:')
|
|
||||||
self.printPackageInfo(self.outPackage)
|
|
||||||
mutex.release()
|
|
||||||
|
|
||||||
def package(self):
|
|
||||||
mutex = threading.Lock()
|
|
||||||
threads = []
|
|
||||||
packagingTools = []
|
|
||||||
|
|
||||||
if self.qtIFW != '':
|
|
||||||
threads.append(threading.Thread(target=self.createAppInstaller, args=(mutex,)))
|
|
||||||
packagingTools += ['Qt Installer Framework']
|
|
||||||
|
|
||||||
if len(packagingTools) > 0:
|
|
||||||
print('Detected packaging tools: {}\n'.format(', '.join(packagingTools)))
|
|
||||||
|
|
||||||
for thread in threads:
|
|
||||||
thread.start()
|
|
||||||
|
|
||||||
for thread in threads:
|
|
||||||
thread.join()
|
|
|
@ -1,222 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Webcamoid, webcam capture application.
|
|
||||||
# Copyright (C) 2017 Gonzalo Exequiel Pedone
|
|
||||||
#
|
|
||||||
# Webcamoid is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Webcamoid is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Webcamoid. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# Web-Site: http://webcamoid.github.io/
|
|
||||||
|
|
||||||
import math
|
|
||||||
import os
|
|
||||||
import platform
|
|
||||||
import subprocess # nosec
|
|
||||||
import sys
|
|
||||||
import threading
|
|
||||||
import zipfile
|
|
||||||
|
|
||||||
from WebcamoidDeployTools import DTDeployBase
|
|
||||||
from WebcamoidDeployTools import DTQt5
|
|
||||||
from WebcamoidDeployTools import DTBinaryPecoff
|
|
||||||
|
|
||||||
|
|
||||||
class Deploy(DTDeployBase.DeployBase, DTQt5.Qt5Tools):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
rootDir = os.path.normpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../..'))
|
|
||||||
self.setRootDir(rootDir)
|
|
||||||
self.pkgsDir = os.path.join(self.buildDir, 'ports/deploy/packages_auto/windows')
|
|
||||||
self.detectQtIFW()
|
|
||||||
self.detectQtIFWVersion()
|
|
||||||
self.adminRights = True
|
|
||||||
self.programName = 'AkVirtualCamera'
|
|
||||||
self.packageConfig = os.path.join(self.buildDir, 'package_info.conf')
|
|
||||||
self.rootInstallDir = os.path.join(self.installDir, self.programName + '.plugin')
|
|
||||||
self.binaryInstallDir = os.path.join(self.rootInstallDir, 'bin')
|
|
||||||
self.mainBinary = os.path.join(self.binaryInstallDir, self.programName + '.exe')
|
|
||||||
self.programName = os.path.splitext(os.path.basename(self.mainBinary))[0]
|
|
||||||
self.detectMake()
|
|
||||||
self.binarySolver = DTBinaryPecoff.PecoffBinaryTools()
|
|
||||||
self.binarySolver.readExcludes(os.name, sys.platform)
|
|
||||||
self.dependencies = []
|
|
||||||
self.installerConfig = os.path.join(self.installDir, 'installer/config')
|
|
||||||
self.installerPackages = os.path.join(self.installDir, 'installer/packages')
|
|
||||||
self.licenseFile = os.path.join(self.rootDir, 'COPYING')
|
|
||||||
self.installerScript = os.path.join(self.rootDir, 'ports/deploy/installscript.windows.qs')
|
|
||||||
self.changeLog = os.path.join(self.rootDir, 'ChangeLog')
|
|
||||||
|
|
||||||
def prepare(self):
|
|
||||||
self.detectTargetArch()
|
|
||||||
|
|
||||||
if self.qtIFWVersion == '' or int(self.qtIFWVersion.split('.')[0]) < 3:
|
|
||||||
appsDir = '@ApplicationsDir@'
|
|
||||||
else:
|
|
||||||
if self.targetArch == '32bit':
|
|
||||||
appsDir = '@ApplicationsDirX86@'
|
|
||||||
else:
|
|
||||||
appsDir = '@ApplicationsDirX64@'
|
|
||||||
|
|
||||||
self.installerTargetDir = appsDir + '/' + self.programName + '.plugin'
|
|
||||||
arch = 'win32' if self.targetArch == '32bit' else 'win64'
|
|
||||||
self.outPackage = os.path.join(self.pkgsDir,
|
|
||||||
'{}-{}-{}.exe'.format(self.programName,
|
|
||||||
self.programVersion(),
|
|
||||||
arch))
|
|
||||||
|
|
||||||
print('Stripping symbols')
|
|
||||||
self.binarySolver.stripSymbols(self.installDir)
|
|
||||||
print('Removing unnecessary files')
|
|
||||||
self.removeUnneededFiles(self.installDir)
|
|
||||||
print('\nWritting build system information\n')
|
|
||||||
self.writeBuildInfo()
|
|
||||||
|
|
||||||
def removeDebugs(self):
|
|
||||||
dbgFiles = set()
|
|
||||||
|
|
||||||
for root, _, files in os.walk(self.libQtInstallDir):
|
|
||||||
for f in files:
|
|
||||||
if f.endswith('.dll'):
|
|
||||||
fname, ext = os.path.splitext(f)
|
|
||||||
dbgFile = os.path.join(root, '{}d{}'.format(fname, ext))
|
|
||||||
|
|
||||||
if os.path.exists(dbgFile):
|
|
||||||
dbgFiles.add(dbgFile)
|
|
||||||
|
|
||||||
for f in dbgFiles:
|
|
||||||
os.remove(f)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def removeUnneededFiles(path):
|
|
||||||
afiles = set()
|
|
||||||
|
|
||||||
for root, _, files in os.walk(path):
|
|
||||||
for f in files:
|
|
||||||
if f.endswith('.a') \
|
|
||||||
or f.endswith('.static.prl') \
|
|
||||||
or f.endswith('.pdb') \
|
|
||||||
or f.endswith('.lib'):
|
|
||||||
afiles.add(os.path.join(root, f))
|
|
||||||
|
|
||||||
for afile in afiles:
|
|
||||||
os.remove(afile)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def sysInfo():
|
|
||||||
try:
|
|
||||||
process = subprocess.Popen(['cmd', '/c', 'ver'], # nosec
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, _ = process.communicate()
|
|
||||||
windowsVersion = stdout.decode(sys.getdefaultencoding()).strip()
|
|
||||||
|
|
||||||
return 'Windows Version: {}\n'.format(windowsVersion)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return ' '.join(platform.uname())
|
|
||||||
|
|
||||||
def writeBuildInfo(self):
|
|
||||||
try:
|
|
||||||
os.makedirs(self.pkgsDir)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
shareDir = os.path.join(self.rootInstallDir, 'share')
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.makedirs(shareDir)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
depsInfoFile = os.path.join(shareDir, 'build-info.txt')
|
|
||||||
|
|
||||||
# Write repository info.
|
|
||||||
|
|
||||||
with open(depsInfoFile, 'w') as f:
|
|
||||||
commitHash = self.gitCommitHash(self.rootDir)
|
|
||||||
|
|
||||||
if len(commitHash) < 1:
|
|
||||||
commitHash = 'Unknown'
|
|
||||||
|
|
||||||
print(' Commit hash: ' + commitHash)
|
|
||||||
f.write('Commit hash: ' + commitHash + '\n')
|
|
||||||
|
|
||||||
buildLogUrl = ''
|
|
||||||
|
|
||||||
if 'TRAVIS_BUILD_WEB_URL' in os.environ:
|
|
||||||
buildLogUrl = os.environ['TRAVIS_BUILD_WEB_URL']
|
|
||||||
elif 'APPVEYOR_ACCOUNT_NAME' in os.environ and 'APPVEYOR_PROJECT_NAME' in os.environ and 'APPVEYOR_JOB_ID' in os.environ:
|
|
||||||
buildLogUrl = 'https://ci.appveyor.com/project/{}/{}/build/job/{}'.format(os.environ['APPVEYOR_ACCOUNT_NAME'],
|
|
||||||
os.environ['APPVEYOR_PROJECT_SLUG'],
|
|
||||||
os.environ['APPVEYOR_JOB_ID'])
|
|
||||||
|
|
||||||
if len(buildLogUrl) > 0:
|
|
||||||
print(' Build log URL: ' + buildLogUrl)
|
|
||||||
f.write('Build log URL: ' + buildLogUrl + '\n')
|
|
||||||
|
|
||||||
print()
|
|
||||||
f.write('\n')
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def hrSize(size):
|
|
||||||
i = int(math.log(size) // math.log(1024))
|
|
||||||
|
|
||||||
if i < 1:
|
|
||||||
return '{} B'.format(size)
|
|
||||||
|
|
||||||
units = ['KiB', 'MiB', 'GiB', 'TiB']
|
|
||||||
sizeKiB = size / (1024 ** i)
|
|
||||||
|
|
||||||
return '{:.2f} {}'.format(sizeKiB, units[i - 1])
|
|
||||||
|
|
||||||
def printPackageInfo(self, path):
|
|
||||||
if os.path.exists(path):
|
|
||||||
print(' ',
|
|
||||||
os.path.basename(path),
|
|
||||||
self.hrSize(os.path.getsize(path)))
|
|
||||||
print(' sha256sum:', Deploy.sha256sum(path))
|
|
||||||
else:
|
|
||||||
print(' ',
|
|
||||||
os.path.basename(path),
|
|
||||||
'FAILED')
|
|
||||||
|
|
||||||
def createAppInstaller(self, mutex):
|
|
||||||
packagePath = self.createInstaller()
|
|
||||||
|
|
||||||
if not packagePath:
|
|
||||||
return
|
|
||||||
|
|
||||||
mutex.acquire()
|
|
||||||
print('Created installable package:')
|
|
||||||
self.printPackageInfo(self.outPackage)
|
|
||||||
mutex.release()
|
|
||||||
|
|
||||||
def package(self):
|
|
||||||
mutex = threading.Lock()
|
|
||||||
threads = []
|
|
||||||
packagingTools = []
|
|
||||||
|
|
||||||
if self.qtIFW != '':
|
|
||||||
threads.append(threading.Thread(target=self.createAppInstaller, args=(mutex,)))
|
|
||||||
packagingTools += ['Qt Installer Framework']
|
|
||||||
|
|
||||||
if len(packagingTools) > 0:
|
|
||||||
print('Detected packaging tools: {}\n'.format(', '.join(packagingTools)))
|
|
||||||
|
|
||||||
for thread in threads:
|
|
||||||
thread.start()
|
|
||||||
|
|
||||||
for thread in threads:
|
|
||||||
thread.join()
|
|
|
@ -1,13 +0,0 @@
|
||||||
function Component()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.prototype.beginInstallation = function()
|
|
||||||
{
|
|
||||||
component.beginInstallation();
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.prototype.createOperations = function()
|
|
||||||
{
|
|
||||||
component.createOperations();
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
[Package]
|
|
||||||
appName = AkVirtualCamera
|
|
||||||
packageName = akvirtualcamera
|
|
||||||
version = 9.0.0
|
|
||||||
description = AkVirtualCamera, virtual camera for Mac and Windows
|
|
||||||
url = https://github.com/webcamoid/akvirtualcamera
|
|
||||||
licenseDescription = GNU General Public License v3.0
|
|
Loading…
Reference in a new issue