Support outputdir option

Signed-off-by: Hiroshi Miura <miurahr@linux.com>
This commit is contained in:
Hiroshi Miura
2019-03-16 10:48:03 +09:00
parent 1d9488198e
commit 5fa5b044b5
5 changed files with 183 additions and 169 deletions

View File

@@ -16,6 +16,7 @@ Added
* sphnix document.
* test packaging on CI.
* cli: output directory option.
Changed
-------

View File

@@ -30,7 +30,7 @@ Another Qt installer(aqt)
This is an utility replacing the official graphical Qt installer. It can
automatically download prebuilt Qt binaries for any target (you're not bound to
Linux binaries on Linux; you could also download iOS binaries).
It's working on Linux, OS X and Windows.
It's working with python on Linux, OS X and Windows.
Prerequisite
------------

View File

@@ -35,6 +35,7 @@ class Cli():
arch = args.arch
target = args.target
os_name = args.host
output_dir = args.outputdir
if arch is None:
if os_name == "linux" and target == "desktop":
arch = "gcc_64"
@@ -48,7 +49,10 @@ class Cli():
exit(1)
qt_version = args.qt_version
QtInstaller(QtArchives(os_name, qt_version, target, arch)).install()
if output_dir is not None:
QtInstaller(QtArchives(os_name, qt_version, target, arch)).install(target_dir=output_dir)
else:
QtInstaller(QtArchives(os_name, qt_version, target, arch)).install()
sys.stdout.write("\033[K")
print("Finished installation")
@@ -76,6 +80,8 @@ class Cli():
"\nwindows/desktop: win64_msvc2017_64, win64_msvc2015_64"
"\n in32_msvc2015, win32_mingw53"
"\nandroid: android_x86, android_armv7")
install_parser.add_argument('-O', '--outputdir', nargs='?',
help='Target output directory(default current directory)')
list_parser = subparsers.add_parser('list')
list_parser.set_defaults(func=self.run_list)
list_parser.add_argument("qt_version", help="Qt version in the format of \"5.X.Y\"")

View File

@@ -20,6 +20,7 @@
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import functools
import logging
import os
import platform
@@ -29,6 +30,7 @@ import traceback
import aqt.metalink
from six import StringIO
from multiprocessing.dummy import Pool
from operator import and_
if sys.version_info.major == 3:
from subprocess import run
else:
@@ -39,24 +41,23 @@ NUM_PROCESS = 3
class QtInstaller:
"""
Installer class to download packages and extract it.
"""
def __init__(self, qt_archives):
self.qt_archives = qt_archives
@staticmethod
def retrieve_archive(package):
def retrieve_archive(package, path=None):
archive = package.get_archive()
url = package.get_url()
sys.stdout.write("\033[K")
print("-Downloading {}...".format(url))
try:
r = aqt.metalink.get(url, stream=True)
except requests.exceptions.ConnectionError as e:
print("Caught download error: %s" % e.args)
exc_buffer = StringIO()
traceback.print_exc(file=exc_buffer)
logging.error('Uncaught exception in worker process:\n%s', exc_buffer.getvalue())
raise e
return False
else:
with open(archive, 'wb') as fd:
for chunk in r.iter_content(chunk_size=8196):
@@ -64,50 +65,56 @@ class QtInstaller:
sys.stdout.write("\033[K")
print("-Extracting {}...".format(archive))
if platform.system() == 'Windows':
run([r'C:\Program Files\7-Zip\7z.exe', 'x', '-aoa', '-y', archive])
if path is not None:
run([r'C:\Program Files\7-Zip\7z.exe', 'x', '-aoa', '-y', '-o', path, archive])
else:
run([r'C:\Program Files\7-Zip\7z.exe', 'x', '-aoa', '-y', archive])
else:
run([r'7zr', 'x', '-aoa', '-y', archive])
if path is not None:
run([r'7zr', 'x', '-aoa', '-y', '-o', path, archive])
else:
run([r'7zr', 'x', '-aoa', '-y', archive])
os.unlink(archive)
return True
@staticmethod
def get_base_dir(qt_version):
return os.path.join(os.getcwd(), 'Qt{}'.format(qt_version))
def install(self):
qt_version, target, arch = self.qt_archives.get_target_config()
if arch.startswith('win'):
arch_dir = arch[6:]
def get_base_dir(qt_version, target_dir=None):
if target_dir is not None:
return os.path.join(target_dir, 'Qt{}'.format(qt_version))
else:
arch_dir = arch
base_dir = self.get_base_dir(qt_version)
if not os.path.exists(base_dir):
os.mkdir(base_dir)
elif not os.path.isdir(base_dir):
os.unlink(base_dir)
os.mkdir(base_dir)
os.chdir(base_dir)
return os.path.join(os.getcwd(), 'Qt{}'.format(qt_version))
def install(self, target_dir=None):
qt_version, target, arch = self.qt_archives.get_target_config()
base_dir = self.get_base_dir(qt_version, target_dir)
archives = self.qt_archives.get_archives()
p = Pool(NUM_PROCESS)
p.map(self.retrieve_archive, archives)
try:
# prepare qt.conf
with open(os.path.join(base_dir, qt_version, arch_dir, 'bin', 'qt.conf'), 'w') as f:
f.write("[Paths]\n")
f.write("Prefix=..\n")
# prepare qtconfig.pri
with open(os.path.join(base_dir, qt_version, arch_dir, 'mkspecs', 'qconfig.pri'), 'r+') as f:
lines = f.readlines()
f.seek(0)
f.truncate()
for line in lines:
if 'QT_EDITION' in line:
line = 'QT_EDITION = OpenSource'
f.write(line)
except IOError as e:
print("Configuration file generation error: %s" % e.args)
exc_buffer = StringIO()
traceback.print_exc(file=exc_buffer)
logging.error('Error happened when writing configuration files:\n%s', exc_buffer.getvalue())
raise e
ret_arr = p.map(functools.partial(self.retrieve_archive, path=base_dir), archives)
ret = functools.reduce(and_, ret_arr)
if ret:
if arch.startswith('win'):
arch_dir = arch[6:]
else:
arch_dir = arch
try:
# prepare qt.conf
with open(os.path.join(base_dir, qt_version, arch_dir, 'bin', 'qt.conf'), 'w') as f:
f.write("[Paths]\n")
f.write("Prefix=..\n")
# prepare qtconfig.pri
with open(os.path.join(base_dir, qt_version, arch_dir, 'mkspecs', 'qconfig.pri'), 'r+') as f:
lines = f.readlines()
f.seek(0)
f.truncate()
for line in lines:
if 'QT_EDITION' in line:
line = 'QT_EDITION = OpenSource'
f.write(line)
except IOError as e:
print("Configuration file generation error: %s" % e.args)
exc_buffer = StringIO()
traceback.print_exc(file=exc_buffer)
logging.error('Error happened when writing configuration files:\n%s', exc_buffer.getvalue())
raise e
else:
exit(1)

View File

@@ -11,48 +11,48 @@ jobs:
- template: ci/steps.yml
strategy:
matrix:
Python 3.7 QT 5.13.0 mac android android_x86:
ARCH: android_x86
QT_VERSION: 5.13.0
ARCHDIR: android_x86
PYTHON_VERSION: '3.7'
TARGET: android
HOST: mac
Python 3.7 QT 5.13.0 mac android android_armv7:
ARCH: android_armv7
QT_VERSION: 5.13.0
ARCHDIR: android_armv7
PYTHON_VERSION: '3.7'
TARGET: android
HOST: mac
Python 3.7 QT 5.13.0 mac desktop clang_64:
ARCH: clang_64
QT_VERSION: 5.13.0
ARCHDIR: clang_64
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: mac
Python 3.7 QT 5.12.3 mac desktop clang_64:
ARCH: clang_64
QT_VERSION: 5.12.3
ARCHDIR: clang_64
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: mac
Python 3.7 QT 5.13.0 mac ios ios:
ARCH: ios
QT_VERSION: 5.13.0
ARCHDIR: ios
PYTHON_VERSION: '3.7'
TARGET: ios
ARCH: ios
QT_VERSION: 5.13.0
HOST: mac
Python 3.7 QT 5.11.3 mac desktop clang_64:
ARCH: clang_64
QT_VERSION: 5.11.3
ARCHDIR: clang_64
ARCHDIR: ios
Python 3.7 QT 5.12.3 mac desktop clang_64:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: clang_64
QT_VERSION: 5.12.3
HOST: mac
ARCHDIR: clang_64
Python 3.7 QT 5.13.0 mac android android_x86:
PYTHON_VERSION: '3.7'
TARGET: android
ARCH: android_x86
QT_VERSION: 5.13.0
HOST: mac
ARCHDIR: android_x86
Python 3.7 QT 5.13.0 mac android android_armv7:
PYTHON_VERSION: '3.7'
TARGET: android
ARCH: android_armv7
QT_VERSION: 5.13.0
HOST: mac
ARCHDIR: android_armv7
Python 3.7 QT 5.11.3 mac desktop clang_64:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: clang_64
QT_VERSION: 5.11.3
HOST: mac
ARCHDIR: clang_64
Python 3.7 QT 5.13.0 mac desktop clang_64:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: clang_64
QT_VERSION: 5.13.0
HOST: mac
ARCHDIR: clang_64
- job: Windows
pool:
vmImage: vs2017-win2016
@@ -60,83 +60,83 @@ jobs:
- template: ci/steps.yml
strategy:
matrix:
Python 3.7 QT 5.13.0 windows desktop win64_mingw73:
ARCH: win64_mingw73
QT_VERSION: 5.13.0
ARCHDIR: mingw73
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: windows
Python 3.7 QT 5.13.0 windows desktop win64_msvc2017_64:
ARCH: win64_msvc2017_64
QT_VERSION: 5.13.0
ARCHDIR: msvc2017_64
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: windows
Python 3.7 QT 5.13.0 windows android android_x86:
PYTHON_VERSION: '3.7'
TARGET: android
ARCH: android_x86
QT_VERSION: 5.13.0
HOST: windows
ARCHDIR: android_x86
PYTHON_VERSION: '3.7'
TARGET: android
HOST: windows
Python 3.7 QT 5.13.0 windows desktop win32_mingw73:
ARCH: win32_mingw73
QT_VERSION: 5.13.0
ARCHDIR: mingw73
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: windows
Python 3.7 QT 5.11.3 windows desktop win64_msvc2017_64:
ARCH: win64_msvc2017_64
QT_VERSION: 5.11.3
ARCHDIR: msvc2017_64
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: windows
Python 3.7 QT 5.13.0 windows android android_armv7:
ARCH: android_armv7
QT_VERSION: 5.13.0
ARCHDIR: android_armv7
PYTHON_VERSION: '3.7'
TARGET: android
HOST: windows
Python 3.7 QT 5.12.3 windows desktop win64_msvc2017_64:
ARCH: win64_msvc2017_64
QT_VERSION: 5.12.3
ARCHDIR: msvc2017_64
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: windows
Python 3.7 QT 5.12.3 windows desktop win32_msvc2017:
ARCH: win32_msvc2017
QT_VERSION: 5.12.3
ARCHDIR: msvc2017
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: windows
Python 3.7 QT 5.13.0 windows desktop win64_msvc2015_64:
ARCH: win64_msvc2015_64
QT_VERSION: 5.13.0
ARCHDIR: msvc2015_64
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: windows
Python 3.7 QT 5.11.3 windows desktop win32_msvc2015:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: win32_msvc2015
QT_VERSION: 5.11.3
HOST: windows
ARCHDIR: msvc2015
Python 3.7 QT 5.13.0 windows desktop win64_mingw73:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: win64_mingw73
QT_VERSION: 5.13.0
HOST: windows
ARCHDIR: mingw73
Python 3.7 QT 5.13.0 windows desktop win32_mingw73:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: win32_mingw73
QT_VERSION: 5.13.0
HOST: windows
ARCHDIR: mingw73
Python 3.7 QT 5.13.0 windows desktop win32_msvc2017:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: win32_msvc2017
QT_VERSION: 5.13.0
HOST: windows
ARCHDIR: msvc2017
Python 3.7 QT 5.13.0 windows desktop win64_msvc2015_64:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: win64_msvc2015_64
QT_VERSION: 5.13.0
HOST: windows
ARCHDIR: msvc2015_64
Python 3.7 QT 5.13.0 windows desktop win64_msvc2017_64:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: win64_msvc2017_64
QT_VERSION: 5.13.0
HOST: windows
ARCHDIR: msvc2017_64
Python 3.7 QT 5.13.0 windows android android_armv7:
PYTHON_VERSION: '3.7'
TARGET: android
ARCH: android_armv7
QT_VERSION: 5.13.0
HOST: windows
ARCHDIR: android_armv7
Python 3.7 QT 5.11.3 windows desktop win64_msvc2017_64:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: win64_msvc2017_64
QT_VERSION: 5.11.3
HOST: windows
ARCHDIR: msvc2017_64
Python 3.7 QT 5.12.3 windows desktop win32_msvc2017:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: win32_msvc2017
QT_VERSION: 5.12.3
HOST: windows
ARCHDIR: msvc2017
Python 3.7 QT 5.12.3 windows desktop win64_msvc2017_64:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: win64_msvc2017_64
QT_VERSION: 5.12.3
HOST: windows
ARCHDIR: msvc2017_64
- job: Linux
pool:
vmImage: ubuntu-16.04
@@ -144,38 +144,38 @@ jobs:
- template: ci/steps.yml
strategy:
matrix:
Python 3.7 QT 5.11.3 linux desktop gcc_64:
ARCH: gcc_64
QT_VERSION: 5.11.3
ARCHDIR: gcc_64
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: linux
Python 3.7 QT 5.13.0 linux desktop gcc_64:
ARCH: gcc_64
QT_VERSION: 5.13.0
ARCHDIR: gcc_64
PYTHON_VERSION: '3.7'
TARGET: desktop
HOST: linux
Python 3.7 QT 5.13.0 linux android android_x86:
ARCH: android_x86
QT_VERSION: 5.13.0
ARCHDIR: android_x86
PYTHON_VERSION: '3.7'
TARGET: android
HOST: linux
Python 3.7 QT 5.13.0 linux android android_armv7:
ARCH: android_armv7
QT_VERSION: 5.13.0
ARCHDIR: android_armv7
PYTHON_VERSION: '3.7'
TARGET: android
HOST: linux
Python 3.7 QT 5.12.3 linux desktop gcc_64:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: gcc_64
QT_VERSION: 5.12.3
HOST: linux
ARCHDIR: gcc_64
Python 3.7 QT 5.11.3 linux desktop gcc_64:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: gcc_64
QT_VERSION: 5.11.3
HOST: linux
ARCHDIR: gcc_64
Python 3.7 QT 5.13.0 linux android android_armv7:
PYTHON_VERSION: '3.7'
TARGET: android
ARCH: android_armv7
QT_VERSION: 5.13.0
HOST: linux
ARCHDIR: android_armv7
Python 3.7 QT 5.13.0 linux android android_x86:
PYTHON_VERSION: '3.7'
TARGET: android
ARCH: android_x86
QT_VERSION: 5.13.0
HOST: linux
ARCHDIR: android_x86
Python 3.7 QT 5.13.0 linux desktop gcc_64:
PYTHON_VERSION: '3.7'
TARGET: desktop
ARCH: gcc_64
QT_VERSION: 5.13.0
HOST: linux
ARCHDIR: gcc_64