예제 #1
0
파일: Execution.py 프로젝트: nexcvon/Nuitka
def wrapCommandForDebuggerForExec(*args):
    """Wrap a command for system debugger to call exec

    Args:
        args: (list of str) args for call to be debugged
    Returns:
        args tuple with debugger command inserted

    Notes:
        Currently only gdb and lldb are supported, but adding more
        debuggers would be very welcome.
    """

    gdb_path = getExecutablePath("gdb")

    # Windows extra ball, attempt the downloaded one.
    if isWin32Windows() and gdb_path is None:
        from nuitka.Options import assumeYesForDownloads

        mingw64_gcc_path = getCachedDownloadedMinGW64(
            target_arch=getArchitecture(),
            assume_yes_for_downloads=assumeYesForDownloads(),
        )

        with withEnvironmentPathAdded("PATH", os.path.dirname(mingw64_gcc_path)):
            lldb_path = getExecutablePath("lldb")

    if gdb_path is None and lldb_path is None:
        lldb_path = getExecutablePath("lldb")

        if lldb_path is None:
            general.sysexit("Error, no 'gdb' or 'lldb' binary found in path.")

    if gdb_path is not None:
        args = (gdb_path, "gdb", "-ex=run", "-ex=where", "-ex=quit", "--args") + args
    else:
        args = (lldb_path, "lldb", "-o", "run", "-o", "bt", "-o", "quit", "--") + args

    return args
def getAppImageToolPath():
    """Return the path of appimagetool (for Linux).

    Will prompt the user to download if not already cached in AppData
    directory for Nuitka.
    """

    appimagetool_url = (
        "https://github.com/AppImage/AppImageKit/releases/download/12/appimagetool-%s.AppImage"
        % getArchitecture())

    return getCachedDownload(
        url=appimagetool_url,
        is_arch_specific=True,
        binary=appimagetool_url.rsplit("/", 1)[1],
        flatten=True,
        specifity=appimagetool_url.rsplit("/", 2)[1],
        message="""\
Nuitka will make use of AppImage (https://appimage.org/) tool
to combine Nuitka dist folder to onefile binary.""",
        reject="Nuitka does not work in --onefile on Linux without.",
        assume_yes_for_downloads=assumeYesForDownloads(),
    )
예제 #3
0
파일: DependsExe.py 프로젝트: psydox/Nuitka
def getDependsExePath():
    """Return the path of depends.exe (for Windows).

    Will prompt the user to download if not already cached in AppData
    directory for Nuitka.
    """
    if getArchitecture() == "x86":
        depends_url = "https://dependencywalker.com/depends22_x86.zip"
    else:
        depends_url = "https://dependencywalker.com/depends22_x64.zip"

    return getCachedDownload(
        url=depends_url,
        is_arch_specific=getArchitecture(),
        binary="depends.exe",
        flatten=True,
        specificity="",  # Note: If there ever was an update, put version here.
        message="""\
Nuitka will make use of Dependency Walker (https://dependencywalker.com) tool
to analyze the dependencies of Python extension modules.""",
        reject="Nuitka does not work in --standalone or --onefile on Windows without.",
        assume_yes_for_downloads=assumeYesForDownloads(),
    )
예제 #4
0
def packDistFolderToOnefileLinux(onefile_output_filename, dist_dir, binary_filename):
    """Pack to onefile binary on Linux.

    Notes: This is mostly a wrapper around AppImage, which does all the heavy
    lifting.
    """

    if not locateDLL("fuse"):
        postprocessing_logger.sysexit(
            """\
Error, the fuse library (libfuse.so.x from fuse2, *not* fuse3) must be installed
for onefile creation to work on Linux."""
        )

    # This might be possible to avoid being done with --runtime-file.
    apprun_filename = os.path.join(dist_dir, "AppRun")
    with open(apprun_filename, "w") as output_file:
        output_file.write(
            """\
#!/bin/bash
exec -a $ARGV0 $APPDIR/%s $@"""
            % os.path.basename(binary_filename)
        )

    addFileExecutablePermission(apprun_filename)

    binary_basename = os.path.basename(getResultBasepath())

    icon_paths = getIconPaths()

    assert icon_paths
    extension = os.path.splitext(icon_paths[0])[1].lower()

    shutil.copyfile(icon_paths[0], getResultBasepath() + extension)

    with open(getResultBasepath() + ".desktop", "w") as output_file:
        output_file.write(
            """\
[Desktop Entry]
Name=%(binary_basename)s
Exec=%(binary_filename)s
Icon=%(binary_basename)s
Type=Application
Categories=Utility;"""
            % {
                "binary_basename": binary_basename,
                "binary_filename": os.path.basename(binary_filename),
            }
        )

    postprocessing_logger.info(
        "Creating single file from dist folder, this may take a while."
    )

    stdout_filename = binary_filename + ".appimage.stdout.txt"
    stderr_filename = binary_filename + ".appimage.stderr.txt"

    stdout_file = open(stdout_filename, "wb")
    stderr_file = open(stderr_filename, "wb")

    # Starting the process while locked, so file handles are not duplicated.
    appimagetool_process = subprocess.Popen(
        (
            _getAppImageToolPath(
                for_operation=True, assume_yes_for_downloads=assumeYesForDownloads()
            ),
            dist_dir,
            "--comp",
            "xz",
            "-n",
            onefile_output_filename,
        ),
        shell=False,
        stdin=getNullInput(),
        stdout=stdout_file,
        stderr=stderr_file,
    )

    result = appimagetool_process.wait()

    stdout_file.close()
    stderr_file.close()

    if not os.path.exists(onefile_output_filename):
        postprocessing_logger.sysexit(
            "Error, expected output file %r not created by AppImage, check its outputs %r and %r."
            % (onefile_output_filename, stdout_filename, stderr_filename)
        )

    if result != 0:
        # Useless now.
        os.unlink(onefile_output_filename)

        if b"Text file busy" in getFileContents(stderr_filename, mode="rb"):
            postprocessing_logger.sysexit(
                "Error, error exit from AppImage because target file is locked."
            )

        postprocessing_logger.sysexit(
            "Error, error exit from AppImage, check its outputs %r and %r."
            % (stdout_filename, stderr_filename)
        )

    os.unlink(stdout_filename)
    os.unlink(stderr_filename)

    postprocessing_logger.info("Completed onefile creation.")
예제 #5
0
def getDependsExePath():
    """ Return the path of depends.exe (for Windows).

        Will prompt the user to download if not already cached in AppData
        directory for Nuitka.
    """
    if Utils.getArchitecture() == "x86":
        depends_url = "http://dependencywalker.com/depends22_x86.zip"
    else:
        depends_url = "http://dependencywalker.com/depends22_x64.zip"

    nuitka_app_dir = getAppDir()

    nuitka_depends_dir = os.path.join(nuitka_app_dir, Utils.getArchitecture())
    nuitka_depends_zip = os.path.join(nuitka_depends_dir,
                                      os.path.basename(depends_url))
    depends_exe = os.path.join(nuitka_depends_dir, "depends.exe")
    makePath(nuitka_depends_dir)

    if not os.path.isfile(nuitka_depends_zip) and not os.path.isfile(
            depends_exe):
        if assumeYesForDownloads():
            reply = "y"
        else:
            Tracing.printLine("""\
Nuitka will make use of Dependency Walker (http://dependencywalker.com) tool
to analyze the dependencies of Python extension modules. Is it OK to download
and put it in "%s".
No installer needed, cached, one time question.

Proceed and download? [Yes]/No """ % (nuitka_app_dir))
            Tracing.flushStdout()

            reply = raw_input()

        if reply.lower() in ("no", "n"):
            sys.exit(
                "Nuitka does not work in --standalone on Windows without.")

        info("Downloading '%s'" % depends_url)

        try:
            urlretrieve(depends_url, nuitka_depends_zip)
        except Exception:  # Any kind of error, pylint: disable=broad-except
            sys.exit("""Failed to download '%s'.\
Contents should manually be extracted to '%s'.""" %
                     (depends_url, nuitka_depends_dir))

    if not os.path.isfile(depends_exe):
        info("Extracting to '%s'" % depends_exe)

        import zipfile

        try:
            depends_zip = zipfile.ZipFile(nuitka_depends_zip)
            depends_zip.extractall(nuitka_depends_dir)
        except Exception:  # Catching anything zip throws, pylint: disable=broad-except
            info("Problem with the downloaded zip file, deleting it.")

            deleteFile(depends_exe, must_exist=False)
            deleteFile(nuitka_depends_zip, must_exist=True)

            sys.exit("Error, need '%s' as extracted from '%s'." %
                     (depends_exe, depends_url))

    assert os.path.isfile(depends_exe)

    return depends_exe
예제 #6
0
파일: Onefile.py 프로젝트: psydox/Nuitka
def packDistFolderToOnefileLinux(onefile_output_filename, dist_dir,
                                 binary_filename):
    """Pack to onefile binary on Linux.

    Notes: This is mostly a wrapper around AppImage, which does all the heavy
    lifting.
    """

    if not locateDLL("fuse"):
        postprocessing_logger.sysexit("""\
Error, the fuse library (libfuse.so.x from fuse2, *not* fuse3) must be installed
for onefile creation to work on Linux.""")

    # This might be possible to avoid being done with --runtime-file.
    apprun_filename = os.path.join(dist_dir, "AppRun")
    putTextFileContents(
        apprun_filename,
        contents="""\
#!/bin/bash
exec -a $ARGV0 $APPDIR/%s \"$@\"""" % os.path.basename(binary_filename),
    )

    addFileExecutablePermission(apprun_filename)

    binary_basename = os.path.basename(getResultBasepath())

    icon_paths = getIconPaths()

    assert icon_paths
    extension = os.path.splitext(icon_paths[0])[1].lower()

    copyFile(icon_paths[0], getResultBasepath() + extension)

    putTextFileContents(
        getResultBasepath() + ".desktop",
        contents="""\
[Desktop Entry]
Name=%(binary_basename)s
Exec=%(binary_filename)s
Icon=%(binary_basename)s
Type=Application
Categories=Utility;""" % {
            "binary_basename": binary_basename,
            "binary_filename": os.path.basename(binary_filename),
        },
    )

    postprocessing_logger.info(
        "Creating single file from dist folder, this may take a while.")

    stdout_filename = binary_filename + ".appimage.stdout.txt"
    stderr_filename = binary_filename + ".appimage.stderr.txt"

    stdout_file = openTextFile(stdout_filename, "wb")
    stderr_file = openTextFile(stderr_filename, "wb")

    command = (
        _getAppImageToolPath(for_operation=True,
                             assume_yes_for_downloads=assumeYesForDownloads()),
        dist_dir,
        "--comp",
        getAppImageCompression(),
        "-n",
        onefile_output_filename,
    )

    stderr_file.write(b"Executed %r\n" % " ".join(command))

    # Starting the process while locked, so file handles are not duplicated, we
    # need fine grained control over process here, therefore we cannot use the
    # Execution.executeProcess() function without making it too complex and not
    # all Python versions allow using with, pylint: disable=consider-using-with
    # pylint: disable
    appimagetool_process = subprocess.Popen(
        command,
        shell=False,
        stdin=getNullInput(),
        stdout=stdout_file,
        stderr=stderr_file,
    )

    result = appimagetool_process.wait()

    stdout_file.close()
    stderr_file.close()

    if result != 0:
        # Useless result if there were errors, so now remove it.
        deleteFile(onefile_output_filename, must_exist=False)

        stderr = getFileContents(stderr_filename, mode="rb")

        if b"Text file busy" in stderr:
            postprocessing_logger.sysexit(
                "Error, error exit from AppImage because target file is locked."
            )

        if b"modprobe fuse" in stderr:
            postprocessing_logger.sysexit(
                "Error, error exit from AppImage because fuse kernel module was not loaded."
            )

        postprocessing_logger.sysexit(
            "Error, error exit from AppImage, check its outputs '%s' and '%s'."
            % (stdout_filename, stderr_filename))

    if not os.path.exists(onefile_output_filename):
        postprocessing_logger.sysexit(
            "Error, expected output file %r not created by AppImage, check its outputs '%s' and '%s'."
            % (onefile_output_filename, stdout_filename, stderr_filename))

    deleteFile(stdout_filename, must_exist=True)
    deleteFile(stderr_filename, must_exist=True)

    postprocessing_logger.info("Completed onefile creation.")
예제 #7
0
def getDependsExePath():
    """ Return the path of depends.exe (for Windows).

        Will prompt the user to download if not already cached in AppData
        directory for Nuitka.
    """
    if Utils.getArchitecture() == "x86":
        depends_url = "http://dependencywalker.com/depends22_x86.zip"
    else:
        depends_url = "http://dependencywalker.com/depends22_x64.zip"

    nuitka_app_dir = getAppDir()

    nuitka_depends_dir = os.path.join(nuitka_app_dir, Utils.getArchitecture())
    nuitka_depends_zip = os.path.join(nuitka_depends_dir, os.path.basename(depends_url))
    depends_exe = os.path.join(nuitka_depends_dir, "depends.exe")
    makePath(nuitka_depends_dir)

    if not os.path.isfile(nuitka_depends_zip) and not os.path.isfile(depends_exe):
        if assumeYesForDownloads():
            reply = "y"
        else:
            Tracing.printLine(
                """\
Nuitka will make use of Dependency Walker (http://dependencywalker.com) tool
to analyze the dependencies of Python extension modules. Is it OK to download
and put it in "%s".
No installer needed, cached, one time question.

Proceed and download? [Yes]/No """
                % (nuitka_app_dir)
            )
            Tracing.flushStdout()

            reply = raw_input()

        if reply.lower() in ("no", "n"):
            sys.exit("Nuitka does not work in --standalone on Windows without.")

        info("Downloading '%s'" % depends_url)

        try:
            urlretrieve(depends_url, nuitka_depends_zip)
        except Exception:  # Any kind of error, pylint: disable=broad-except
            sys.exit(
                """Failed to download '%s'.\
Contents should manually be extracted to '%s'."""
                % (depends_url, nuitka_depends_dir)
            )

    if not os.path.isfile(depends_exe):
        info("Extracting to '%s'" % depends_exe)

        import zipfile

        try:
            depends_zip = zipfile.ZipFile(nuitka_depends_zip)
            depends_zip.extractall(nuitka_depends_dir)
        except Exception:  # Catching anything zip throws, pylint:disable=W0703
            info("Problem with the downloaded zip file, deleting it.")

            deleteFile(depends_exe, must_exist=False)
            deleteFile(nuitka_depends_zip, must_exist=True)

            sys.exit(
                "Error, need '%s' as extracted from '%s'." % (depends_exe, depends_url)
            )

    assert os.path.isfile(depends_exe)

    return depends_exe