#!/usr/bin/python # -*- coding: utf-8 -*- # Copyright (C) 2015 The Qt Company Ltd. # Contact: http://engin.io # # You may use this file under the terms of the 3-clause BSD license. # See the file LICENSE from this package for details. # from __future__ import print_function import os import shutil import subprocess import sys import glob # Qt qmake = "qmake" qmake_spec = subprocess.check_output([qmake, "-query", "QMAKE_SPEC"]).strip().decode('utf-8') qt_install_prefix = subprocess.check_output([qmake, "-query", "QT_INSTALL_PREFIX"]).strip().decode('utf-8') qt_install_placeholder = "<__QT__INSTALL__PREFIX__>" make = "make" if sys.platform == "win32": make = "jom" # from the installer framework binarycreator = "binarycreator" # visual studio #setEnv = "c:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Bin\\SetEnv.Cmd" # should be extracted from .qmake.conf VERSION = "unknown_version" # Build Enginio subprocess.check_call(["git", "clean", "-xdf"]) os.mkdir("build") os.chdir("build") # this is evil - keep the process alive so that we can set the right sdk env here # and it may not work, at least currently I have conflicts with VS 7.1 and 8 #process = subprocess.Popen('cmd.exe /k\n', shell=True, stdin=subprocess.PIPE) #process.stdin.write('call "' + setEnv + '"\n') #process.stdin.write(qmake + " ../..\r\n") #process.stdin.write(jom + "\n") # docs build currently errors out! # process.stdin.write("nmake docs\n") #process.stdin.write("exit\n") #process.communicate() subprocess.check_call([qmake, "CONFIG+=silent", "../.."]) print("Compiling Enginio...") try: from subprocess import DEVNULL # py3k except ImportError: DEVNULL = open(os.devnull, 'wb') subprocess.check_call([make]) if sys.platform == "win32": # bug with jom subtargets subprocess.check_call(["nmake", "docs"]) else: subprocess.check_call([make, "docs"]) # on Windows dlls are built in the lib dir but need to be in bin if sys.platform == "win32": os.mkdir("bin") alldlls = glob.glob("lib/*.dll") for dll in alldlls: os.rename(dll, "bin" + dll[3:]) # on Linux so files need their rpath adjusted if sys.platform.startswith("linux"): subprocess.check_call(["chrpath", "-r", "$ORIGIN", "lib/libEnginio.so"]) subprocess.check_call(["chrpath", "-r", "$ORIGIN/../../lib", "qml/Enginio/libenginioplugin.so"]) cwd = os.getcwd() if sys.platform == "darwin": otool = "otool" install_name_tool = "install_name_tool" print(cwd) install_path = subprocess.check_output([otool, "-D", "lib/Enginio.framework/Enginio"]).split().pop() rpath = install_path.replace(qt_install_prefix, qt_install_placeholder) plugin_lib = "qml/Enginio/libenginioplugin.dylib" plugin_debug_lib = "qml/Enginio/libenginioplugin_debug.dylib" enginio_lib = install_path.replace(qt_install_prefix, '.') subprocess.check_call([install_name_tool, "-id", rpath, enginio_lib]) subprocess.check_call([install_name_tool, "-id", rpath + "_debug", enginio_lib + "_debug"]) rpath_libs = subprocess.check_output([otool, "-L", enginio_lib]).strip().split('\n') rpath_libs.extend(subprocess.check_output([otool, "-L", plugin_lib]).strip().split('\n')) rpath_libs.extend(subprocess.check_output([otool, "-L", plugin_debug_lib]).strip().split('\n')) seen = set() for line in rpath_libs: lib = line.split()[0].strip() if lib not in seen and lib.startswith(qt_install_prefix): print("# " + lib) subprocess.check_call([install_name_tool, "-change", lib, lib.replace(qt_install_prefix, qt_install_placeholder), enginio_lib]) subprocess.check_call([install_name_tool, "-change", lib, lib.replace(qt_install_prefix, qt_install_placeholder), enginio_lib + "_debug"]) subprocess.check_call([install_name_tool, "-change", lib, lib.replace(qt_install_prefix, qt_install_placeholder), plugin_lib]) subprocess.check_call([install_name_tool, "-change", lib, lib.replace(qt_install_prefix, qt_install_placeholder), plugin_debug_lib]) seen.add(lib) if sys.platform == "darwin" or sys.platform.startswith("linux"): filenames = ['mkspecs/modules-inst/qt_lib_enginio.pri', 'lib/Enginio.framework/Enginio_debug.prl', 'lib/Enginio.framework/Enginio.prl', 'lib/libEnginio.prl', 'lib/pkgconfig/Enginio.pc', 'lib/libEnginio.la', 'lib/Enginio.la', 'lib/Enginio_debug.la'] for f in filenames: if os.path.exists(f): with open(f, "r+") as f_handle: lines = f_handle.readlines() f_handle.seek(0) f_handle.truncate() for line in lines: modline = line if qt_install_prefix in line: modline = line.replace(qt_install_prefix, qt_install_placeholder) f_handle.write(modline) os.chdir("..") patcher_dest = "packages/com.digia.enginio/data/patcher.py" os.mkdir(os.path.dirname(patcher_dest)) shutil.copyfile("patcher.py", patcher_dest) os.chdir(cwd) # Copy files around os.chdir("../..") packages = { "com.digia.enginio": ["include", "lib", "qml", "doc/qtenginio.qch", ], "com.digia.enginioExamples": ["examples",], "com.digia.enginioDocumentation": ["doc/qtenginio",], "com.digia.enginioSources": ["src",], } if sys.platform == "win32": packages["com.digia.enginio"].append("bin") package_xml = "dist/packages/com.digia.enginio/meta/package.xml" with open(package_xml, "r+") as xml: lines = xml.readlines() xml.seek(0) xml.truncate() for line in lines: if "" in line: xml.write("true\n") xml.write(line) print("Creating installer...") for package in packages: for path in packages[package]: sourcePath = "dist/build/" + path if not os.path.exists(sourcePath): # Find examples/ sourcePath = path if not os.path.exists(sourcePath): print("ERROR: Could not find path '" + path + "' in source or build directory.") exit(1) print("Creating ", path, " dir.") dest = "dist/packages/" + package + "/data/" + path if os.path.exists(dest): print("ERROR: ", dest, " exists already.") exit(1) if os.path.isfile(sourcePath): os.mkdir(os.path.dirname(dest)) shutil.copyfile(sourcePath, dest) else: shutil.copytree(sourcePath, dest, symlinks=True) # copy the real headers # src/enginio_client # src/enginio_plugin headerPath = "dist/packages/com.digia.enginio/data/include/Enginio/" import fileinput for line in fileinput.input(".qmake.conf"): if line.startswith("MODULE_VERSION"): import re VERSION = re.search(r'[0-9.]+', line).group(0) privateHeaderPath = headerPath + VERSION + "/Enginio/private" allHeaders = glob.glob("src/*/*.h") for header in allHeaders: fileName = header[header.rindex(os.sep):] if header.endswith("_p.h"): print("Copy ", header, " to ", privateHeaderPath + fileName) shutil.copyfile(header, privateHeaderPath + fileName) else: print("Copy ", header, " to ", headerPath + fileName) shutil.copyfile(header, headerPath + fileName) os.chdir("dist") # the Module .pri file is special - take the one from mkspecs/modules_inst modulesPath = "packages/com.digia.enginio/data/mkspecs/modules" os.mkdir("packages/com.digia.enginio/data/mkspecs") os.mkdir(modulesPath) shutil.copyfile("build/mkspecs/modules-inst/qt_lib_enginio.pri", modulesPath + "/qt_lib_enginio.pri") pkgname = "QtEnginioInstaller_" + VERSION + '-' + qmake_spec subprocess.check_call([binarycreator, "--offline-only", "-c", "config" + os.sep + "config.xml", "-p", "packages", pkgname]) if sys.platform == "darwin": subprocess.check_call(["hdiutil", "create", pkgname + ".dmg", "-srcfolder", pkgname + ".app"]) print("Installer created.")