def buildMainModuleTree(filename, is_main): # Detect to be frozen modules if any, so we can consider to not follow # to them. if is_main: # TODO: Doesn't work for deeply nested packages at all. if Options.hasPythonFlagPackageMode(): module_name = ModuleName(os.path.basename(filename) + ".__main__") else: module_name = ModuleName("__main__") else: module_name = Importing.getModuleNameAndKindFromFilename(filename)[0] module, _added = buildModule( module_name=module_name, module_filename=filename, source_code=None, is_top=True, is_main=is_main, is_extension=False, is_fake=False, hide_syntax_error=False, ) if is_main and Options.isStandaloneMode(): module.setEarlyModules(detectEarlyImports()) # Main modules do not get added to the import cache, but plugins get to see it. if module.isMainModule(): Plugins.onModuleDiscovered(module) else: addImportedModule(imported_module=module) return module
def buildModuleTree(filename, package, is_top, is_main): module, source_ref, source_filename = decideModuleTree( filename=filename, package=package, is_top=is_top, is_main=is_main, is_shlib=False, ) if is_top: ModuleRegistry.addRootModule(module) OutputDirectories.setMainModule(module) # Detect to be frozen modules if any, so we can consider to not recurse # to them. if Options.isStandaloneMode(): detectEarlyImports() # If there is source code associated (not the case for namespace packages of # Python3.3 or higher, then read it. if source_filename is not None: source_code = readSourceCodeFromFilename( module_name=module.getFullName(), source_filename=source_filename ) if is_main: checkPythonVersionFromCode(source_code) # Read source code. createModuleTree( module=module, source_ref=source_ref, source_code=source_code, is_main=is_main, ) # Main modules do not get added to the import cache, but plugins get to see it. if module.isMainModule(): Plugins.onModuleDiscovered(module) else: addImportedModule(imported_module=module) return module
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() )