Ejemplo n.º 1
0
def compileTree(main_module):
    source_dir = getSourceDirectoryPath(main_module)

    if not Options.shallOnlyExecCppCall():
        # Now build the target language code for the whole tree.
        makeSourceDirectory(
            main_module = main_module
        )

        if Options.isStandaloneMode():
            for late_import in detectLateImports():
                addFrozenModule(late_import)

        if getFrozenModuleCount():
            frozen_code = generateBytecodeFrozenCode()

            writeSourceCode(
                filename = Utils.joinpath(
                    source_dir,
                    "__frozen.cpp"
                ),
                source_code = frozen_code
            )

        writeBinaryData(
            filename    = Utils.joinpath(source_dir, "__constants.bin"),
            binary_data = ConstantCodes.stream_data.getBytes()
        )
    else:
        source_dir = getSourceDirectoryPath(main_module)

        if not Utils.isFile( Utils.joinpath(source_dir, "__helpers.hpp")):
            sys.exit("Error, no previous build directory exists.")

    if Options.isShowProgress():
        Tracing.printLine(
            """Total memory usage before running scons: {memory}:""".format(
                memory      = Utils.getHumanReadableProcessMemoryUsage()
            )
        )

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

    return result, options
Ejemplo n.º 2
0
def main():
    """ Main program flow of Nuitka

        At this point, options will be parsed already, Nuitka will be executing
        in the desired version of Python with desired flags, and we just get
        to execute the task assigned.

        We might be asked to only re-compile generated C++, dump only an XML
        representation of the internal node tree after optimization, etc.
    """

    # Main has to fullfil many options, leading to many branches
    # pylint: disable=R0912

    positional_args = Options.getPositionalArgs()
    assert len( positional_args ) > 0

    filename = Options.getPositionalArgs()[0]

    # Inform the importing layer about the main script directory, so it can use
    # it when attempting to follow imports.
    Importing.setMainScriptDirectory(
        main_dir = Utils.dirname(Utils.abspath(filename))
    )

    # Detect to be frozen modules if any, so we can consider to not recurse
    # to them.
    if Options.isStandaloneMode():
        for early_import in detectEarlyImports():
            addFrozenModule(early_import)

            if early_import[0] == "site":
                origin_prefix_filename = Utils.joinpath(
                    Utils.dirname(early_import[3]),
                    "orig-prefix.txt"
                )

                if Utils.isFile(origin_prefix_filename):
                    global data_files

                    data_files.append(
                        (filename, "orig-prefix.txt")
                    )

    # Turn that source code into a node tree structure.
    try:
        main_module = createNodeTree(
            filename = filename
        )
    except (SyntaxError, IndentationError) as e:
        if Options.isFullCompat() and \
           e.args[0].startswith("unknown encoding:"):
            if Utils.python_version >= 333 or \
               (
                   Utils.python_version >= 276 and \
                   Utils.python_version < 300
               ) or \
               "2.7.5+" in sys.version or \
               "3.3.2+" in sys.version: # Debian backports have "+" versions
                complaint = "no-exist"
            else:
                complaint = "with BOM"

            e.args = (
                "encoding problem: %s" % complaint,
                (e.args[1][0], 1, None, None)
            )

        sys.exit(
            SyntaxErrors.formatOutput(e)
        )

    if Options.shallDumpBuiltTree():
        dumpTree(main_module)
    elif Options.shallDumpBuiltTreeXML():
        dumpTreeXML(main_module)
    elif Options.shallDisplayBuiltTree():
        displayTree(main_module)
    else:
        result, options = compileTree(
            main_module = main_module
        )

        # Exit if compilation failed.
        if not result:
            sys.exit(1)

        # Remove the source directory (now build directory too) if asked to.
        if Options.isRemoveBuildDir():
            shutil.rmtree(
                getSourceDirectoryPath(main_module)
            )

        if Options.isStandaloneMode():
            binary_filename = options["result_name"] + ".exe"

            standalone_entry_points.insert(
                0,
                (binary_filename, None)
            )

            if Utils.getOS() == "NetBSD":
                warning("Standalone mode on NetBSD is not functional, due to $ORIGIN linkage not being supported.")

            for early_dll in detectUsedDLLs(standalone_entry_points):
                shutil.copy(
                    early_dll,
                    Utils.joinpath(
                        getStandaloneDirectoryPath(main_module),
                        Utils.basename(early_dll)
                    )
                )

                if Options.isShowInclusion():
                    info("Included used shared library '%s'.", early_dll)

        if Options.isStandaloneMode():
            for source_filename, target_filename in data_files:
                shutil.copy2(
                    source_filename,
                    Utils.joinpath(
                        getStandaloneDirectoryPath(main_module),
                        target_filename
                    )
                )

        # Modules should not be executable, but Scons creates them like it, fix
        # it up here.
        if Utils.getOS() != "Windows" and Options.shallMakeModule():
            subprocess.call(
                (
                    "chmod",
                    "-x",
                    getResultFullpath(main_module)
                )
            )

        # Execute the module immediately if option was given.
        if Options.shallExecuteImmediately():
            if Options.shallMakeModule():
                executeModule(
                    tree       = main_module,
                    clean_path = Options.shallClearPythonPathEnvironment()
                )
            else:
                executeMain(
                    binary_filename = getResultFullpath(main_module),
                    tree            = main_module,
                    clean_path      = Options.shallClearPythonPathEnvironment()
                )