Files
nuitka-mirror/nuitka/Options.py
2019-01-24 16:28:13 +01:00

463 lines
10 KiB
Python

# Copyright 2019, Kay Hayen, mailto:kay.hayen@gmail.com
#
# Part of "Nuitka", an optimizing Python compiler that is compatible and
# integrates with CPython, but also works on its own.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
""" Options module """
import logging
import os
import sys
from nuitka.OptionParsing import parseOptions
from nuitka.utils import Utils
options = None
positional_args = None
extra_args = []
is_nuitka_run = None
def parseArgs():
# singleton with many cases, pylint: disable=global-statement,too-many-branches
global is_nuitka_run, options, positional_args, extra_args
is_nuitka_run, options, positional_args, extra_args = parseOptions()
if shallListPlugins():
from nuitka.plugins.Plugins import listPlugins
listPlugins()
if options.verbose:
logging.getLogger().setLevel(logging.DEBUG)
else:
logging.getLogger().setLevel(logging.INFO)
# Standalone mode implies an executable, not importing "site" module, which is
# only for this machine, recursing to all modules, and even including the
# standard library.
if options.is_standalone:
if not options.executable:
sys.exit("""\
Error, conflicting options, cannot make standalone module, only executable.""")
options.recurse_all = True
if Utils.getOS() == "NetBSD":
logging.warning("Standalone mode on NetBSD is not functional, due to $ORIGIN linkage not being supported.")
for any_case_module in getShallFollowModules():
if any_case_module.startswith('.'):
bad = True
else:
for char in "/\\:":
if char in any_case_module:
bad = True
break
else:
bad = False
if bad:
sys.exit(
"""\
Error, '--follow-import-to' takes only module names, not directory path '%s'.""" % \
any_case_module
)
for no_case_module in getShallFollowInNoCase():
if no_case_module.startswith('.'):
bad = True
else:
for char in "/\\:":
if char in no_case_module:
bad = True
break
else:
bad = False
if bad:
sys.exit(
"""\
Error, '--nofollow-import-to' takes only module names, not directory path '%s'.""" % \
no_case_module
)
scons_python = getPythonPathForScons()
if scons_python is not None and not os.path.exists(scons_python):
sys.exit("Error, no such Python binary '%s'." % scons_python)
if options.output_filename is not None and \
(isStandaloneMode() or shallMakeModule()):
sys.exit(
"""\
Error, can only specify output filename for acceleration mode, not for module
mode where filenames are mandatory, and not for standalone where there is a
sane default used inside the dist folder."""
)
def isVerbose():
return options.verbose
def shallTraceExecution():
return options.trace_execution
def shallExecuteImmediately():
return options.immediate_execution
def shallRunInDebugger():
return options.debugger
def shallDumpBuiltTreeXML():
return options.dump_xml
def shallOnlyExecCCompilerCall():
return options.recompile_c_only
def shallNotDoExecCCompilerCall():
return options.generate_c_only
def getFileReferenceMode():
if options.file_reference_mode is None:
value = ("runtime"
if shallMakeModule() or isStandaloneMode() else
"original")
else:
value = options.file_reference_mode
return value
def shallMakeModule():
return not options.executable
def shallCreatePyiFile():
return options.pyi_file
def isAllowedToReexecute():
return options.allow_reexecute
def shallFollowStandardLibrary():
return options.recurse_stdlib
def shallFollowNoImports():
return options.recurse_none
def shallFollowAllImports():
return options.recurse_all
def _splitShellPattern(value):
return value.split(',') if '{' not in value else [value]
def getShallFollowInNoCase():
return sum(
[_splitShellPattern(x) for x in options.recurse_not_modules ],
[]
)
def getShallFollowModules():
return sum(
[_splitShellPattern(x) for x in options.recurse_modules + options.include_modules + options.include_packages],
[]
)
def getShallFollowExtra():
return sum(
[_splitShellPattern(x) for x in options.recurse_extra],
[]
)
def getShallFollowExtraFilePatterns():
return sum(
[_splitShellPattern(x) for x in options.recurse_extra_files],
[]
)
def getMustIncludeModules():
return sum(
[_splitShellPattern(x) for x in options.include_modules],
[]
)
def getMustIncludePackages():
return sum(
[_splitShellPattern(x) for x in options.include_packages ],
[]
)
def shallWarnImplicitRaises():
return options.warn_implicit_exceptions
def shallWarnUnusualCode():
return options.warn_unusual_code
def assumeYesForDownloads():
return options.assume_yes_for_downloads
def isDebug():
return options is not None and (options.debug or options.debugger)
def isPythonDebug():
return options.python_debug or sys.flags.debug
def isUnstripped():
return options.unstripped or options.profile
def isProfile():
return options.profile
def shallCreateGraph():
return options.graph
def getOutputFilename():
return options.output_filename
def getOutputPath(path):
if options.output_dir:
return os.path.normpath(os.path.join(options.output_dir, path))
else:
return path
def getOutputDir():
return options.output_dir if options.output_dir else '.'
def getPositionalArgs():
return tuple(positional_args)
def getMainArgs():
return tuple(extra_args)
def shallOptimizeStringExec():
return False
def shallClearPythonPathEnvironment():
return not options.keep_pythonpath
def isShowScons():
return options.show_scons
def getJobLimit():
return int(options.jobs)
def isLto():
return options.lto
def isClang():
return options.clang
def isMingw64():
return options.mingw64
def getMsvcVersion():
return options.msvc
def shallDisableConsoleWindow():
return options.win_disable_console
def isFullCompat():
return not options.improved
def isShowProgress():
return options.show_progress
def isShowMemory():
return options is not None and options.show_memory
def isShowInclusion():
return options.show_inclusion
def isRemoveBuildDir():
return options.remove_build and not options.generate_c_only
def getIntendedPythonArch():
return options.python_arch
def isExperimental(indication):
""" Are experimental features to be enabled."""
return hasattr(options, "experimental") and indication in options.experimental
def getExperimentalIndications():
if hasattr(options, "experimental"):
return options.experimental
else:
return ()
def shallExplainImports():
return options is not None and options.explain_imports
def isStandaloneMode():
return options.is_standalone
def getIconPath():
return options.icon_path
_python_flags = None
def getPythonFlags():
# singleton, pylint: disable=global-statement
global _python_flags
if _python_flags is None:
_python_flags = set()
for parts in options.python_flags:
for part in parts.split(','):
if part in ("-S", "nosite", "no_site"):
_python_flags.add("no_site")
elif part in ("static_hashes", "norandomization",
"no_randomization"):
_python_flags.add("no_randomization")
elif part in ("-v", "trace_imports", "trace_import"):
_python_flags.add("trace_imports")
elif part in ("no_warnings", "nowarnings"):
_python_flags.add("no_warnings")
elif part in ("-O", "no_asserts", "noasserts"):
_python_flags.add("no_asserts")
elif part in ("-OO", "no_docstrings", "nodocstrings"):
_python_flags.add("no_docstrings")
_python_flags.add("no_asserts")
else:
# Do not warn before executing in final context.
if "PYTHONHASHSEED" in os.environ:
logging.warning("Unsupported flag '%s'.", part)
return _python_flags
def shallFreezeAllStdlib():
return not shallFollowStandardLibrary()
def shallNotUseDependsExeCachedResults():
return options.no_dependency_cache or options.update_dependency_cache
def shallNotStoreDependsExeCachedResults():
return options.no_dependency_cache
def shallListPlugins():
return options is not None and options.list_plugins
def getPluginsEnabled():
""" Return the names of plugin that were enabled.
"""
result = set()
if options:
for plugin_enabled in options.plugins_enabled:
result.add(plugin_enabled.split('=',1)[0])
return tuple(result)
def getPluginOptions(plugin_name):
""" Return the options provided for a specific plugin.
"""
result = []
if options:
for plugin_enabled in options.plugins_enabled:
if '=' not in plugin_enabled:
continue
name, args = plugin_enabled.split('=',1)
if name == plugin_name:
result.extend(args.split(','))
return result
def getPluginsDisabled():
""" Return the names of plugin that were disabled.
"""
if not options:
return ()
return tuple(set(options.plugins_disabled))
def getUserPlugins():
if not options:
return ()
return tuple(set(options.user_plugins))
def shallDetectMissingPlugins():
return options is not None and options.detect_missing_plugins
def getPythonPathForScons():
return options.python_scons