Beispiel #1
0
def shallUseStaticLibPython():
    """*bool* = "--static-libpython=yes|auto"

    Notes:
        Currently only Anaconda on non-Windows can do this and MSYS2.
    """

    if options.static_libpython == "auto":
        if isWin32Windows() and os.path.exists(
                os.path.join(sys.prefix, "etc/config.site")):
            return True

        # For Anaconda default to trying static lib python library, which
        # normally is just not available or if it is even unusable.
        if (os.path.exists(os.path.join(sys.prefix, "conda-meta"))
                and not isWin32Windows() and not getOS() == "Darwin"):
            return True

        options.static_libpython = "no"

        if getSystemStaticLibPythonPath() is not None:
            Tracing.options_logger.info(
                "Detected static libpython as existing, consider using '--static-libpython=yes'."
            )

    return options.static_libpython == "yes"
Beispiel #2
0
def executePostProcessing(result_filename):

    if isWin32Windows():
        # Copy the Windows manifest from the CPython binary to the created
        # executable, so it finds "MSCRT.DLL". This is needed for Python2
        # only, for Python3 newer MSVC doesn't hide the C runtime.
        if python_version < 300 and not Options.shallMakeModule():
            copyResourcesFromFileToFile(
                sys.executable,
                target_filename=result_filename,
                resource_kind=RT_MANIFEST,
            )

        assert os.path.exists(result_filename)

        # Attach the binary blob as a Windows resource.
        addResourceToFile(
            target_filename=result_filename,
            data=ConstantCodes.stream_data.getBytes(),
            resource_kind=RT_RCDATA,
            res_name=3,
            lang_id=0,
        )

    # Modules should not be executable, but Scons creates them like it, fix
    # it up here.
    if not isWin32Windows() and Options.shallMakeModule():
        old_stat = os.stat(result_filename)

        mode = old_stat.st_mode
        mode &= ~(stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)

        if mode != old_stat.st_mode:
            os.chmod(result_filename, mode)
Beispiel #3
0
def getNumpyCoreBinaries(module):
    """Return any binaries in numpy/core and/or numpy/.libs.

    Notes:
        This covers the special cases like MKL binaries.

    Returns:
        tuple of abspaths of binaries.
    """
    numpy_dir = module.getCompileTimeDirectory()
    numpy_core_dir = os.path.join(numpy_dir, "core")
    base_prefix = getSystemPrefixPath()

    binaries = []

    # first look in numpy/.libs for binaries
    libdir = os.path.join(numpy_dir,
                          ".libs" if getOS() != "Darwin" else ".dylibs")
    suffix_start = len(libdir) + 1
    if os.path.isdir(libdir):
        dlls_pkg = os.listdir(libdir)
        binaries += [[os.path.join(libdir, f), suffix_start] for f in dlls_pkg]

    # then look for libraries in numpy.core package path
    # should already return the MKL files in ordinary cases

    re_anylib = re.compile(r"\w+\.(?:dll|so|dylib)", re.IGNORECASE)

    dlls_pkg = [f for f in os.listdir(numpy_core_dir) if re_anylib.match(f)]
    binaries += [[os.path.join(numpy_core_dir, f), suffix_start]
                 for f in dlls_pkg]

    # Also look for MKL libraries in folder "above" numpy.
    # This should meet the layout of Anaconda installs.

    if isWin32Windows():
        lib_dir = os.path.join(base_prefix, "Library", "bin")
        suffix_start = len(lib_dir) + 1
    else:
        lib_dir = os.path.join(base_prefix, "lib")
        suffix_start = len(lib_dir) + 1

    if not os.path.isdir(lib_dir):
        return binaries

    re_mkllib = re.compile(r"^(?:lib)?mkl\w+\.(?:dll|so|dylib)", re.IGNORECASE)

    for f in os.listdir(lib_dir):
        if isWin32Windows():
            if not (f.startswith(
                ("libi", "libm", "mkl")) and f.endswith(".dll")):
                continue
        else:
            if not re_mkllib.match(f):
                continue

        binaries.append([os.path.join(lib_dir, f), suffix_start])

    return binaries
Beispiel #4
0
def get_numpy_core_binaries():
    """ Return any binaries in numpy/core and/or numpy/.libs, whether or not actually used by our script.

    Notes:
        This covers the special cases like MKL binaries, which cannot be detected by dependency managers.

    Returns:
        tuple of abspaths of binaries
    """

    base_prefix = get_sys_prefix()
    suffix_start = len(base_prefix) + 1
    binaries = []

    # first look in numpy/.libs for binaries
    _, pkg_dir = get_package_paths("numpy")
    libdir = os.path.join(pkg_dir, ".libs")
    suffix_start = len(libdir) + 1
    if os.path.isdir(libdir):
        dlls_pkg = [f for f in os.listdir(libdir)]
        binaries += [[os.path.join(libdir, f), suffix_start] for f in dlls_pkg]

    # then look for libraries in numpy.core package path
    # should already return the MKL files in ordinary cases
    _, pkg_dir = get_package_paths("numpy.core")
    re_anylib = re.compile(r"\w+\.(?:dll|so|dylib)", re.IGNORECASE)
    dlls_pkg = [f for f in os.listdir(pkg_dir) if re_anylib.match(f)]
    binaries += [[os.path.join(pkg_dir, f), suffix_start] for f in dlls_pkg]

    # Also look for MKL libraries in folder "above" numpy.
    # This should meet the layout of Anaconda installs.

    if isWin32Windows():
        lib_dir = os.path.join(base_prefix, "Library", "bin")
        suffix_start = len(lib_dir) + 1
    else:
        lib_dir = os.path.join(base_prefix, "lib")
        suffix_start = len(lib_dir) + 1

    if not os.path.isdir(lib_dir):
        return binaries

    re_mkllib = re.compile(r"^(?:lib)?mkl\w+\.(?:dll|so|dylib)", re.IGNORECASE)

    for f in os.listdir(lib_dir):
        if isWin32Windows():
            if not (f.startswith(
                ("libi", "libm", "mkl")) and f.endswith(".dll")):
                continue
        else:
            if not re_mkllib.match(f):
                continue

        binaries.append([os.path.join(lib_dir, f), suffix_start])

    return binaries
Beispiel #5
0
    def _getNumpyCoreBinaries(numpy_dir):
        """Return any binaries in numpy package.

        Notes:
            This covers the special cases like MKL binaries.

        Returns:
            tuple of abspaths of binaries.
        """
        numpy_core_dir = os.path.join(numpy_dir, "core")

        # first look in numpy/.libs for binaries
        libdir = os.path.join(numpy_dir, ".libs" if not isMacOS() else ".dylibs")
        if os.path.isdir(libdir):
            for full_path, filename in listDir(libdir):
                yield full_path, filename

        # Then look for libraries in numpy.core package path
        # should already return the MKL files in ordinary cases
        re_anylib = re.compile(r"\w+\.(?:dll|so|dylib)", re.IGNORECASE)

        for full_path, filename in listDir(numpy_core_dir):
            if not re_anylib.match(filename):
                continue

            yield full_path, filename

        # Also look for MKL libraries in folder "above" numpy.
        # This should meet the layout of Anaconda installs.
        base_prefix = getSystemPrefixPath()

        if isWin32Windows():
            lib_dir = os.path.join(base_prefix, "Library", "bin")
        else:
            lib_dir = os.path.join(base_prefix, "lib")

        if os.path.isdir(lib_dir):
            re_mkllib = re.compile(r"^(?:lib)?mkl\w+\.(?:dll|so|dylib)", re.IGNORECASE)

            for full_path, filename in listDir(lib_dir):
                if isWin32Windows():
                    if not (
                        filename.startswith(("libi", "libm", "mkl"))
                        and filename.endswith(".dll")
                    ):
                        continue
                else:
                    if not re_mkllib.match(filename):
                        continue

                yield full_path, filename
Beispiel #6
0
def shallUseStaticLibPython():
    """*bool* = derived from `sys.prefix` and `os.name`

    Notes:
        Currently only Anaconda on non-Windows can do this.
    """

    if isWin32Windows() and os.path.exists(
            os.path.join(sys.prefix, "etc/config.site")):
        return True

    # For Anaconda default to trying static lib python library, which
    # normally is just not available or if it is even unusable.
    return (os.path.exists(os.path.join(sys.prefix, "conda-meta"))
            and not isWin32Windows() and not getOS() == "Darwin")
Beispiel #7
0
def _wasMsvcMode():
    if not isWin32Windows():
        return False

    return (getSconsReportValue(
        source_dir=OutputDirectories.getSourceDirectoryPath(),
        key="msvc_mode") == "True")
Beispiel #8
0
def isMSYS2MingwPython():
    if not isWin32Windows() or "GCC" not in sys.version:
        return False

    import sysconfig

    return "-mingw_" in sysconfig.get_config_var("SO")
Beispiel #9
0
    def createPreModuleLoadCode(module):
        """Method called when a module is being imported.

        Notes:
            If full name equals "PyQt?" we insert code to include the dist
            folder in the 'PATH' environment variable (on Windows only).

        Args:
            module: the module object
        Returns:
            Code to insert and descriptive text (tuple), or (None, None).
        """
        if not isWin32Windows():  # we are only relevant on Windows
            return None, None

        if module.getFullName() not in ("PyQt4", "PyQt5"):
            return None, None  # not for us

        code = """import os
path = os.environ.get("PATH", "")
if not path.startswith(__nuitka_binary_dir):
    os.environ["PATH"] = __nuitka_binary_dir + ";" + path
"""
        return (
            code,
            "Adding binary folder to runtime 'PATH' environment variable for proper loading.",
        )
Beispiel #10
0
def runValgrind(descr, tool, args, include_startup, save_logfilename=None):
    # Many cases to deal with, pylint: disable=too-many-branches

    if isWin32Windows():
        sys.exit("Error, valgrind is not available on Windows.")

    if descr:
        my_print(descr, tool, file=sys.stderr, end="... ")

    with withTemporaryFile() as log_file:
        log_filename = log_file.name

        command = ["valgrind", "-q"]

        if tool == "callgrind":
            command += ("--tool=callgrind",
                        "--callgrind-out-file=%s" % log_filename)
        elif tool == "massif":
            command += ("--tool=massif", "--massif-out-file=%s" % log_filename)
        else:
            sys.exit("Error, no support for tool '%s' yet." % tool)

        # Do not count things before main module starts its work.
        if not include_startup:
            command += (
                "--zero-before=init__main__()",
                "--zero-before=init__main__",
                "--zero-before=PyInit___main__",
                "--zero-before=PyInit___main__()",
            )

        command.extend(args)

        _stdout_valgrind, stderr_valgrind, exit_valgrind = executeProcess(
            command)

        assert exit_valgrind == 0, stderr_valgrind
        if descr:
            my_print("OK", file=sys.stderr)

        if save_logfilename is not None:
            copyFile(log_filename, save_logfilename)

        max_mem = None

        for line in getFileContentByLine(log_filename):
            if tool == "callgrind" and line.startswith("summary:"):
                return int(line.split()[1])
            elif tool == "massif" and line.startswith("mem_heap_B="):
                mem = int(line.split("=")[1])

                if max_mem is None:
                    max_mem = 0

                max_mem = max(mem, max_mem)

        if tool == "massif" and max_mem is not None:
            return max_mem

        sys.exit("Error, didn't parse Valgrind log file successfully.")
Beispiel #11
0
    def createPreModuleLoadCode(module):
        """ This method is called with a module that will be imported.

        Notes:
            If the word "tkinter" occurs in its full name, we know that the correct
            setting of the TCL environment must be ensured before this happens.

        Args:
            module: the module object
        Returns:
            Code to insert and None (tuple)
        """
        if not isWin32Windows():  # we are only relevant on Windows
            return None, None

        # only insert code for tkinter related modules
        if not _isTkInterModule(module):
            return None, None

        # The following code will be executed before importing the module.
        # If required we set the respective environment values.
        code = """import os
if not os.environ.get("TCL_LIBRARY", None):
    os.environ["TCL_LIBRARY"] = os.path.join(__nuitka_binary_dir, "tcl")
    os.environ["TK_LIBRARY"] = os.path.join(__nuitka_binary_dir, "tk")"""
        return code, "Need to make sure we set environment variables for TCL."
Beispiel #12
0
def _shallUseStaticLibPython():
    # return driven, pylint: disable=too-many-return-statements

    if shallMakeModule():
        return False, "not used in module mode"

    if options.static_libpython == "auto":
        # Nuitka-Python is good to to static linking.
        if isNuitkaPython():
            return True, "Nuitka-Python is broken."

        # Debian packages with are usable if the OS is new enough
        from nuitka.utils.StaticLibraries import (
            isDebianSuitableForStaticLinking, )

        if (isDebianBasedLinux() and isDebianPackagePython()
                and isDebianSuitableForStaticLinking()
                and not isPythonDebug()):
            return True, "Nuitka on Debian-Python needs package '%s' installed." % (
                "python2-dev" if str is bytes else "python3-dev")

        if isMSYS2MingwPython():
            return True, "Nuitka on MSYS2 needs package 'python-devel' installed."

        # For Anaconda default to trying static lib python library, which
        # normally is just not available or if it is even unusable.
        if isAnacondaPython() and not isMacOS() and not isWin32Windows():
            return True, "Nuitka on Anaconda needs package 'libpython' installed."

        if isPyenvPython():
            return True, "Nuitka on pyenv should not use '--enable-shared'."

    return options.static_libpython == "yes", None
Beispiel #13
0
def enableProgressBar():
    global use_progress_bar  # singleton, pylint: disable=global-statement
    global tqdm  # singleton, pylint: disable=global-statement

    if isWin32Windows():
        colorama = importFromInlineCopy("colorama", must_exist=True)
        colorama.init()

    tqdm = importFromInlineCopy("tqdm", must_exist=False)

    if tqdm is None:
        try:
            # Cannot use import tqdm due to pylint bug.
            import tqdm as tqdm_installed  # pylint: disable=I0021,import-error

            tqdm = tqdm_installed
        except ImportError:
            # We handle the case without inline copy too, but it may be removed, e.g. on
            # Debian it's only a recommended install, and not included that way.
            pass

    # Tolerate the absence ignore the progress bar
    if tqdm is not None:
        tqdm = tqdm.tqdm

        tqdm.set_lock(RLock())
        use_progress_bar = True
Beispiel #14
0
def shallCreateCmdFileForExecution():
    """*bool* = derived from Python installation and modes

    Notes: Most for accerated mode on Windows with uninstalled python, to
    make sure they find their Python DLL.
    """
    return isWin32Windows() and shallTreatUninstalledPython()
Beispiel #15
0
def packDistFolderToOnefileBootstrap(onefile_output_filename, dist_dir):
    postprocessing_logger.info(
        "Creating single file from dist folder, this may take a while.")

    onefile_logger.info("Running bootstrap binary compilation via Scons.")

    # Now need to append to payload it, potentially compressing it.
    compressor_python = getCompressorPython()

    # First need to create the bootstrap binary for unpacking.
    _runOnefileScons(
        quiet=not Options.isShowScons(),
        onefile_compression=compressor_python is not None,
    )

    if isWin32Windows():
        executePostProcessingResources(manifest=None, onefile=True)

    Plugins.onBootstrapBinary(onefile_output_filename)

    if isMacOS():
        addMacOSCodeSignature(filenames=[onefile_output_filename])

    runOnefileCompressor(
        compressor_python=compressor_python,
        dist_dir=dist_dir,
        onefile_output_filename=onefile_output_filename,
        start_binary=getResultFullpath(onefile=False),
    )
Beispiel #16
0
    def onModuleEncounter(self, module_filename, module_name, module_kind):
        # Make sure
        if module_name.isBelowNamespace("webview.platforms"):
            if isWin32Windows():
                result = module_name in (
                    "webview.platforms.winforms",
                    "webview.platforms.edgechromium",
                    "webview.platforms.edgehtml",
                    "webview.platforms.mshtml",
                    "webview.platforms.cef",
                )
                reason = "Platforms package of webview used on '%s'." % getOS()
            elif isMacOS():
                result = module_name == "webview.platforms.cocoa"
                reason = "Platforms package of webview used on '%s'." % getOS()
            elif getActiveQtPlugin() is not None:
                result = module_name = "webview.platforms.qt"
                reason = ("Platforms package of webview used due to '%s'." %
                          getActiveQtPlugin())
            else:
                result = module_name = "webview.platforms.gtk"
                reason = (
                    "Platforms package of webview used on '%s' without Qt plugin enabled."
                    % getOS())

            return result, reason
Beispiel #17
0
    def createPreModuleLoadCode(self, module):
        """Method called when a module is being imported.

        Notes:
            If full name equals to the binding we insert code to include the dist
            folder in the 'PATH' environment variable (on Windows only).

        Args:
            module: the module object
        Returns:
            Code to insert and descriptive text (tuple), or (None, None).
        """

        # This isonly relevant on standalone mode for Windows
        if not isWin32Windows() or not Options.isStandaloneMode():
            return None

        full_name = module.getFullName()

        if full_name == self.binding_name:
            code = """import os
path = os.environ.get("PATH", "")
if not path.startswith(__nuitka_binary_dir):
    os.environ["PATH"] = __nuitka_binary_dir + ";" + path
"""
            return (
                code,
                "Adding binary folder to runtime 'PATH' environment variable for proper loading.",
            )
Beispiel #18
0
def getResultRunFilename(onefile):
    result = getResultFullpath(onefile=onefile)

    if isWin32Windows() and Options.shallTreatUninstalledPython():
        result = getResultBasepath(onefile=onefile) + ".cmd"

    return result
Beispiel #19
0
    def isRelevant():
        """ This method is called one time only to check, whether the plugin might make sense at all.

        Returns:
            True if this is a standalone compilation on Windows, else False.
        """
        return Options.isStandaloneMode() and isWin32Windows()
Beispiel #20
0
def _openBinaryFileForAppending(onefile_output_filename):
    max_attempts = 5

    # TODO: This is code duplication with resource handling, should be unified
    # and with as a context manager.

    for attempt in range(1, max_attempts + 1):
        try:
            with open(onefile_output_filename, "ab") as output_file:
                yield output_file
                return
        except OSError as e:
            # Only for Windows at this time, other platforms don't have the issue.
            if not isWin32Windows() and not isPosixWindows():
                raise

            if e.errno in (110, 13):
                onefile_logger.warning("""
Failed to open binary for payload attachment in attempt %d.
Disable Anti-Virus, e.g. Windows Defender for build folders. Retrying after a second of delay."""
                                       % attempt)
            else:
                onefile_logger.warning("""
Failed to open binary for payload attachment in attempt %d with error code %d.
Disable Anti-Virus, e.g. Windows Defender for build folders. Retrying after a second of delay."""
                                       % (attempt, e.errno))

            time.sleep(1)
            continue
        else:
            if attempt != 1:
                onefile_logger.warning(
                    "Succeeded to open binary for payload attachment in attempt %d."
                    % attempt)
            break
Beispiel #21
0
    def createPreModuleLoadCode(module):
        """ This method is called with a module that will be imported.

        Notes:
            If the word "tkinter" occurs in its full name, we know that the correct
            setting of the TCL environment must be ensured before this happens.

        Args:
            module: the module object
        Returns:
            Code to insert and None (tuple)
        """
        if not isWin32Windows():  # we are only relevant on Windows
            return None, None

        # only insert code for tkinter related modules
        if not _isTkInterModule(module):
            return None, None

        # The following code will be executed before importing the module.
        # If required we set the respective environment values.
        code = """import os
if not os.environ.get("TCL_LIBRARY", None):
    os.environ["TCL_LIBRARY"] = os.path.join(__nuitka_binary_dir, "tcl")
    os.environ["TK_LIBRARY"] = os.path.join(__nuitka_binary_dir, "tk")"""
        return code, "Need to make sure we set environment variables for TCL."
Beispiel #22
0
    def isRelevant():
        """ This method is called one time only to check, whether the plugin might make sense at all.

        Returns:
            True if this is a standalone compilation on Windows, else False.
        """
        return Options.isStandaloneMode() and isWin32Windows()
Beispiel #23
0
    def considerExtraDlls(self, dist_dir, module):
        """ Copy TCL libraries to the dist folder.

        Notes:
            We will copy the TCL/TK directories to the program's root directory.
            The general intention is that we return a tuple of file names.
            We need however two subdirectories inserted, and therefore do the
            copy ourselves and return an empty tuple.

        Args:
            dist_dir: the name of the program's dist folder
            module: the module object (not used here)

        Returns:
            None
        """
        if not _isTkInterModule(module):
            return ()

        if not isWin32Windows():  # if not Windows notify wrong usage once
            info("tkinter plugin supported on Windows only")
            return ()

        if python_version < 340:  # last tk/tcl qualifyers Py 2
            tk_lq = "tk8.5"
            tcl_lq = "tcl8.5"
        else:  # last tk/tcl qualifyers Py 3+
            tk_lq = "tk8.6"
            tcl_lq = "tcl8.6"

        # check possible locations of the dirs
        sys_tcl = os.path.join(os.path.dirname(sys.executable), "tcl")
        tk = os.path.join(sys_tcl, tk_lq)
        tcl = os.path.join(sys_tcl, tcl_lq)

        # if this was not the right place, try this:
        if not (os.path.exists(tk) and os.path.exists(tcl)):
            tk = os.environ.get("TK_LIBRARY", None)
            tcl = os.environ.get("TCL_LIBRARY", None)
            if not (tk and tcl):
                info(" Could not find TK / TCL libraries")
                sys.exit("aborting standalone generation.")

        # survived the above, now do the copying to following locations
        tar_tk = os.path.join(dist_dir, "tk")
        tar_tcl = os.path.join(dist_dir, "tcl")

        info(" Now copying tk libraries from %r." % tk)  # just to entertain
        shutil.copytree(tk, tar_tk)
        info(" Now copying tkinter libraries from %r." %
             tcl)  # just to entertain
        shutil.copytree(tcl, tar_tcl)

        # Definitely don't need the demos, so remove them again.
        # TODO: Anything else?
        shutil.rmtree(os.path.join(tar_tk, "demos"), ignore_errors=True)

        return ()
Beispiel #24
0
def enableProgressBar():
    global use_progress_bar  # singleton, pylint: disable=global-statement

    if _getTqdmModule() is not None:
        use_progress_bar = True

        if isWin32Windows():
            colorama = importFromInlineCopy("colorama", must_exist=True)
            colorama.init()
Beispiel #25
0
def _getClcacheGuessedPaths(python_prefix):
    assert isWin32Windows()

    # Search the compiling Python, the Scons Python (likely the same, but not necessarily)
    # and then Anaconda, if an environment variable present from activated, or installed in
    # CI like Github actions.
    for python_dir in _getPythonDirCandidates(python_prefix):
        yield os.path.join(python_dir, "scripts", "clcache.exe")
        yield os.path.join(python_dir, "bin", "clcache.exe")
Beispiel #26
0
    def considerExtraDlls(self, dist_dir, module):
        """ Copy TCL libraries to the dist folder.

        Notes:
            We will copy the TCL/TK directories to the program's root directory.
            The general intention is that we return a tuple of file names.
            We need however two subdirectories inserted, and therefore do the
            copy ourselves and return an empty tuple.

        Args:
            dist_dir: the name of the program's dist folder
            module: the module object (not used here)

        Returns:
            None
        """
        if not _isTkInterModule(module):
            return ()

        if not isWin32Windows():  # if not Windows notify wrong usage once
            info("tkinter plugin supported on Windows only")
            return ()

        if python_version < 340:  # last tk/tcl qualifyers Py 2
            tk_lq = "tk8.5"
            tcl_lq = "tcl8.5"
        else:  # last tk/tcl qualifyers Py 3+
            tk_lq = "tk8.6"
            tcl_lq = "tcl8.6"

        # check possible locations of the dirs
        sys_tcl = os.path.join(os.path.dirname(sys.executable), "tcl")
        tk = os.path.join(sys_tcl, tk_lq)
        tcl = os.path.join(sys_tcl, tcl_lq)

        # if this was not the right place, try this:
        if not (os.path.exists(tk) and os.path.exists(tcl)):
            tk = os.environ.get("TK_LIBRARY", None)
            tcl = os.environ.get("TCL_LIBRARY", None)
            if not (tk and tcl):
                info(" Could not find TK / TCL libraries")
                sys.exit("aborting standalone generation.")

        # survived the above, now do the copying to following locations
        tar_tk = os.path.join(dist_dir, "tk")
        tar_tcl = os.path.join(dist_dir, "tcl")

        info(" Now copying tk libraries from %r." % tk)  # just to entertain
        shutil.copytree(tk, tar_tk)
        info(" Now copying tkinter libraries from %r." % tcl)  # just to entertain
        shutil.copytree(tcl, tar_tcl)

        # Definitely don't need the demos, so remove them again.
        # TODO: Anything else?
        shutil.rmtree(os.path.join(tar_tk, "demos"), ignore_errors=True)

        return ()
Beispiel #27
0
def executePostProcessing(result_filename):

    # Copy the Windows manifest from the CPython binary to the created
    # executable, so it finds "MSCRT.DLL". This is needed for Python2
    # only, for Python3 newer MSVC doesn't hide the C runtime.
    if python_version < 300:
        if isWin32Windows() and not Options.shallMakeModule():
            copyResourcesFromFileToFile(sys.executable, result_filename, RT_MANIFEST)

    # Modules should not be executable, but Scons creates them like it, fix
    # it up here.
    if not isWin32Windows() and Options.shallMakeModule():
        old_stat = os.stat(result_filename)

        mode = old_stat.st_mode
        mode &= ~(stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)

        if mode != old_stat.st_mode:
            os.chmod(result_filename, mode)
Beispiel #28
0
def executePostProcessing(result_filename):

    # Copy the Windows manifest from the CPython binary to the created
    # executable, so it finds "MSCRT.DLL". This is needed for Python2
    # only, for Python3 newer MSVC doesn't hide the C runtime.
    if python_version < 300:
        if isWin32Windows() and not Options.shallMakeModule():
            copyResourcesFromFileToFile(sys.executable, result_filename,
                                        RT_MANIFEST)

    # Modules should not be executable, but Scons creates them like it, fix
    # it up here.
    if not isWin32Windows() and Options.shallMakeModule():
        old_stat = os.stat(result_filename)

        mode = old_stat.st_mode
        mode &= ~(stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)

        if mode != old_stat.st_mode:
            os.chmod(result_filename, mode)
Beispiel #29
0
def _getCcacheGuessedPaths(python_prefix):
    if isWin32Windows():
        # Search the compiling Python, the Scons Python (likely the same, but not necessarily)
        # and then Anaconda, if an environment variable present from activated, or installed in
        # CI like Github actions.
        for python_dir in _getPythonDirCandidates(python_prefix):
            yield os.path.join(python_dir, "bin", "ccache.exe")
            yield os.path.join(python_dir, "scripts", "ccache.exe")

    elif getOS() == "Darwin":
        # For macOS, we might find Homebrew ccache installed but not in PATH.
        yield "/usr/local/opt/ccache"
Beispiel #30
0
def get_numpy_core_binaries():
    """ Return any binaries in numpy/core and/or numpy/.libs, whether or not actually used by our script.

    Notes:
        This covers the special cases like MKL binaries, which cannot be detected by dependency managers.

    Returns:
        tuple of abspaths of binaries
    """

    # covers/unifies cases, where sys.base_prefix does not deliver
    # everything we need and/or is not an abspath.
    base_prefix = getattr(sys, "real_prefix",
                          getattr(sys, "base_prefix", sys.prefix))

    base_prefix = os.path.abspath(base_prefix)

    binaries = []

    # first look in numpy/.libs for binaries
    _, pkg_dir = get_package_paths("numpy")
    libdir = os.path.join(pkg_dir, ".libs")
    if os.path.isdir(libdir):
        dlls_pkg = [f for f in os.listdir(libdir)]
        binaries += [(os.path.join(libdir, f), ".") for f in dlls_pkg]

    # then look for libraries in numpy.core package path
    # should already return the MKL DLLs in ordinary cases
    _, pkg_dir = get_package_paths("numpy.core")
    re_anylib = re.compile(r"\w+\.(?:dll|so|dylib)", re.IGNORECASE)
    dlls_pkg = [f for f in os.listdir(pkg_dir) if re_anylib.match(f)]
    binaries += [(os.path.join(pkg_dir, f), ".") for f in dlls_pkg]

    # Also look for MKL libraries in Python's lib directory if present.
    # Anything found here will have to land in the dist folder, because there
    # just is no logical other place, and hope for the best ...
    # TODO: not supported yet!
    if isWin32Windows():
        lib_dir = os.path.join(base_prefix, "Library", "bin")
    else:
        lib_dir = os.path.join(base_prefix, "lib")

    if os.path.isdir(lib_dir):
        re_mkllib = re.compile(r"^(?:lib)?mkl\w+\.(?:dll|so|dylib)",
                               re.IGNORECASE)
        dlls_mkl = [f for f in os.listdir(lib_dir) if re_mkllib.match(f)]
        if dlls_mkl:
            info(" Additional MKL libraries found.")
            info(" Not copying MKL binaries in '%s' for numpy!" % libdir)
            # binaries += [(os.path.join(lib_dir, f), '.') for f in dlls_mkl]

    return binaries
Beispiel #31
0
def compileTree(main_module):
    source_dir = OutputDirectories.getSourceDirectoryPath()

    if not Options.shallOnlyExecCCompilerCall():
        if Options.isShowProgress() or Options.isShowMemory():
            info(
                "Total memory usage before generating C code: {memory}:".format(
                    memory=MemoryUsage.getHumanReadableProcessMemoryUsage()
                )
            )
        # Now build the target language code for the whole tree.
        makeSourceDirectory(main_module=main_module)

        frozen_code = generateBytecodeFrozenCode()

        if frozen_code is not None:
            writeSourceCode(
                filename=os.path.join(source_dir, "__frozen.c"), source_code=frozen_code
            )

        if not isWin32Windows():
            writeBinaryData(
                filename=os.path.join(source_dir, "__constants.bin"),
                binary_data=ConstantCodes.stream_data.getBytes(),
            )
    else:
        source_dir = OutputDirectories.getSourceDirectoryPath()

        if not os.path.isfile(os.path.join(source_dir, "__helpers.h")):
            sys.exit("Error, no previous build directory exists.")

    if Options.isShowProgress() or Options.isShowMemory():
        info(
            "Total memory usage before running scons: {memory}:".format(
                memory=MemoryUsage.getHumanReadableProcessMemoryUsage()
            )
        )

    if Options.isShowMemory():
        InstanceCounters.printStats()

    if Options.isDebug():
        Reports.doMissingOptimizationReport()

    if Options.shallNotDoExecCCompilerCall():
        return True, {}

    # Run the Scons to build things.
    result, options = runScons(main_module=main_module, quiet=not Options.isShowScons())

    return result, options
Beispiel #32
0
def get_numpy_core_binaries():
    """ Return any binaries in numpy/core and/or numpy/.libs, whether or not actually used by our script.

    Notes:
        This covers the special cases like MKL binaries, which cannot be detected by dependency managers.

    Returns:
        tuple of abspaths of binaries
    """

    # covers/unifies cases, where sys.base_prefix does not deliver
    # everything we need and/or is not an abspath.
    base_prefix = getattr(sys, "real_prefix", getattr(sys, "base_prefix", sys.prefix))

    base_prefix = os.path.abspath(base_prefix)

    binaries = []

    # first look in numpy/.libs for binaries
    _, pkg_dir = get_package_paths("numpy")
    libdir = os.path.join(pkg_dir, ".libs")
    if os.path.isdir(libdir):
        dlls_pkg = [f for f in os.listdir(libdir)]
        binaries += [(os.path.join(libdir, f), ".") for f in dlls_pkg]

    # then look for libraries in numpy.core package path
    # should already return the MKL DLLs in ordinary cases
    _, pkg_dir = get_package_paths("numpy.core")
    re_anylib = re.compile(r"\w+\.(?:dll|so|dylib)", re.IGNORECASE)
    dlls_pkg = [f for f in os.listdir(pkg_dir) if re_anylib.match(f)]
    binaries += [(os.path.join(pkg_dir, f), ".") for f in dlls_pkg]

    # Also look for MKL libraries in Python's lib directory if present.
    # Anything found here will have to land in the dist folder, because there
    # just is no logical other place, and hope for the best ...
    # TODO: not supported yet!
    if isWin32Windows():
        lib_dir = os.path.join(base_prefix, "Library", "bin")
    else:
        lib_dir = os.path.join(base_prefix, "lib")

    if os.path.isdir(lib_dir):
        re_mkllib = re.compile(r"^(?:lib)?mkl\w+\.(?:dll|so|dylib)", re.IGNORECASE)
        dlls_mkl = [f for f in os.listdir(lib_dir) if re_mkllib.match(f)]
        if dlls_mkl:
            info(" Additional MKL libraries found.")
            info(" Not copying MKL binaries in '%s' for numpy!" % libdir)
            # binaries += [(os.path.join(lib_dir, f), '.') for f in dlls_mkl]

    return binaries
Beispiel #33
0
    def considerExtraDlls(self, dist_dir, module):
        module_name = module.getFullName()

        if module_name == "zmq.libzmq" and isWin32Windows():
            # TODO: Very strange thing for zmq on Windows, needs the .pyd file in wrong dir too. Have
            # this done in a dedicated form somewhere.
            shutil.copyfile(
                os.path.join(dist_dir, "zmq\\libzmq.pyd"),
                os.path.join(dist_dir, "libzmq" +
                             getSharedLibrarySuffix(preferred=True)),
            )

        return NuitkaPluginBase.considerExtraDlls(self,
                                                  dist_dir=dist_dir,
                                                  module=module)
Beispiel #34
0
 def _getResourcesTargetDir(self):
     """Where does the Qt bindings package expect the resources files."""
     if isMacOS():
         return "Content/Resources"
     elif isWin32Windows():
         if self.binding_name in ("PySide2", "PyQt5"):
             return "resources"
         else:
             # While PyQt6/PySide6 complains about these, they are not working
             # return os.path.join(self.binding_name, "resources")
             return "."
     else:
         if self.binding_name in ("PySide2", "PySide6", "PyQt6"):
             return "."
         elif self.binding_name == "PyQt5":
             return "resources"
         else:
             assert False
Beispiel #35
0
def get_scipy_core_binaries():
    """ Return binaries from the extra-dlls folder (Windows only).
    """
    binaries = []
    if not isWin32Windows():
        return binaries
    extra_dll = os.path.join(
        os.path.dirname(get_module_file_attribute("scipy")), "extra-dll")
    if not os.path.isdir(extra_dll):
        return binaries

    netto_bins = os.listdir(extra_dll)

    for f in netto_bins:
        if not f.endswith(".dll"):
            continue
        binaries.append((os.path.join(extra_dll, f), "."))

    return binaries
Beispiel #36
0
def get_scipy_core_binaries():
    """ Return binaries from the extra-dlls folder (Windows only).
    """
    binaries = []
    if not isWin32Windows():
        return binaries
    extra_dll = os.path.join(
        os.path.dirname(get_module_file_attribute("scipy")), "extra-dll"
    )
    if not os.path.isdir(extra_dll):
        return binaries

    netto_bins = os.listdir(extra_dll)

    for f in netto_bins:
        if not f.endswith(".dll"):
            continue
        binaries.append((os.path.join(extra_dll, f), "."))

    return binaries