Nuitka-winsvc 2.7.7__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of Nuitka-winsvc might be problematic. Click here for more details.
- nuitka/Builtins.py +259 -0
- nuitka/BytecodeCaching.py +184 -0
- nuitka/Bytecodes.py +109 -0
- nuitka/CacheCleanup.py +54 -0
- nuitka/Constants.py +425 -0
- nuitka/Errors.py +93 -0
- nuitka/HardImportRegistry.py +408 -0
- nuitka/MainControl.py +1201 -0
- nuitka/ModuleRegistry.py +364 -0
- nuitka/OptionParsing.py +2473 -0
- nuitka/Options.py +2948 -0
- nuitka/OutputDirectories.py +201 -0
- nuitka/PostProcessing.py +551 -0
- nuitka/Progress.py +252 -0
- nuitka/PythonFlavors.py +426 -0
- nuitka/PythonOperators.py +146 -0
- nuitka/PythonVersions.py +513 -0
- nuitka/Serialization.py +291 -0
- nuitka/SourceCodeReferences.py +176 -0
- nuitka/Tracing.py +579 -0
- nuitka/TreeXML.py +141 -0
- nuitka/Variables.py +515 -0
- nuitka/Version.py +88 -0
- nuitka/__init__.py +19 -0
- nuitka/__main__.py +224 -0
- nuitka/__past__.py +217 -0
- nuitka/build/Backend.scons +1111 -0
- nuitka/build/CCompilerVersion.scons +281 -0
- nuitka/build/DataComposerInterface.py +116 -0
- nuitka/build/Offsets.scons +626 -0
- nuitka/build/Onefile.scons +564 -0
- nuitka/build/SconsCaching.py +451 -0
- nuitka/build/SconsCompilerSettings.py +1133 -0
- nuitka/build/SconsHacks.py +215 -0
- nuitka/build/SconsInterface.py +664 -0
- nuitka/build/SconsProgress.py +100 -0
- nuitka/build/SconsSpawn.py +436 -0
- nuitka/build/SconsUtils.py +939 -0
- nuitka/build/__init__.py +19 -0
- nuitka/build/include/nuitka/allocator.h +450 -0
- nuitka/build/include/nuitka/builtins.h +97 -0
- nuitka/build/include/nuitka/calling.h +123 -0
- nuitka/build/include/nuitka/checkers.h +39 -0
- nuitka/build/include/nuitka/checksum_tools.h +28 -0
- nuitka/build/include/nuitka/compiled_asyncgen.h +281 -0
- nuitka/build/include/nuitka/compiled_cell.h +64 -0
- nuitka/build/include/nuitka/compiled_coroutine.h +271 -0
- nuitka/build/include/nuitka/compiled_frame.h +502 -0
- nuitka/build/include/nuitka/compiled_function.h +170 -0
- nuitka/build/include/nuitka/compiled_generator.h +287 -0
- nuitka/build/include/nuitka/compiled_method.h +54 -0
- nuitka/build/include/nuitka/constants.h +251 -0
- nuitka/build/include/nuitka/constants_blob.h +34 -0
- nuitka/build/include/nuitka/debug_settings.h +60 -0
- nuitka/build/include/nuitka/environment_variables.h +30 -0
- nuitka/build/include/nuitka/environment_variables_system.h +51 -0
- nuitka/build/include/nuitka/exception_groups.h +167 -0
- nuitka/build/include/nuitka/exceptions.h +1458 -0
- nuitka/build/include/nuitka/filesystem_paths.h +117 -0
- nuitka/build/include/nuitka/freelists.h +92 -0
- nuitka/build/include/nuitka/hedley.h +1774 -0
- nuitka/build/include/nuitka/helper/attributes.h +90 -0
- nuitka/build/include/nuitka/helper/boolean.h +86 -0
- nuitka/build/include/nuitka/helper/bytearrays.h +34 -0
- nuitka/build/include/nuitka/helper/bytes.h +28 -0
- nuitka/build/include/nuitka/helper/calling_generated.h +132 -0
- nuitka/build/include/nuitka/helper/comparisons_dual_eq.h +47 -0
- nuitka/build/include/nuitka/helper/comparisons_dual_ge.h +39 -0
- nuitka/build/include/nuitka/helper/comparisons_dual_gt.h +39 -0
- nuitka/build/include/nuitka/helper/comparisons_dual_le.h +47 -0
- nuitka/build/include/nuitka/helper/comparisons_dual_lt.h +47 -0
- nuitka/build/include/nuitka/helper/comparisons_dual_ne.h +39 -0
- nuitka/build/include/nuitka/helper/comparisons_eq.h +247 -0
- nuitka/build/include/nuitka/helper/comparisons_ge.h +197 -0
- nuitka/build/include/nuitka/helper/comparisons_gt.h +197 -0
- nuitka/build/include/nuitka/helper/comparisons_le.h +247 -0
- nuitka/build/include/nuitka/helper/comparisons_lt.h +247 -0
- nuitka/build/include/nuitka/helper/comparisons_ne.h +197 -0
- nuitka/build/include/nuitka/helper/complex.h +46 -0
- nuitka/build/include/nuitka/helper/dictionaries.h +481 -0
- nuitka/build/include/nuitka/helper/floats.h +32 -0
- nuitka/build/include/nuitka/helper/import_hard.h +121 -0
- nuitka/build/include/nuitka/helper/indexes.h +47 -0
- nuitka/build/include/nuitka/helper/ints.h +165 -0
- nuitka/build/include/nuitka/helper/iterators.h +376 -0
- nuitka/build/include/nuitka/helper/lists.h +94 -0
- nuitka/build/include/nuitka/helper/lists_generated.h +36 -0
- nuitka/build/include/nuitka/helper/mappings.h +39 -0
- nuitka/build/include/nuitka/helper/operations.h +114 -0
- nuitka/build/include/nuitka/helper/operations_binary_add.h +240 -0
- nuitka/build/include/nuitka/helper/operations_binary_bitand.h +108 -0
- nuitka/build/include/nuitka/helper/operations_binary_bitor.h +108 -0
- nuitka/build/include/nuitka/helper/operations_binary_bitxor.h +108 -0
- nuitka/build/include/nuitka/helper/operations_binary_divmod.h +103 -0
- nuitka/build/include/nuitka/helper/operations_binary_dual_add.h +34 -0
- nuitka/build/include/nuitka/helper/operations_binary_floordiv.h +103 -0
- nuitka/build/include/nuitka/helper/operations_binary_lshift.h +99 -0
- nuitka/build/include/nuitka/helper/operations_binary_matmult.h +60 -0
- nuitka/build/include/nuitka/helper/operations_binary_mod.h +304 -0
- nuitka/build/include/nuitka/helper/operations_binary_mult.h +247 -0
- nuitka/build/include/nuitka/helper/operations_binary_olddiv.h +125 -0
- nuitka/build/include/nuitka/helper/operations_binary_pow.h +90 -0
- nuitka/build/include/nuitka/helper/operations_binary_rshift.h +99 -0
- nuitka/build/include/nuitka/helper/operations_binary_sub.h +117 -0
- nuitka/build/include/nuitka/helper/operations_binary_truediv.h +103 -0
- nuitka/build/include/nuitka/helper/operations_builtin_types.h +247 -0
- nuitka/build/include/nuitka/helper/operations_inplace_add.h +173 -0
- nuitka/build/include/nuitka/helper/operations_inplace_bitand.h +76 -0
- nuitka/build/include/nuitka/helper/operations_inplace_bitor.h +76 -0
- nuitka/build/include/nuitka/helper/operations_inplace_bitxor.h +76 -0
- nuitka/build/include/nuitka/helper/operations_inplace_floordiv.h +95 -0
- nuitka/build/include/nuitka/helper/operations_inplace_lshift.h +62 -0
- nuitka/build/include/nuitka/helper/operations_inplace_matmult.h +60 -0
- nuitka/build/include/nuitka/helper/operations_inplace_mod.h +218 -0
- nuitka/build/include/nuitka/helper/operations_inplace_mult.h +184 -0
- nuitka/build/include/nuitka/helper/operations_inplace_olddiv.h +115 -0
- nuitka/build/include/nuitka/helper/operations_inplace_pow.h +87 -0
- nuitka/build/include/nuitka/helper/operations_inplace_rshift.h +62 -0
- nuitka/build/include/nuitka/helper/operations_inplace_sub.h +102 -0
- nuitka/build/include/nuitka/helper/operations_inplace_truediv.h +95 -0
- nuitka/build/include/nuitka/helper/raising.h +114 -0
- nuitka/build/include/nuitka/helper/rangeobjects.h +66 -0
- nuitka/build/include/nuitka/helper/richcomparisons.h +35 -0
- nuitka/build/include/nuitka/helper/sequences.h +33 -0
- nuitka/build/include/nuitka/helper/sets.h +25 -0
- nuitka/build/include/nuitka/helper/slices.h +314 -0
- nuitka/build/include/nuitka/helper/strings.h +30 -0
- nuitka/build/include/nuitka/helper/subscripts.h +390 -0
- nuitka/build/include/nuitka/helper/tuples.h +187 -0
- nuitka/build/include/nuitka/helpers.h +417 -0
- nuitka/build/include/nuitka/importing.h +149 -0
- nuitka/build/include/nuitka/incbin.h +402 -0
- nuitka/build/include/nuitka/jit_sources.h +25 -0
- nuitka/build/include/nuitka/prelude.h +626 -0
- nuitka/build/include/nuitka/printing.h +84 -0
- nuitka/build/include/nuitka/python_pgo.h +57 -0
- nuitka/build/include/nuitka/safe_string_ops.h +57 -0
- nuitka/build/include/nuitka/threading.h +142 -0
- nuitka/build/include/nuitka/tracing.h +82 -0
- nuitka/build/include/nuitka/type_aliases.h +30 -0
- nuitka/build/include/nuitka/unfreezing.h +91 -0
- nuitka/build/inline_copy/appdirs/LICENSE.txt +23 -0
- nuitka/build/inline_copy/appdirs/appdirs.py +611 -0
- nuitka/build/inline_copy/atomicwrites/LICENSE +19 -0
- nuitka/build/inline_copy/atomicwrites/atomicwrites.py +226 -0
- nuitka/build/inline_copy/bin/scons.py +58 -0
- nuitka/build/inline_copy/clcache/clcache/LICENSE +30 -0
- nuitka/build/inline_copy/clcache/clcache/__init__.py +4 -0
- nuitka/build/inline_copy/clcache/clcache/caching.py +2008 -0
- nuitka/build/inline_copy/colorama/LICENSE.txt +27 -0
- nuitka/build/inline_copy/colorama/colorama/__init__.py +6 -0
- nuitka/build/inline_copy/colorama/colorama/ansi.py +102 -0
- nuitka/build/inline_copy/colorama/colorama/ansitowin32.py +258 -0
- nuitka/build/inline_copy/colorama/colorama/initialise.py +80 -0
- nuitka/build/inline_copy/colorama/colorama/win32.py +152 -0
- nuitka/build/inline_copy/colorama/colorama/winterm.py +169 -0
- nuitka/build/inline_copy/glob2/LICENSE +27 -0
- nuitka/build/inline_copy/glob2/glob2/__init__.py +5 -0
- nuitka/build/inline_copy/glob2/glob2/compat.py +167 -0
- nuitka/build/inline_copy/glob2/glob2/fnmatch.py +141 -0
- nuitka/build/inline_copy/glob2/glob2/impl.py +216 -0
- nuitka/build/inline_copy/jinja2/LICENSE.rst +28 -0
- nuitka/build/inline_copy/jinja2/README.rst +2 -0
- nuitka/build/inline_copy/jinja2/jinja2/__init__.py +72 -0
- nuitka/build/inline_copy/jinja2/jinja2/_compat.py +105 -0
- nuitka/build/inline_copy/jinja2/jinja2/_identifier.py +2 -0
- nuitka/build/inline_copy/jinja2/jinja2/bccache.py +361 -0
- nuitka/build/inline_copy/jinja2/jinja2/compiler.py +1721 -0
- nuitka/build/inline_copy/jinja2/jinja2/constants.py +32 -0
- nuitka/build/inline_copy/jinja2/jinja2/debug.py +378 -0
- nuitka/build/inline_copy/jinja2/jinja2/defaults.py +56 -0
- nuitka/build/inline_copy/jinja2/jinja2/environment.py +1276 -0
- nuitka/build/inline_copy/jinja2/jinja2/exceptions.py +146 -0
- nuitka/build/inline_copy/jinja2/jinja2/ext.py +627 -0
- nuitka/build/inline_copy/jinja2/jinja2/filters.py +1190 -0
- nuitka/build/inline_copy/jinja2/jinja2/idtracking.py +286 -0
- nuitka/build/inline_copy/jinja2/jinja2/lexer.py +739 -0
- nuitka/build/inline_copy/jinja2/jinja2/loaders.py +483 -0
- nuitka/build/inline_copy/jinja2/jinja2/meta.py +106 -0
- nuitka/build/inline_copy/jinja2/jinja2/nativetypes.py +220 -0
- nuitka/build/inline_copy/jinja2/jinja2/nodes.py +999 -0
- nuitka/build/inline_copy/jinja2/jinja2/optimizer.py +49 -0
- nuitka/build/inline_copy/jinja2/jinja2/parser.py +903 -0
- nuitka/build/inline_copy/jinja2/jinja2/runtime.py +808 -0
- nuitka/build/inline_copy/jinja2/jinja2/sandbox.py +488 -0
- nuitka/build/inline_copy/jinja2/jinja2/tests.py +174 -0
- nuitka/build/inline_copy/jinja2/jinja2/utils.py +642 -0
- nuitka/build/inline_copy/jinja2/jinja2/visitor.py +87 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Action.py +1475 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Builder.py +905 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/CacheDir.py +314 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Conftest.py +805 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Debug.py +251 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Defaults.py +646 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Environment.py +2561 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/EnvironmentValues.py +119 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Errors.py +222 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Executor.py +660 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Job.py +439 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Memoize.py +242 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Node/Alias.py +176 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Node/FS.py +3861 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Node/Python.py +195 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Node/__init__.py +1784 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/PathList.py +224 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/__init__.py +341 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/aix.py +81 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/cygwin.py +61 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/darwin.py +70 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/hpux.py +45 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/irix.py +41 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/mingw.py +33 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/os2.py +55 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/posix.py +124 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/sunos.py +47 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/virtualenv.py +115 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Platform/win32.py +429 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/SConf.py +1119 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/SConsign.py +453 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Scanner/C.py +226 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Scanner/Dir.py +131 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Scanner/Prog.py +114 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Scanner/RC.py +57 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Scanner/__init__.py +436 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Script/Interactive.py +372 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Script/Main.py +1469 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Script/SConsOptions.py +1071 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Script/SConscript.py +686 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Script/__init__.py +425 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Subst.py +979 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Taskmaster.py +1062 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/386asm.py +61 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/GettextCommon.py +429 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/MSCommon/__init__.py +52 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/MSCommon/arch.py +66 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/MSCommon/common.py +371 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/MSCommon/netframework.py +83 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/MSCommon/sdk.py +411 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/MSCommon/vc.py +994 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/MSCommon/vs.py +608 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/PharLapCommon.py +116 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/__init__.py +882 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/aixc++.py +43 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/aixcc.py +74 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/aixcxx.py +77 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/aixlink.py +78 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/applelink.py +209 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/ar.py +63 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/as.py +49 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/asm.py +78 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/bcc32.py +81 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/c++.py +44 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/cc.py +105 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/clang.py +91 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/clangCommon/__init__.py +18 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/clangxx.py +99 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/cxx.py +95 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/cyglink.py +212 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/default.py +50 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/filesystem.py +98 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/g++.py +45 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/gas.py +56 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/gcc.py +110 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/gettext_tool.py +69 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/gnulink.py +70 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/gxx.py +78 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/hpc++.py +45 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/hpcc.py +53 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/hpcxx.py +88 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/hplink.py +72 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/icc.py +59 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/icl.py +52 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/ilink.py +55 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/ilink32.py +60 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/install.py +510 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/intelc.py +617 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/link.py +72 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/linkCommon/LoadableModule.py +131 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/linkCommon/SharedLibrary.py +218 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/linkCommon/__init__.py +171 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/linkloc.py +112 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/m4.py +63 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/masm.py +77 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/mingw.py +232 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/msgfmt.py +132 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/msginit.py +137 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/msgmerge.py +125 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/mslib.py +73 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/mslink.py +339 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/mssdk.py +50 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/msvc.py +325 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/msvs.py +2116 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/mwcc.py +207 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/mwld.py +108 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/nasm.py +72 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/rmic.py +139 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/rpcgen.py +70 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/sgiar.py +68 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/sgic++.py +43 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/sgicc.py +53 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/sgicxx.py +61 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/sgilink.py +59 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/sunar.py +64 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/sunc++.py +45 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/suncc.py +58 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/suncxx.py +153 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/sunlink.py +79 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/tar.py +73 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/textfile.py +198 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/tlib.py +53 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/wix.py +104 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/xgettext.py +337 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Tool/zip.py +120 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Util.py +2134 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Utilities/ConfigureCache.py +171 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Utilities/__init__.py +0 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Utilities/sconsign.py +494 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Variables/BoolVariable.py +96 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Variables/EnumVariable.py +110 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Variables/ListVariable.py +152 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Variables/PackageVariable.py +107 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Variables/PathVariable.py +158 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Variables/__init__.py +334 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/Warnings.py +238 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/__init__.py +9 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/compat/__init__.py +104 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/compat/_scons_dbm.py +42 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/compat/win32.py +101 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/cpp.py +640 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/dblite.py +295 -0
- nuitka/build/inline_copy/lib/scons-4.3.0/SCons/exitfuncs.py +59 -0
- nuitka/build/inline_copy/markupsafe/LICENSE.rst +28 -0
- nuitka/build/inline_copy/markupsafe/markupsafe/__init__.py +327 -0
- nuitka/build/inline_copy/markupsafe/markupsafe/_compat.py +33 -0
- nuitka/build/inline_copy/markupsafe/markupsafe/_constants.py +264 -0
- nuitka/build/inline_copy/markupsafe/markupsafe/_native.py +69 -0
- nuitka/build/inline_copy/pefile/LICENSE.txt +21 -0
- nuitka/build/inline_copy/pefile/ordlookup/__init__.py +41 -0
- nuitka/build/inline_copy/pefile/ordlookup/oleaut32.py +400 -0
- nuitka/build/inline_copy/pefile/ordlookup/ws2_32.py +120 -0
- nuitka/build/inline_copy/pefile/pefile.py +8034 -0
- nuitka/build/inline_copy/pkg_resources/pkg_resources/__init__.py +3272 -0
- nuitka/build/inline_copy/pkg_resources/pkg_resources/py31compat.py +21 -0
- nuitka/build/inline_copy/python_hacl/LICENSE.txt +201 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/Hacl_Hash_MD5.c +1430 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/Hacl_Hash_MD5.h +66 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/Hacl_Hash_SHA1.c +463 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/Hacl_Hash_SHA1.h +66 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/Hacl_Hash_SHA2.c +1273 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/Hacl_Hash_SHA2.h +204 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/Hacl_Hash_SHA3.c +734 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/Hacl_Hash_SHA3.h +131 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/Hacl_Streaming_Types.h +83 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/include/krml/FStar_UInt128_Verified.h +346 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/include/krml/FStar_UInt_8_16_32_64.h +107 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/include/krml/fstar_uint128_struct_endianness.h +68 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/include/krml/internal/target.h +293 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/include/krml/lowstar_endianness.h +231 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/include/krml/types.h +14 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/internal/Hacl_Hash_MD5.h +56 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/internal/Hacl_Hash_SHA1.h +56 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/internal/Hacl_Hash_SHA2.h +164 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/internal/Hacl_Hash_SHA3.h +65 -0
- nuitka/build/inline_copy/python_hacl/hacl_312/python_hacl_namespaces.h +89 -0
- nuitka/build/inline_copy/stubgen/astunparse.py +938 -0
- nuitka/build/inline_copy/stubgen/six.py +998 -0
- nuitka/build/inline_copy/stubgen/stubgen.py +484 -0
- nuitka/build/inline_copy/tqdm/tqdm/__init__.py +40 -0
- nuitka/build/inline_copy/tqdm/tqdm/_main.py +9 -0
- nuitka/build/inline_copy/tqdm/tqdm/_monitor.py +97 -0
- nuitka/build/inline_copy/tqdm/tqdm/_tqdm.py +9 -0
- nuitka/build/inline_copy/tqdm/tqdm/_tqdm_notebook.py +9 -0
- nuitka/build/inline_copy/tqdm/tqdm/_tqdm_pandas.py +24 -0
- nuitka/build/inline_copy/tqdm/tqdm/_utils.py +12 -0
- nuitka/build/inline_copy/tqdm/tqdm/auto.py +44 -0
- nuitka/build/inline_copy/tqdm/tqdm/autonotebook.py +28 -0
- nuitka/build/inline_copy/tqdm/tqdm/dask.py +46 -0
- nuitka/build/inline_copy/tqdm/tqdm/notebook.py +316 -0
- nuitka/build/inline_copy/tqdm/tqdm/std.py +1524 -0
- nuitka/build/inline_copy/tqdm/tqdm/tk.py +207 -0
- nuitka/build/inline_copy/tqdm/tqdm/utils.py +351 -0
- nuitka/build/inline_copy/tqdm/tqdm/version.py +2 -0
- nuitka/build/inline_copy/yaml/LICENSE +20 -0
- nuitka/build/inline_copy/yaml/yaml/__init__.py +427 -0
- nuitka/build/inline_copy/yaml/yaml/composer.py +139 -0
- nuitka/build/inline_copy/yaml/yaml/constructor.py +748 -0
- nuitka/build/inline_copy/yaml/yaml/cyaml.py +101 -0
- nuitka/build/inline_copy/yaml/yaml/dumper.py +62 -0
- nuitka/build/inline_copy/yaml/yaml/emitter.py +1137 -0
- nuitka/build/inline_copy/yaml/yaml/error.py +75 -0
- nuitka/build/inline_copy/yaml/yaml/events.py +86 -0
- nuitka/build/inline_copy/yaml/yaml/loader.py +63 -0
- nuitka/build/inline_copy/yaml/yaml/nodes.py +49 -0
- nuitka/build/inline_copy/yaml/yaml/parser.py +589 -0
- nuitka/build/inline_copy/yaml/yaml/reader.py +185 -0
- nuitka/build/inline_copy/yaml/yaml/representer.py +389 -0
- nuitka/build/inline_copy/yaml/yaml/resolver.py +227 -0
- nuitka/build/inline_copy/yaml/yaml/scanner.py +1435 -0
- nuitka/build/inline_copy/yaml/yaml/serializer.py +111 -0
- nuitka/build/inline_copy/yaml/yaml/tokens.py +104 -0
- nuitka/build/inline_copy/zlib/LICENSE +22 -0
- nuitka/build/inline_copy/zlib/crc32.c +1049 -0
- nuitka/build/inline_copy/zlib/crc32.h +9446 -0
- nuitka/build/inline_copy/zlib/zconf.h +551 -0
- nuitka/build/inline_copy/zlib/zlib.h +1938 -0
- nuitka/build/inline_copy/zlib/zutil.h +275 -0
- nuitka/build/inline_copy/zstd/LICENSE.txt +30 -0
- nuitka/build/inline_copy/zstd/common/bitstream.h +463 -0
- nuitka/build/inline_copy/zstd/common/compiler.h +288 -0
- nuitka/build/inline_copy/zstd/common/cpu.h +213 -0
- nuitka/build/inline_copy/zstd/common/debug.h +107 -0
- nuitka/build/inline_copy/zstd/common/entropy_common.c +360 -0
- nuitka/build/inline_copy/zstd/common/error_private.c +56 -0
- nuitka/build/inline_copy/zstd/common/error_private.h +80 -0
- nuitka/build/inline_copy/zstd/common/fse.h +715 -0
- nuitka/build/inline_copy/zstd/common/fse_decompress.c +393 -0
- nuitka/build/inline_copy/zstd/common/huf.h +361 -0
- nuitka/build/inline_copy/zstd/common/mem.h +426 -0
- nuitka/build/inline_copy/zstd/common/xxhash.c +826 -0
- nuitka/build/inline_copy/zstd/common/xxhash.h +285 -0
- nuitka/build/inline_copy/zstd/common/zstd_common.c +83 -0
- nuitka/build/inline_copy/zstd/common/zstd_deps.h +111 -0
- nuitka/build/inline_copy/zstd/common/zstd_errors.h +95 -0
- nuitka/build/inline_copy/zstd/common/zstd_internal.h +478 -0
- nuitka/build/inline_copy/zstd/decompress/huf_decompress.c +1350 -0
- nuitka/build/inline_copy/zstd/decompress/zstd_ddict.c +244 -0
- nuitka/build/inline_copy/zstd/decompress/zstd_ddict.h +44 -0
- nuitka/build/inline_copy/zstd/decompress/zstd_decompress.c +1930 -0
- nuitka/build/inline_copy/zstd/decompress/zstd_decompress_block.c +1540 -0
- nuitka/build/inline_copy/zstd/decompress/zstd_decompress_block.h +62 -0
- nuitka/build/inline_copy/zstd/decompress/zstd_decompress_internal.h +190 -0
- nuitka/build/inline_copy/zstd/zstd.h +2391 -0
- nuitka/build/static_src/CompiledAsyncgenType.c +2211 -0
- nuitka/build/static_src/CompiledCellType.c +300 -0
- nuitka/build/static_src/CompiledCodeHelpers.c +2160 -0
- nuitka/build/static_src/CompiledCoroutineType.c +1946 -0
- nuitka/build/static_src/CompiledFrameType.c +1337 -0
- nuitka/build/static_src/CompiledFunctionType.c +3320 -0
- nuitka/build/static_src/CompiledGeneratorType.c +1997 -0
- nuitka/build/static_src/CompiledGeneratorTypeUncompiledIntegration.c +2117 -0
- nuitka/build/static_src/CompiledMethodType.c +614 -0
- nuitka/build/static_src/GenerateHeadersMain.c +30 -0
- nuitka/build/static_src/HelpersAllocator.c +939 -0
- nuitka/build/static_src/HelpersAttributes.c +1241 -0
- nuitka/build/static_src/HelpersBuiltin.c +901 -0
- nuitka/build/static_src/HelpersBuiltinTypeMethods.c +3594 -0
- nuitka/build/static_src/HelpersBytes.c +107 -0
- nuitka/build/static_src/HelpersCalling.c +397 -0
- nuitka/build/static_src/HelpersCallingGenerated.c +14361 -0
- nuitka/build/static_src/HelpersChecksumTools.c +59 -0
- nuitka/build/static_src/HelpersClasses.c +91 -0
- nuitka/build/static_src/HelpersComparisonDualEq.c +183 -0
- nuitka/build/static_src/HelpersComparisonDualGe.c +121 -0
- nuitka/build/static_src/HelpersComparisonDualGt.c +121 -0
- nuitka/build/static_src/HelpersComparisonDualLe.c +183 -0
- nuitka/build/static_src/HelpersComparisonDualLt.c +183 -0
- nuitka/build/static_src/HelpersComparisonDualNe.c +121 -0
- nuitka/build/static_src/HelpersComparisonEq.c +12070 -0
- nuitka/build/static_src/HelpersComparisonEqUtils.c +169 -0
- nuitka/build/static_src/HelpersComparisonGe.c +11871 -0
- nuitka/build/static_src/HelpersComparisonGt.c +11855 -0
- nuitka/build/static_src/HelpersComparisonLe.c +11957 -0
- nuitka/build/static_src/HelpersComparisonLt.c +11941 -0
- nuitka/build/static_src/HelpersComparisonNe.c +11979 -0
- nuitka/build/static_src/HelpersConsole.c +124 -0
- nuitka/build/static_src/HelpersConstantsBlob.c +1487 -0
- nuitka/build/static_src/HelpersDeepcopy.c +636 -0
- nuitka/build/static_src/HelpersDictionaries.c +1739 -0
- nuitka/build/static_src/HelpersDictionariesGenerated.c +738 -0
- nuitka/build/static_src/HelpersDumpBacktraces.c +63 -0
- nuitka/build/static_src/HelpersEnvironmentVariables.c +65 -0
- nuitka/build/static_src/HelpersEnvironmentVariablesSystem.c +97 -0
- nuitka/build/static_src/HelpersExceptions.c +298 -0
- nuitka/build/static_src/HelpersFiles.c +353 -0
- nuitka/build/static_src/HelpersFilesystemPaths.c +1322 -0
- nuitka/build/static_src/HelpersFloats.c +92 -0
- nuitka/build/static_src/HelpersHeapStorage.c +68 -0
- nuitka/build/static_src/HelpersImport.c +506 -0
- nuitka/build/static_src/HelpersImportHard.c +526 -0
- nuitka/build/static_src/HelpersJitSources.c +48 -0
- nuitka/build/static_src/HelpersLists.c +899 -0
- nuitka/build/static_src/HelpersListsGenerated.c +564 -0
- nuitka/build/static_src/HelpersMappings.c +46 -0
- nuitka/build/static_src/HelpersMatching.c +192 -0
- nuitka/build/static_src/HelpersOperationBinaryAdd.c +6477 -0
- nuitka/build/static_src/HelpersOperationBinaryAddUtils.c +703 -0
- nuitka/build/static_src/HelpersOperationBinaryBitand.c +2738 -0
- nuitka/build/static_src/HelpersOperationBinaryBitor.c +2738 -0
- nuitka/build/static_src/HelpersOperationBinaryBitxor.c +2738 -0
- nuitka/build/static_src/HelpersOperationBinaryDivmod.c +2406 -0
- nuitka/build/static_src/HelpersOperationBinaryDivmodUtils.c +33 -0
- nuitka/build/static_src/HelpersOperationBinaryDualAdd.c +172 -0
- nuitka/build/static_src/HelpersOperationBinaryFloordiv.c +2422 -0
- nuitka/build/static_src/HelpersOperationBinaryInplaceAdd.c +220 -0
- nuitka/build/static_src/HelpersOperationBinaryLshift.c +2846 -0
- nuitka/build/static_src/HelpersOperationBinaryMatmult.c +453 -0
- nuitka/build/static_src/HelpersOperationBinaryMod.c +6549 -0
- nuitka/build/static_src/HelpersOperationBinaryMult.c +6438 -0
- nuitka/build/static_src/HelpersOperationBinaryMultUtils.c +125 -0
- nuitka/build/static_src/HelpersOperationBinaryOlddiv.c +2355 -0
- nuitka/build/static_src/HelpersOperationBinaryPow.c +2743 -0
- nuitka/build/static_src/HelpersOperationBinaryPowUtils.c +26 -0
- nuitka/build/static_src/HelpersOperationBinaryRshift.c +2706 -0
- nuitka/build/static_src/HelpersOperationBinarySub.c +2649 -0
- nuitka/build/static_src/HelpersOperationBinaryTruediv.c +2415 -0
- nuitka/build/static_src/HelpersOperationInplaceAdd.c +5211 -0
- nuitka/build/static_src/HelpersOperationInplaceAddUtils.c +144 -0
- nuitka/build/static_src/HelpersOperationInplaceBitand.c +1826 -0
- nuitka/build/static_src/HelpersOperationInplaceBitor.c +1826 -0
- nuitka/build/static_src/HelpersOperationInplaceBitxor.c +1826 -0
- nuitka/build/static_src/HelpersOperationInplaceFloordiv.c +2605 -0
- nuitka/build/static_src/HelpersOperationInplaceLshift.c +1594 -0
- nuitka/build/static_src/HelpersOperationInplaceMatmult.c +603 -0
- nuitka/build/static_src/HelpersOperationInplaceMod.c +4762 -0
- nuitka/build/static_src/HelpersOperationInplaceMult.c +4689 -0
- nuitka/build/static_src/HelpersOperationInplaceOlddiv.c +2553 -0
- nuitka/build/static_src/HelpersOperationInplacePow.c +2807 -0
- nuitka/build/static_src/HelpersOperationInplaceRshift.c +1534 -0
- nuitka/build/static_src/HelpersOperationInplaceSub.c +2894 -0
- nuitka/build/static_src/HelpersOperationInplaceTruediv.c +2612 -0
- nuitka/build/static_src/HelpersProfiling.c +104 -0
- nuitka/build/static_src/HelpersPythonPgo.c +113 -0
- nuitka/build/static_src/HelpersRaising.c +447 -0
- nuitka/build/static_src/HelpersSafeStrings.c +185 -0
- nuitka/build/static_src/HelpersSequences.c +134 -0
- nuitka/build/static_src/HelpersSlices.c +73 -0
- nuitka/build/static_src/HelpersStrings.c +998 -0
- nuitka/build/static_src/HelpersTuples.c +148 -0
- nuitka/build/static_src/HelpersTypes.c +329 -0
- nuitka/build/static_src/InspectPatcher.c +439 -0
- nuitka/build/static_src/MainProgram.c +2060 -0
- nuitka/build/static_src/MetaPathBasedLoader.c +2290 -0
- nuitka/build/static_src/MetaPathBasedLoaderImportlibMetadataDistribution.c +125 -0
- nuitka/build/static_src/MetaPathBasedLoaderResourceReader.c +158 -0
- nuitka/build/static_src/MetaPathBasedLoaderResourceReaderFiles.c +785 -0
- nuitka/build/static_src/OnefileBootstrap.c +1580 -0
- nuitka/build/static_src/OnefileSplashScreen.cpp +275 -0
- nuitka/code_generation/AsyncgenCodes.py +186 -0
- nuitka/code_generation/AttributeCodes.py +357 -0
- nuitka/code_generation/BinaryOperationHelperDefinitions.py +720 -0
- nuitka/code_generation/BranchCodes.py +67 -0
- nuitka/code_generation/BuiltinCodes.py +529 -0
- nuitka/code_generation/CallCodes.py +1186 -0
- nuitka/code_generation/ClassCodes.py +156 -0
- nuitka/code_generation/CodeGeneration.py +1078 -0
- nuitka/code_generation/CodeHelperSelection.py +81 -0
- nuitka/code_generation/CodeHelpers.py +455 -0
- nuitka/code_generation/CodeObjectCodes.py +165 -0
- nuitka/code_generation/ComparisonCodes.py +569 -0
- nuitka/code_generation/ComparisonHelperDefinitions.py +146 -0
- nuitka/code_generation/ConditionalCodes.py +236 -0
- nuitka/code_generation/ConstantCodes.py +243 -0
- nuitka/code_generation/Contexts.py +1248 -0
- nuitka/code_generation/CoroutineCodes.py +253 -0
- nuitka/code_generation/CtypesCodes.py +46 -0
- nuitka/code_generation/DictCodes.py +918 -0
- nuitka/code_generation/Emission.py +75 -0
- nuitka/code_generation/ErrorCodes.py +281 -0
- nuitka/code_generation/EvalCodes.py +444 -0
- nuitka/code_generation/ExceptionCodes.py +337 -0
- nuitka/code_generation/ExpressionCTypeSelectionHelpers.py +227 -0
- nuitka/code_generation/ExpressionCodes.py +61 -0
- nuitka/code_generation/FrameCodes.py +518 -0
- nuitka/code_generation/FunctionCodes.py +858 -0
- nuitka/code_generation/GeneratorCodes.py +218 -0
- nuitka/code_generation/GlobalConstants.py +249 -0
- nuitka/code_generation/GlobalsLocalsCodes.py +211 -0
- nuitka/code_generation/IdCodes.py +53 -0
- nuitka/code_generation/ImportCodes.py +468 -0
- nuitka/code_generation/Indentation.py +45 -0
- nuitka/code_generation/IndexCodes.py +50 -0
- nuitka/code_generation/InjectCCodes.py +28 -0
- nuitka/code_generation/IntegerCodes.py +110 -0
- nuitka/code_generation/IteratorCodes.py +378 -0
- nuitka/code_generation/JitCodes.py +44 -0
- nuitka/code_generation/LabelCodes.py +68 -0
- nuitka/code_generation/LineNumberCodes.py +91 -0
- nuitka/code_generation/ListCodes.py +502 -0
- nuitka/code_generation/LoaderCodes.py +193 -0
- nuitka/code_generation/LocalsDictCodes.py +359 -0
- nuitka/code_generation/LoopCodes.py +88 -0
- nuitka/code_generation/MatchCodes.py +67 -0
- nuitka/code_generation/ModuleCodes.py +247 -0
- nuitka/code_generation/Namify.py +260 -0
- nuitka/code_generation/NetworkxCodes.py +51 -0
- nuitka/code_generation/OperationCodes.py +398 -0
- nuitka/code_generation/PackageResourceCodes.py +986 -0
- nuitka/code_generation/PrintCodes.py +93 -0
- nuitka/code_generation/PythonAPICodes.py +215 -0
- nuitka/code_generation/RaisingCodes.py +481 -0
- nuitka/code_generation/Reports.py +115 -0
- nuitka/code_generation/ReturnCodes.py +143 -0
- nuitka/code_generation/SetCodes.py +196 -0
- nuitka/code_generation/SliceCodes.py +465 -0
- nuitka/code_generation/StringCodes.py +303 -0
- nuitka/code_generation/SubscriptCodes.py +263 -0
- nuitka/code_generation/TensorflowCodes.py +54 -0
- nuitka/code_generation/TryCodes.py +326 -0
- nuitka/code_generation/TupleCodes.py +115 -0
- nuitka/code_generation/TypeAliasCodes.py +120 -0
- nuitka/code_generation/VariableCodes.py +519 -0
- nuitka/code_generation/VariableDeclarations.py +279 -0
- nuitka/code_generation/YieldCodes.py +253 -0
- nuitka/code_generation/__init__.py +19 -0
- nuitka/code_generation/c_types/CTypeBases.py +177 -0
- nuitka/code_generation/c_types/CTypeBooleans.py +104 -0
- nuitka/code_generation/c_types/CTypeCFloats.py +57 -0
- nuitka/code_generation/c_types/CTypeCLongs.py +45 -0
- nuitka/code_generation/c_types/CTypeModuleDictVariables.py +109 -0
- nuitka/code_generation/c_types/CTypeNuitkaBooleans.py +150 -0
- nuitka/code_generation/c_types/CTypeNuitkaInts.py +200 -0
- nuitka/code_generation/c_types/CTypeNuitkaVoids.py +107 -0
- nuitka/code_generation/c_types/CTypePyObjectPointers.py +572 -0
- nuitka/code_generation/c_types/CTypeVoids.py +92 -0
- nuitka/code_generation/c_types/__init__.py +19 -0
- nuitka/code_generation/templates/CodeTemplatesAsyncgens.py +106 -0
- nuitka/code_generation/templates/CodeTemplatesConstants.py +296 -0
- nuitka/code_generation/templates/CodeTemplatesCoroutines.py +109 -0
- nuitka/code_generation/templates/CodeTemplatesExceptions.py +84 -0
- nuitka/code_generation/templates/CodeTemplatesFrames.py +235 -0
- nuitka/code_generation/templates/CodeTemplatesFunction.py +117 -0
- nuitka/code_generation/templates/CodeTemplatesGeneratorFunction.py +130 -0
- nuitka/code_generation/templates/CodeTemplatesIterators.py +40 -0
- nuitka/code_generation/templates/CodeTemplatesLoader.py +180 -0
- nuitka/code_generation/templates/CodeTemplatesModules.py +710 -0
- nuitka/code_generation/templates/CodeTemplatesVariables.py +388 -0
- nuitka/code_generation/templates/TemplateDebugWrapper.py +80 -0
- nuitka/code_generation/templates/__init__.py +19 -0
- nuitka/code_generation/templates_c/CodeTemplateCallsMethodPositional.c.j2 +321 -0
- nuitka/code_generation/templates_c/CodeTemplateCallsMixed.c.j2 +143 -0
- nuitka/code_generation/templates_c/CodeTemplateCallsPositional.c.j2 +677 -0
- nuitka/code_generation/templates_c/CodeTemplateCallsPositionalMethodDescr.c.j2 +165 -0
- nuitka/code_generation/templates_c/CodeTemplateMakeListHinted.c.j2 +38 -0
- nuitka/code_generation/templates_c/CodeTemplateMakeListSmall.c.j2 +41 -0
- nuitka/code_generation/templates_c/HelperBuiltinMethodOperation.c.j2 +53 -0
- nuitka/code_generation/templates_c/HelperDictionaryCopy.c.j2 +364 -0
- nuitka/code_generation/templates_c/HelperImportHard.c.j2 +37 -0
- nuitka/code_generation/templates_c/HelperLongTools.c.j2 +53 -0
- nuitka/code_generation/templates_c/HelperObjectTools.c.j2 +20 -0
- nuitka/code_generation/templates_c/HelperOperationBinary.c.j2 +148 -0
- nuitka/code_generation/templates_c/HelperOperationBinaryDual.c.j2 +115 -0
- nuitka/code_generation/templates_c/HelperOperationComparison.c.j2 +352 -0
- nuitka/code_generation/templates_c/HelperOperationComparisonBytes.c.j2 +115 -0
- nuitka/code_generation/templates_c/HelperOperationComparisonDual.c.j2 +86 -0
- nuitka/code_generation/templates_c/HelperOperationComparisonFloat.c.j2 +31 -0
- nuitka/code_generation/templates_c/HelperOperationComparisonInt.c.j2 +32 -0
- nuitka/code_generation/templates_c/HelperOperationComparisonList.c.j2 +112 -0
- nuitka/code_generation/templates_c/HelperOperationComparisonLong.c.j2 +157 -0
- nuitka/code_generation/templates_c/HelperOperationComparisonStr.c.j2 +115 -0
- nuitka/code_generation/templates_c/HelperOperationComparisonTuple.c.j2 +99 -0
- nuitka/code_generation/templates_c/HelperOperationComparisonUnicode.c.j2 +115 -0
- nuitka/code_generation/templates_c/HelperOperationInplace.c.j2 +281 -0
- nuitka/code_generation/templates_c/HelperSlotsBinary.c.j2 +420 -0
- nuitka/code_generation/templates_c/HelperSlotsBytes.c.j2 +51 -0
- nuitka/code_generation/templates_c/HelperSlotsCommon.c.j2 +71 -0
- nuitka/code_generation/templates_c/HelperSlotsFloat.c.j2 +327 -0
- nuitka/code_generation/templates_c/HelperSlotsInt.c.j2 +411 -0
- nuitka/code_generation/templates_c/HelperSlotsList.c.j2 +59 -0
- nuitka/code_generation/templates_c/HelperSlotsLong.c.j2 +229 -0
- nuitka/code_generation/templates_c/HelperSlotsSet.c.j2 +47 -0
- nuitka/code_generation/templates_c/HelperSlotsStr.c.j2 +55 -0
- nuitka/code_generation/templates_c/HelperSlotsTuple.c.j2 +58 -0
- nuitka/code_generation/templates_c/HelperSlotsUnicode.c.j2 +62 -0
- nuitka/containers/Namedtuples.py +51 -0
- nuitka/containers/OrderedDicts.py +191 -0
- nuitka/containers/OrderedSets.py +123 -0
- nuitka/containers/OrderedSetsFallback.py +139 -0
- nuitka/containers/__init__.py +19 -0
- nuitka/distutils/Build.py +76 -0
- nuitka/distutils/DistutilCommands.py +438 -0
- nuitka/distutils/__init__.py +19 -0
- nuitka/finalizations/Finalization.py +35 -0
- nuitka/finalizations/FinalizeMarkups.py +136 -0
- nuitka/finalizations/__init__.py +19 -0
- nuitka/freezer/DependsExe.py +257 -0
- nuitka/freezer/DllDependenciesCommon.py +97 -0
- nuitka/freezer/DllDependenciesMacOS.py +444 -0
- nuitka/freezer/DllDependenciesPosix.py +242 -0
- nuitka/freezer/DllDependenciesWin32.py +315 -0
- nuitka/freezer/ImportDetection.py +359 -0
- nuitka/freezer/IncludedDataFiles.py +689 -0
- nuitka/freezer/IncludedEntryPoints.py +376 -0
- nuitka/freezer/Onefile.py +296 -0
- nuitka/freezer/Standalone.py +520 -0
- nuitka/freezer/__init__.py +19 -0
- nuitka/importing/IgnoreListing.py +449 -0
- nuitka/importing/ImportCache.py +95 -0
- nuitka/importing/ImportResolving.py +186 -0
- nuitka/importing/Importing.py +1200 -0
- nuitka/importing/PreloadedPackages.py +164 -0
- nuitka/importing/Recursion.py +611 -0
- nuitka/importing/StandardLibrary.py +429 -0
- nuitka/importing/__init__.py +19 -0
- nuitka/nodes/AsyncgenNodes.py +107 -0
- nuitka/nodes/AttributeLookupNodes.py +124 -0
- nuitka/nodes/AttributeNodes.py +386 -0
- nuitka/nodes/AttributeNodesGenerated.py +10734 -0
- nuitka/nodes/BuiltinAllNodes.py +115 -0
- nuitka/nodes/BuiltinAnyNodes.py +124 -0
- nuitka/nodes/BuiltinComplexNodes.py +83 -0
- nuitka/nodes/BuiltinDecodingNodes.py +52 -0
- nuitka/nodes/BuiltinDecoratorNodes.py +85 -0
- nuitka/nodes/BuiltinDictNodes.py +140 -0
- nuitka/nodes/BuiltinFormatNodes.py +159 -0
- nuitka/nodes/BuiltinHashNodes.py +63 -0
- nuitka/nodes/BuiltinInputNodes.py +39 -0
- nuitka/nodes/BuiltinIntegerNodes.py +170 -0
- nuitka/nodes/BuiltinIteratorNodes.py +391 -0
- nuitka/nodes/BuiltinLenNodes.py +61 -0
- nuitka/nodes/BuiltinNextNodes.py +111 -0
- nuitka/nodes/BuiltinOpenNodes.py +148 -0
- nuitka/nodes/BuiltinOperationNodeBasesGenerated.py +7367 -0
- nuitka/nodes/BuiltinRangeNodes.py +690 -0
- nuitka/nodes/BuiltinRefNodes.py +314 -0
- nuitka/nodes/BuiltinSumNodes.py +104 -0
- nuitka/nodes/BuiltinTypeNodes.py +454 -0
- nuitka/nodes/BuiltinVarsNodes.py +44 -0
- nuitka/nodes/BytesNodes.py +829 -0
- nuitka/nodes/CallNodes.py +217 -0
- nuitka/nodes/Checkers.py +55 -0
- nuitka/nodes/ChildrenHavingMixins.py +21576 -0
- nuitka/nodes/ClassNodes.py +286 -0
- nuitka/nodes/CodeObjectSpecs.py +230 -0
- nuitka/nodes/ComparisonNodes.py +687 -0
- nuitka/nodes/ConditionalNodes.py +884 -0
- nuitka/nodes/ConstantRefNodes.py +1717 -0
- nuitka/nodes/ContainerMakingNodes.py +408 -0
- nuitka/nodes/ContainerOperationNodes.py +87 -0
- nuitka/nodes/CoroutineNodes.py +144 -0
- nuitka/nodes/CtypesNodes.py +51 -0
- nuitka/nodes/DictionaryNodes.py +1513 -0
- nuitka/nodes/ExceptionNodes.py +393 -0
- nuitka/nodes/ExecEvalNodes.py +229 -0
- nuitka/nodes/ExpressionBases.py +1301 -0
- nuitka/nodes/ExpressionBasesGenerated.py +2103 -0
- nuitka/nodes/ExpressionShapeMixins.py +886 -0
- nuitka/nodes/FrameNodes.py +413 -0
- nuitka/nodes/FunctionAttributeNodes.py +102 -0
- nuitka/nodes/FunctionNodes.py +1303 -0
- nuitka/nodes/FutureSpecs.py +224 -0
- nuitka/nodes/GeneratorNodes.py +201 -0
- nuitka/nodes/GlobalsLocalsNodes.py +209 -0
- nuitka/nodes/HardImportNodesGenerated.py +3599 -0
- nuitka/nodes/ImportHardNodes.py +185 -0
- nuitka/nodes/ImportNodes.py +1366 -0
- nuitka/nodes/IndicatorMixins.py +79 -0
- nuitka/nodes/InjectCNodes.py +51 -0
- nuitka/nodes/IterationHandles.py +407 -0
- nuitka/nodes/KeyValuePairNodes.py +378 -0
- nuitka/nodes/ListOperationNodes.py +525 -0
- nuitka/nodes/LocalsDictNodes.py +717 -0
- nuitka/nodes/LocalsScopes.py +505 -0
- nuitka/nodes/LoopNodes.py +445 -0
- nuitka/nodes/MatchNodes.py +60 -0
- nuitka/nodes/ModuleAttributeNodes.py +180 -0
- nuitka/nodes/ModuleNodes.py +1137 -0
- nuitka/nodes/NetworkxNodes.py +45 -0
- nuitka/nodes/NodeBases.py +890 -0
- nuitka/nodes/NodeMakingHelpers.py +481 -0
- nuitka/nodes/NodeMetaClasses.py +172 -0
- nuitka/nodes/OperatorNodes.py +944 -0
- nuitka/nodes/OperatorNodesUnary.py +403 -0
- nuitka/nodes/OsSysNodes.py +215 -0
- nuitka/nodes/OutlineNodes.py +372 -0
- nuitka/nodes/PackageMetadataNodes.py +982 -0
- nuitka/nodes/PackageResourceNodes.py +424 -0
- nuitka/nodes/PrintNodes.py +105 -0
- nuitka/nodes/ReturnNodes.py +255 -0
- nuitka/nodes/SideEffectNodes.py +139 -0
- nuitka/nodes/SliceNodes.py +386 -0
- nuitka/nodes/StatementBasesGenerated.py +3419 -0
- nuitka/nodes/StatementNodes.py +316 -0
- nuitka/nodes/StrNodes.py +919 -0
- nuitka/nodes/StringConcatenationNodes.py +103 -0
- nuitka/nodes/SubscriptNodes.py +245 -0
- nuitka/nodes/TensorflowNodes.py +38 -0
- nuitka/nodes/TryNodes.py +519 -0
- nuitka/nodes/TypeMatchNodes.py +65 -0
- nuitka/nodes/TypeNodes.py +390 -0
- nuitka/nodes/VariableAssignNodes.py +1177 -0
- nuitka/nodes/VariableDelNodes.py +320 -0
- nuitka/nodes/VariableNameNodes.py +153 -0
- nuitka/nodes/VariableRefNodes.py +895 -0
- nuitka/nodes/VariableReleaseNodes.py +153 -0
- nuitka/nodes/YieldNodes.py +121 -0
- nuitka/nodes/__init__.py +19 -0
- nuitka/nodes/shapes/BuiltinTypeShapes.py +4290 -0
- nuitka/nodes/shapes/ControlFlowDescriptions.py +199 -0
- nuitka/nodes/shapes/IteratorShapes.py +71 -0
- nuitka/nodes/shapes/ShapeMixins.py +255 -0
- nuitka/nodes/shapes/StandardShapes.py +1384 -0
- nuitka/nodes/shapes/__init__.py +19 -0
- nuitka/optimizations/BytecodeDemotion.py +105 -0
- nuitka/optimizations/FunctionInlining.py +110 -0
- nuitka/optimizations/Graphs.py +70 -0
- nuitka/optimizations/Optimization.py +363 -0
- nuitka/optimizations/OptimizeBuiltinCalls.py +1582 -0
- nuitka/optimizations/Tags.py +76 -0
- nuitka/optimizations/TraceCollections.py +1257 -0
- nuitka/optimizations/ValueTraces.py +980 -0
- nuitka/optimizations/__init__.py +19 -0
- nuitka/pgo/PGO.py +160 -0
- nuitka/pgo/__init__.py +19 -0
- nuitka/plugins/PluginBase.py +1924 -0
- nuitka/plugins/Plugins.py +2007 -0
- nuitka/plugins/YamlPluginBase.py +121 -0
- nuitka/plugins/__init__.py +19 -0
- nuitka/plugins/standard/AntiBloatPlugin.py +1024 -0
- nuitka/plugins/standard/ConsiderPyLintAnnotationsPlugin.py +95 -0
- nuitka/plugins/standard/DataFilesPlugin.py +311 -0
- nuitka/plugins/standard/DelvewheelPlugin.py +150 -0
- nuitka/plugins/standard/DillPlugin/DillPlugin.c +37 -0
- nuitka/plugins/standard/DillPlugin/cloudpickle-postLoad.py +67 -0
- nuitka/plugins/standard/DillPlugin/dill-postLoad.py +223 -0
- nuitka/plugins/standard/DillPlugin.py +137 -0
- nuitka/plugins/standard/DllFilesPlugin.py +527 -0
- nuitka/plugins/standard/EnumPlugin.py +64 -0
- nuitka/plugins/standard/EventletPlugin.py +57 -0
- nuitka/plugins/standard/GeventPlugin.py +64 -0
- nuitka/plugins/standard/GiPlugin.py +118 -0
- nuitka/plugins/standard/GlfwPlugin.py +138 -0
- nuitka/plugins/standard/ImplicitImports.py +845 -0
- nuitka/plugins/standard/KivyPlugin.py +141 -0
- nuitka/plugins/standard/MatplotlibPlugin.py +256 -0
- nuitka/plugins/standard/MultiprocessingPlugin.py +199 -0
- nuitka/plugins/standard/NumpyPlugin.py +35 -0
- nuitka/plugins/standard/OptionsNannyPlugin.py +158 -0
- nuitka/plugins/standard/PbrPlugin.py +62 -0
- nuitka/plugins/standard/PkgResourcesPlugin.py +162 -0
- nuitka/plugins/standard/PlaywrightPlugin.py +179 -0
- nuitka/plugins/standard/PmwPlugin.py +248 -0
- nuitka/plugins/standard/PySidePyQtPlugin.py +1666 -0
- nuitka/plugins/standard/PywebViewPlugin.py +81 -0
- nuitka/plugins/standard/SpacyPlugin.py +137 -0
- nuitka/plugins/standard/TensorflowPlugin.py +35 -0
- nuitka/plugins/standard/TkinterPlugin.py +416 -0
- nuitka/plugins/standard/TorchPlugin.py +35 -0
- nuitka/plugins/standard/TransformersPlugin.py +121 -0
- nuitka/plugins/standard/TrioPlugin.py +33 -0
- nuitka/plugins/standard/UpxPlugin.py +174 -0
- nuitka/plugins/standard/__init__.py +19 -0
- nuitka/plugins/standard/standard.nuitka-package.config.yml +9313 -0
- nuitka/plugins/standard/stdlib2.nuitka-package.config.yml +78 -0
- nuitka/plugins/standard/stdlib3.nuitka-package.config.yml +468 -0
- nuitka/reports/CompilationReportReader.py +83 -0
- nuitka/reports/LicenseReport.rst.j2 +41 -0
- nuitka/reports/Reports.py +961 -0
- nuitka/reports/__init__.py +19 -0
- nuitka/specs/BuiltinBytesOperationSpecs.py +180 -0
- nuitka/specs/BuiltinDictOperationSpecs.py +82 -0
- nuitka/specs/BuiltinListOperationSpecs.py +80 -0
- nuitka/specs/BuiltinParameterSpecs.py +831 -0
- nuitka/specs/BuiltinStrOperationSpecs.py +181 -0
- nuitka/specs/BuiltinTypeOperationSpecs.py +34 -0
- nuitka/specs/BuiltinUnicodeOperationSpecs.py +123 -0
- nuitka/specs/HardImportSpecs.py +236 -0
- nuitka/specs/ParameterSpecs.py +630 -0
- nuitka/specs/__init__.py +19 -0
- nuitka/tools/Basics.py +55 -0
- nuitka/tools/__init__.py +19 -0
- nuitka/tools/commercial/__init__.py +21 -0
- nuitka/tools/data_composer/DataComposer.py +593 -0
- nuitka/tools/data_composer/__init__.py +19 -0
- nuitka/tools/data_composer/__main__.py +41 -0
- nuitka/tools/environments/CreateEnvironment.py +69 -0
- nuitka/tools/environments/Virtualenv.py +158 -0
- nuitka/tools/environments/__init__.py +19 -0
- nuitka/tools/general/__init__.py +19 -0
- nuitka/tools/general/dll_report/__init__.py +19 -0
- nuitka/tools/general/dll_report/__main__.py +83 -0
- nuitka/tools/general/find_module/FindModuleCode.py +127 -0
- nuitka/tools/general/find_module/__init__.py +19 -0
- nuitka/tools/general/generate_header/GenerateHeader.py +73 -0
- nuitka/tools/general/generate_header/__init__.py +19 -0
- nuitka/tools/onefile_compressor/OnefileCompressor.py +390 -0
- nuitka/tools/onefile_compressor/__init__.py +19 -0
- nuitka/tools/onefile_compressor/__main__.py +41 -0
- nuitka/tools/podman/Podman.py +55 -0
- nuitka/tools/podman/__init__.py +19 -0
- nuitka/tools/podman/__main__.py +425 -0
- nuitka/tools/profiler/__init__.py +19 -0
- nuitka/tools/profiler/__main__.py +93 -0
- nuitka/tools/scanning/DisplayDistributions.py +39 -0
- nuitka/tools/scanning/DisplayPackageDLLs.py +151 -0
- nuitka/tools/scanning/DisplayPackageData.py +73 -0
- nuitka/tools/scanning/__init__.py +19 -0
- nuitka/tools/specialize/CTypeDescriptions.py +1928 -0
- nuitka/tools/specialize/Common.py +380 -0
- nuitka/tools/specialize/SpecializeC.py +1483 -0
- nuitka/tools/specialize/SpecializePython.py +1151 -0
- nuitka/tools/specialize/__init__.py +19 -0
- nuitka/tools/testing/Common.py +2007 -0
- nuitka/tools/testing/Constructs.py +53 -0
- nuitka/tools/testing/DocTests.py +156 -0
- nuitka/tools/testing/OutputComparison.py +313 -0
- nuitka/tools/testing/Pythons.py +34 -0
- nuitka/tools/testing/RuntimeTracing.py +260 -0
- nuitka/tools/testing/SearchModes.py +208 -0
- nuitka/tools/testing/Valgrind.py +103 -0
- nuitka/tools/testing/__init__.py +19 -0
- nuitka/tools/testing/check_reference_counts/__init__.py +19 -0
- nuitka/tools/testing/check_reference_counts/__main__.py +107 -0
- nuitka/tools/testing/compare_with_cpython/__init__.py +19 -0
- nuitka/tools/testing/compare_with_cpython/__main__.py +942 -0
- nuitka/tools/testing/find_sxs_modules/__init__.py +19 -0
- nuitka/tools/testing/find_sxs_modules/__main__.py +73 -0
- nuitka/tools/testing/measure_construct_performance/__init__.py +19 -0
- nuitka/tools/testing/measure_construct_performance/__main__.py +288 -0
- nuitka/tools/testing/run_nuitka_tests/__init__.py +19 -0
- nuitka/tools/testing/run_nuitka_tests/__main__.py +1091 -0
- nuitka/tools/watch/AutoStage.py +145 -0
- nuitka/tools/watch/Common.py +55 -0
- nuitka/tools/watch/Conda.py +125 -0
- nuitka/tools/watch/GitHub.py +113 -0
- nuitka/tools/watch/Pacman.py +73 -0
- nuitka/tools/watch/Pipenv.py +145 -0
- nuitka/tools/watch/__init__.py +19 -0
- nuitka/tools/watch/__main__.py +615 -0
- nuitka/tree/Building.py +1459 -0
- nuitka/tree/ComplexCallHelperFunctions.py +2150 -0
- nuitka/tree/Extractions.py +48 -0
- nuitka/tree/FutureSpecState.py +71 -0
- nuitka/tree/InternalModule.py +96 -0
- nuitka/tree/Operations.py +45 -0
- nuitka/tree/ReformulationAssertStatements.py +97 -0
- nuitka/tree/ReformulationAssignmentStatements.py +1260 -0
- nuitka/tree/ReformulationBooleanExpressions.py +97 -0
- nuitka/tree/ReformulationCallExpressions.py +314 -0
- nuitka/tree/ReformulationClasses.py +407 -0
- nuitka/tree/ReformulationClasses3.py +1149 -0
- nuitka/tree/ReformulationComparisonExpressions.py +174 -0
- nuitka/tree/ReformulationContractionExpressions.py +676 -0
- nuitka/tree/ReformulationDictionaryCreation.py +304 -0
- nuitka/tree/ReformulationExecStatements.py +386 -0
- nuitka/tree/ReformulationForLoopStatements.py +215 -0
- nuitka/tree/ReformulationFunctionStatements.py +931 -0
- nuitka/tree/ReformulationImportStatements.py +333 -0
- nuitka/tree/ReformulationLambdaExpressions.py +185 -0
- nuitka/tree/ReformulationMatchStatements.py +797 -0
- nuitka/tree/ReformulationMultidist.py +80 -0
- nuitka/tree/ReformulationNamespacePackages.py +239 -0
- nuitka/tree/ReformulationPrintStatements.py +127 -0
- nuitka/tree/ReformulationSequenceCreation.py +438 -0
- nuitka/tree/ReformulationSubscriptExpressions.py +123 -0
- nuitka/tree/ReformulationTryExceptStatements.py +418 -0
- nuitka/tree/ReformulationTryFinallyStatements.py +239 -0
- nuitka/tree/ReformulationWhileLoopStatements.py +160 -0
- nuitka/tree/ReformulationWithStatements.py +382 -0
- nuitka/tree/ReformulationYieldExpressions.py +133 -0
- nuitka/tree/SourceHandling.py +476 -0
- nuitka/tree/SyntaxErrors.py +143 -0
- nuitka/tree/TreeHelpers.py +720 -0
- nuitka/tree/VariableClosure.py +483 -0
- nuitka/tree/__init__.py +19 -0
- nuitka/utils/AppDirs.py +104 -0
- nuitka/utils/CStrings.py +208 -0
- nuitka/utils/CommandLineOptions.py +207 -0
- nuitka/utils/Distributions.py +728 -0
- nuitka/utils/Download.py +217 -0
- nuitka/utils/Execution.py +517 -0
- nuitka/utils/FileOperations.py +1587 -0
- nuitka/utils/Hashing.py +137 -0
- nuitka/utils/Images.py +79 -0
- nuitka/utils/Importing.py +335 -0
- nuitka/utils/InlineCopies.py +52 -0
- nuitka/utils/InstalledPythons.py +254 -0
- nuitka/utils/InstanceCounters.py +86 -0
- nuitka/utils/Jinja2.py +158 -0
- nuitka/utils/Json.py +40 -0
- nuitka/utils/MacOSApp.py +134 -0
- nuitka/utils/MemoryUsage.py +165 -0
- nuitka/utils/ModuleNames.py +317 -0
- nuitka/utils/PackageResources.py +44 -0
- nuitka/utils/ReExecute.py +152 -0
- nuitka/utils/Rest.py +60 -0
- nuitka/utils/SharedLibraries.py +1014 -0
- nuitka/utils/Shebang.py +113 -0
- nuitka/utils/Signing.py +144 -0
- nuitka/utils/SlotMetaClasses.py +57 -0
- nuitka/utils/StaticLibraries.py +260 -0
- nuitka/utils/ThreadedExecutor.py +87 -0
- nuitka/utils/Timing.py +102 -0
- nuitka/utils/Utils.py +483 -0
- nuitka/utils/WindowsFileUsage.py +337 -0
- nuitka/utils/WindowsResources.py +652 -0
- nuitka/utils/Yaml.py +247 -0
- nuitka/utils/__init__.py +19 -0
- nuitka_winsvc-2.7.7.data/scripts/nuitka-run.cmd +24 -0
- nuitka_winsvc-2.7.7.data/scripts/nuitka.cmd +30 -0
- nuitka_winsvc-2.7.7.dist-info/METADATA +115 -0
- nuitka_winsvc-2.7.7.dist-info/RECORD +995 -0
- nuitka_winsvc-2.7.7.dist-info/WHEEL +5 -0
- nuitka_winsvc-2.7.7.dist-info/entry_points.txt +7 -0
- nuitka_winsvc-2.7.7.dist-info/licenses/LICENSE.txt +202 -0
- nuitka_winsvc-2.7.7.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,2008 @@
|
|
|
1
|
+
""" Clcache module with core caching functionality. """
|
|
2
|
+
|
|
3
|
+
# This file is part of the clcache project.
|
|
4
|
+
#
|
|
5
|
+
# The contents of this file are subject to the BSD 3-Clause License, the
|
|
6
|
+
# full text of which is available in the accompanying LICENSE file at the
|
|
7
|
+
# root directory of this project.
|
|
8
|
+
#
|
|
9
|
+
from __future__ import print_function
|
|
10
|
+
from __future__ import absolute_import
|
|
11
|
+
import codecs
|
|
12
|
+
import concurrent.futures
|
|
13
|
+
import contextlib
|
|
14
|
+
import errno
|
|
15
|
+
import gzip
|
|
16
|
+
import hashlib
|
|
17
|
+
import json
|
|
18
|
+
import multiprocessing
|
|
19
|
+
import os
|
|
20
|
+
import pickle
|
|
21
|
+
import re
|
|
22
|
+
import subprocess
|
|
23
|
+
import sys
|
|
24
|
+
import threading
|
|
25
|
+
from collections import defaultdict, namedtuple
|
|
26
|
+
from copy import copy
|
|
27
|
+
from ctypes import windll, wintypes
|
|
28
|
+
from shutil import copyfile, copyfileobj, rmtree
|
|
29
|
+
from tempfile import TemporaryFile
|
|
30
|
+
|
|
31
|
+
from atomicwrites import atomic_write
|
|
32
|
+
from io import open
|
|
33
|
+
|
|
34
|
+
from nuitka.utils.Utils import decoratorRetries
|
|
35
|
+
from nuitka.Tracing import general
|
|
36
|
+
|
|
37
|
+
VERSION = "5.0.0-dev"
|
|
38
|
+
|
|
39
|
+
HashAlgorithm = hashlib.md5
|
|
40
|
+
|
|
41
|
+
OUTPUT_LOCK = threading.Lock()
|
|
42
|
+
|
|
43
|
+
# try to use os.scandir or scandir.scandir
|
|
44
|
+
# fall back to os.listdir if not found
|
|
45
|
+
# same for scandir.walk
|
|
46
|
+
try:
|
|
47
|
+
import scandir
|
|
48
|
+
|
|
49
|
+
WALK = scandir.walk
|
|
50
|
+
LIST = scandir.scandir
|
|
51
|
+
except ImportError:
|
|
52
|
+
WALK = os.walk
|
|
53
|
+
try:
|
|
54
|
+
LIST = os.scandir # type: ignore # pylint: disable=I0021,no-name-in-module
|
|
55
|
+
except AttributeError:
|
|
56
|
+
LIST = os.listdir
|
|
57
|
+
|
|
58
|
+
# The codec that is used by clcache to store compiler STDOUR and STDERR in
|
|
59
|
+
# output.txt and stderr.txt.
|
|
60
|
+
# This codec is up to us and only used for clcache internal storage.
|
|
61
|
+
# For possible values see https://docs.python.org/2/library/codecs.html
|
|
62
|
+
CACHE_COMPILER_OUTPUT_STORAGE_CODEC = "utf-8"
|
|
63
|
+
|
|
64
|
+
# The cl default codec
|
|
65
|
+
CL_DEFAULT_CODEC = "mbcs"
|
|
66
|
+
|
|
67
|
+
# Manifest file will have at most this number of hash lists in it. Need to avoi
|
|
68
|
+
# manifests grow too large.
|
|
69
|
+
MAX_MANIFEST_HASHES = 100
|
|
70
|
+
|
|
71
|
+
# String, by which BASE_DIR will be replaced in paths, stored in manifests.
|
|
72
|
+
# ? is invalid character for file name, so it seems ok
|
|
73
|
+
# to use it as mark for relative path.
|
|
74
|
+
BASEDIR_REPLACEMENT = "?"
|
|
75
|
+
|
|
76
|
+
# Define some Win32 API constants here to avoid dependency on win32pipe
|
|
77
|
+
NMPWAIT_WAIT_FOREVER = wintypes.DWORD(0xFFFFFFFF)
|
|
78
|
+
ERROR_PIPE_BUSY = 231
|
|
79
|
+
|
|
80
|
+
# ManifestEntry: an entry in a manifest file
|
|
81
|
+
# `includeFiles`: list of paths to include files, which this source file uses
|
|
82
|
+
# `includesContentsHash`: hash of the contents of the includeFiles
|
|
83
|
+
# `objectHash`: hash of the object in cache
|
|
84
|
+
ManifestEntry = namedtuple(
|
|
85
|
+
"ManifestEntry", ["includeFiles", "includesContentHash", "objectHash"]
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
CompilerArtifacts = namedtuple(
|
|
89
|
+
"CompilerArtifacts", ["objectFilePath", "stdout", "stderr"]
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def printBinary(stream, rawData):
|
|
94
|
+
with OUTPUT_LOCK:
|
|
95
|
+
stream.buffer.write(rawData)
|
|
96
|
+
stream.flush()
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def basenameWithoutExtension(path):
|
|
100
|
+
basename = os.path.basename(path)
|
|
101
|
+
return os.path.splitext(basename)[0]
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def filesBeneath(baseDir):
|
|
105
|
+
for path, _, filenames in WALK(baseDir):
|
|
106
|
+
for filename in filenames:
|
|
107
|
+
yield os.path.join(path, filename)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def childDirectories(path, absolute=True):
|
|
111
|
+
supportsScandir = LIST != os.listdir # pylint: disable=comparison-with-callable
|
|
112
|
+
for entry in LIST(path):
|
|
113
|
+
if supportsScandir:
|
|
114
|
+
if entry.is_dir():
|
|
115
|
+
yield entry.path if absolute else entry.name
|
|
116
|
+
else:
|
|
117
|
+
absPath = os.path.join(path, entry)
|
|
118
|
+
if os.path.isdir(absPath):
|
|
119
|
+
yield absPath if absolute else entry
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def normalizeBaseDir(baseDir):
|
|
123
|
+
if baseDir:
|
|
124
|
+
baseDir = os.path.normcase(baseDir)
|
|
125
|
+
if baseDir.endswith(os.path.sep):
|
|
126
|
+
baseDir = baseDir[0:-1]
|
|
127
|
+
return baseDir
|
|
128
|
+
else:
|
|
129
|
+
# Converts empty string to None
|
|
130
|
+
return None
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def getCachedCompilerConsoleOutput(path):
|
|
134
|
+
try:
|
|
135
|
+
with open(path, "rb") as f:
|
|
136
|
+
return f.read().decode(CACHE_COMPILER_OUTPUT_STORAGE_CODEC)
|
|
137
|
+
except IOError:
|
|
138
|
+
return ""
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def setCachedCompilerConsoleOutput(path, output):
|
|
142
|
+
with open(path, "wb") as f:
|
|
143
|
+
f.write(output.encode(CACHE_COMPILER_OUTPUT_STORAGE_CODEC))
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class IncludeNotFoundException(Exception):
|
|
147
|
+
pass
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class CacheLockException(Exception):
|
|
151
|
+
pass
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class CompilerFailedException(Exception):
|
|
155
|
+
def __init__(self, exitCode, msgErr, msgOut=""):
|
|
156
|
+
Exception.__init__(self, msgErr)
|
|
157
|
+
self.exitCode = exitCode
|
|
158
|
+
self.msgOut = msgOut
|
|
159
|
+
self.msgErr = msgErr
|
|
160
|
+
|
|
161
|
+
def getReturnTuple(self):
|
|
162
|
+
return self.exitCode, self.msgErr, self.msgOut, False
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class Manifest(object):
|
|
166
|
+
def __init__(self, entries=None):
|
|
167
|
+
if entries is None:
|
|
168
|
+
entries = []
|
|
169
|
+
self._entries = copy(entries)
|
|
170
|
+
|
|
171
|
+
def entries(self):
|
|
172
|
+
return self._entries
|
|
173
|
+
|
|
174
|
+
def addEntry(self, entry):
|
|
175
|
+
"""Adds entry at the top of the entries"""
|
|
176
|
+
self._entries.insert(0, entry)
|
|
177
|
+
|
|
178
|
+
def touchEntry(self, objectHash):
|
|
179
|
+
"""Moves entry in entryIndex position to the top of entries()"""
|
|
180
|
+
entryIndex = next(
|
|
181
|
+
(i for i, e in enumerate(self.entries()) if e.objectHash == objectHash), 0
|
|
182
|
+
)
|
|
183
|
+
self._entries.insert(0, self._entries.pop(entryIndex))
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class ManifestSection(object):
|
|
187
|
+
def __init__(self, manifestSectionDir):
|
|
188
|
+
self.manifestSectionDir = manifestSectionDir
|
|
189
|
+
self.lock = CacheLock.forPath(self.manifestSectionDir)
|
|
190
|
+
|
|
191
|
+
def manifestPath(self, manifestHash):
|
|
192
|
+
return os.path.join(self.manifestSectionDir, manifestHash + ".json")
|
|
193
|
+
|
|
194
|
+
def manifestFiles(self):
|
|
195
|
+
return filesBeneath(self.manifestSectionDir)
|
|
196
|
+
|
|
197
|
+
def setManifest(self, manifestHash, manifest):
|
|
198
|
+
manifestPath = self.manifestPath(manifestHash)
|
|
199
|
+
printTraceStatement(
|
|
200
|
+
"Writing manifest with manifestHash = {} to {}".format(
|
|
201
|
+
manifestHash, manifestPath
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
ensureDirectoryExists(self.manifestSectionDir)
|
|
205
|
+
with atomic_write(manifestPath, overwrite=True) as outFile:
|
|
206
|
+
# Converting namedtuple to JSON via OrderedDict preserves key names and keys order
|
|
207
|
+
entries = [e._asdict() for e in manifest.entries()]
|
|
208
|
+
jsonobject = {"entries": entries}
|
|
209
|
+
json.dump(jsonobject, outFile, sort_keys=True, indent=2)
|
|
210
|
+
|
|
211
|
+
def getManifest(self, manifestHash):
|
|
212
|
+
fileName = self.manifestPath(manifestHash)
|
|
213
|
+
if not os.path.exists(fileName):
|
|
214
|
+
return None
|
|
215
|
+
try:
|
|
216
|
+
with open(fileName, "r") as inFile:
|
|
217
|
+
doc = json.load(inFile)
|
|
218
|
+
return Manifest(
|
|
219
|
+
[
|
|
220
|
+
ManifestEntry(
|
|
221
|
+
e["includeFiles"], e["includesContentHash"], e["objectHash"]
|
|
222
|
+
)
|
|
223
|
+
for e in doc["entries"]
|
|
224
|
+
]
|
|
225
|
+
)
|
|
226
|
+
except IOError:
|
|
227
|
+
return None
|
|
228
|
+
except ValueError:
|
|
229
|
+
printErrStr("clcache: manifest file %s was broken" % fileName)
|
|
230
|
+
return None
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@contextlib.contextmanager
|
|
234
|
+
def allSectionsLocked(repository):
|
|
235
|
+
sections = list(repository.sections())
|
|
236
|
+
for section in sections:
|
|
237
|
+
section.lock.acquire()
|
|
238
|
+
try:
|
|
239
|
+
yield
|
|
240
|
+
finally:
|
|
241
|
+
for section in sections:
|
|
242
|
+
section.lock.release()
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class ManifestRepository(object):
|
|
246
|
+
# Bump this counter whenever the current manifest file format changes.
|
|
247
|
+
# E.g. changing the file format from {'oldkey': ...} to {'newkey': ...} requires
|
|
248
|
+
# invalidation, such that a manifest that was stored using the old format is not
|
|
249
|
+
# interpreted using the new format. Instead the old file will not be touched
|
|
250
|
+
# again due to a new manifest hash and is cleaned away after some time.
|
|
251
|
+
MANIFEST_FILE_FORMAT_VERSION = 6
|
|
252
|
+
|
|
253
|
+
def __init__(self, manifestsRootDir):
|
|
254
|
+
self._manifestsRootDir = manifestsRootDir
|
|
255
|
+
|
|
256
|
+
def section(self, manifestHash):
|
|
257
|
+
return ManifestSection(os.path.join(self._manifestsRootDir, manifestHash[:3]))
|
|
258
|
+
|
|
259
|
+
def sections(self):
|
|
260
|
+
return (
|
|
261
|
+
ManifestSection(path) for path in childDirectories(self._manifestsRootDir)
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
def clean(self, maxManifestsSize):
|
|
265
|
+
manifestFileInfos = []
|
|
266
|
+
for section in self.sections():
|
|
267
|
+
for filePath in section.manifestFiles():
|
|
268
|
+
try:
|
|
269
|
+
manifestFileInfos.append((os.stat(filePath), filePath))
|
|
270
|
+
except OSError:
|
|
271
|
+
pass
|
|
272
|
+
|
|
273
|
+
manifestFileInfos.sort(key=lambda t: t[0].st_atime, reverse=True)
|
|
274
|
+
|
|
275
|
+
remainingObjectsSize = 0
|
|
276
|
+
for stat, filepath in manifestFileInfos:
|
|
277
|
+
if remainingObjectsSize + stat.st_size <= maxManifestsSize:
|
|
278
|
+
remainingObjectsSize += stat.st_size
|
|
279
|
+
else:
|
|
280
|
+
os.remove(filepath)
|
|
281
|
+
return remainingObjectsSize
|
|
282
|
+
|
|
283
|
+
@staticmethod
|
|
284
|
+
def getManifestHash(compilerBinary, commandLine, sourceFile):
|
|
285
|
+
compilerHash = getCompilerHash(compilerBinary)
|
|
286
|
+
|
|
287
|
+
# NOTE: We intentionally do not normalize command line to include
|
|
288
|
+
# preprocessor options. In direct mode we do not perform preprocessing
|
|
289
|
+
# before cache lookup, so all parameters are important. One of the few
|
|
290
|
+
# exceptions to this rule is the /MP switch, which only defines how many
|
|
291
|
+
# compiler processes are running simultaneously. Arguments that specify
|
|
292
|
+
# the compiler where to find the source files are parsed to replace
|
|
293
|
+
# occurrences of CLCACHE_BASEDIR by a placeholder.
|
|
294
|
+
arguments, inputFiles = CommandLineAnalyzer.parseArgumentsAndInputFiles(
|
|
295
|
+
commandLine
|
|
296
|
+
)
|
|
297
|
+
collapseBasedirInCmdPath = lambda path: collapseBasedirToPlaceholder(
|
|
298
|
+
os.path.normcase(os.path.abspath(path))
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
commandLine = []
|
|
302
|
+
argumentsWithPaths = ("AI", "I", "FU")
|
|
303
|
+
for k in sorted(arguments.keys()):
|
|
304
|
+
if k in argumentsWithPaths:
|
|
305
|
+
commandLine.extend(
|
|
306
|
+
["/" + k + collapseBasedirInCmdPath(arg) for arg in arguments[k]]
|
|
307
|
+
)
|
|
308
|
+
else:
|
|
309
|
+
commandLine.extend(["/" + k + arg for arg in arguments[k]])
|
|
310
|
+
|
|
311
|
+
commandLine.extend(collapseBasedirInCmdPath(arg) for arg in inputFiles)
|
|
312
|
+
|
|
313
|
+
additionalData = "{}|{}|{}".format(
|
|
314
|
+
compilerHash, commandLine, ManifestRepository.MANIFEST_FILE_FORMAT_VERSION
|
|
315
|
+
)
|
|
316
|
+
return getFileHash(sourceFile, additionalData)
|
|
317
|
+
|
|
318
|
+
@staticmethod
|
|
319
|
+
def getIncludesContentHashForFiles(includes):
|
|
320
|
+
try:
|
|
321
|
+
listOfHashes = getFileHashes(includes)
|
|
322
|
+
except FileNotFoundError:
|
|
323
|
+
raise IncludeNotFoundException
|
|
324
|
+
return ManifestRepository.getIncludesContentHashForHashes(listOfHashes)
|
|
325
|
+
|
|
326
|
+
@staticmethod
|
|
327
|
+
def getIncludesContentHashForHashes(listOfHashes):
|
|
328
|
+
return HashAlgorithm(",".join(listOfHashes).encode()).hexdigest()
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
# Lets be inefficient and have just one lock for all things, won't be a big deal
|
|
332
|
+
# if it's only used for stats.
|
|
333
|
+
from threading import RLock
|
|
334
|
+
cache_lock = RLock()
|
|
335
|
+
|
|
336
|
+
class CacheLock2(object):
|
|
337
|
+
"""Implement a lock inside the process only. """
|
|
338
|
+
|
|
339
|
+
def __init__(self):
|
|
340
|
+
self._rlock = None
|
|
341
|
+
|
|
342
|
+
def __enter__(self):
|
|
343
|
+
cache_lock.acquire()
|
|
344
|
+
|
|
345
|
+
def __exit__(self, typ, value, traceback):
|
|
346
|
+
cache_lock.release()
|
|
347
|
+
|
|
348
|
+
@staticmethod
|
|
349
|
+
def forPath(path):
|
|
350
|
+
return CacheLock2()
|
|
351
|
+
|
|
352
|
+
class CacheLock(object):
|
|
353
|
+
"""Implements a lock for the object cache which
|
|
354
|
+
can be used in 'with' statements."""
|
|
355
|
+
|
|
356
|
+
INFINITE = 0xFFFFFFFF
|
|
357
|
+
WAIT_ABANDONED_CODE = 0x00000080
|
|
358
|
+
WAIT_TIMEOUT_CODE = 0x00000102
|
|
359
|
+
|
|
360
|
+
def __init__(self, mutexName, timeoutMs):
|
|
361
|
+
self._mutexName = u"Local\\" + mutexName
|
|
362
|
+
self._mutex = None
|
|
363
|
+
self._timeoutMs = timeoutMs
|
|
364
|
+
|
|
365
|
+
def createMutex(self):
|
|
366
|
+
with CacheLock2():
|
|
367
|
+
self._mutex = windll.kernel32.CreateMutexW(
|
|
368
|
+
None, wintypes.BOOL(False), self._mutexName
|
|
369
|
+
)
|
|
370
|
+
assert self._mutex
|
|
371
|
+
|
|
372
|
+
def __enter__(self):
|
|
373
|
+
self.acquire()
|
|
374
|
+
|
|
375
|
+
def __exit__(self, typ, value, traceback):
|
|
376
|
+
self.release()
|
|
377
|
+
|
|
378
|
+
def __del__(self):
|
|
379
|
+
if self._mutex:
|
|
380
|
+
windll.kernel32.CloseHandle(self._mutex)
|
|
381
|
+
|
|
382
|
+
def acquire(self):
|
|
383
|
+
if not self._mutex:
|
|
384
|
+
self.createMutex()
|
|
385
|
+
result = windll.kernel32.WaitForSingleObject(
|
|
386
|
+
self._mutex, wintypes.INT(self._timeoutMs)
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
if result not in [0, self.WAIT_ABANDONED_CODE]:
|
|
391
|
+
# Nuitka: Just give up
|
|
392
|
+
return
|
|
393
|
+
|
|
394
|
+
if result == self.WAIT_TIMEOUT_CODE:
|
|
395
|
+
errorString = (
|
|
396
|
+
"Failed to acquire lock {} after {}ms; "
|
|
397
|
+
"try setting CLCACHE_OBJECT_CACHE_TIMEOUT_MS environment variable to a larger value.".format(
|
|
398
|
+
self._mutexName, self._timeoutMs
|
|
399
|
+
)
|
|
400
|
+
)
|
|
401
|
+
else:
|
|
402
|
+
errorString = "Error! WaitForSingleObject returns {result}, last error {error}".format(
|
|
403
|
+
result=result, error=windll.kernel32.GetLastError()
|
|
404
|
+
)
|
|
405
|
+
raise CacheLockException(errorString)
|
|
406
|
+
|
|
407
|
+
def release(self):
|
|
408
|
+
windll.kernel32.ReleaseMutex(self._mutex)
|
|
409
|
+
|
|
410
|
+
@staticmethod
|
|
411
|
+
def forPath(path):
|
|
412
|
+
timeoutMs = int(os.environ.get("CLCACHE_OBJECT_CACHE_TIMEOUT_MS", 10 * 1000))
|
|
413
|
+
lockName = path.replace(":", "-").replace("\\", "-")
|
|
414
|
+
return CacheLock(lockName, timeoutMs)
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
class CompilerArtifactsSection(object):
|
|
418
|
+
OBJECT_FILE = "object"
|
|
419
|
+
STDOUT_FILE = "output.txt"
|
|
420
|
+
STDERR_FILE = "stderr.txt"
|
|
421
|
+
|
|
422
|
+
def __init__(self, compilerArtifactsSectionDir):
|
|
423
|
+
self.compilerArtifactsSectionDir = compilerArtifactsSectionDir
|
|
424
|
+
self.lock = CacheLock.forPath(self.compilerArtifactsSectionDir)
|
|
425
|
+
|
|
426
|
+
def cacheEntryDir(self, key):
|
|
427
|
+
return os.path.join(self.compilerArtifactsSectionDir, key)
|
|
428
|
+
|
|
429
|
+
def cacheEntries(self):
|
|
430
|
+
return childDirectories(self.compilerArtifactsSectionDir, absolute=False)
|
|
431
|
+
|
|
432
|
+
def cachedObjectName(self, key):
|
|
433
|
+
return os.path.join(
|
|
434
|
+
self.cacheEntryDir(key), CompilerArtifactsSection.OBJECT_FILE
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
def hasEntry(self, key):
|
|
438
|
+
return os.path.exists(self.cacheEntryDir(key))
|
|
439
|
+
|
|
440
|
+
def setEntry(self, key, artifacts):
|
|
441
|
+
cacheEntryDir = self.cacheEntryDir(key)
|
|
442
|
+
# Write new files to a temporary directory
|
|
443
|
+
tempEntryDir = cacheEntryDir + ".new"
|
|
444
|
+
# Remove any possible left-over in tempEntryDir from previous executions
|
|
445
|
+
rmtree(tempEntryDir, ignore_errors=True)
|
|
446
|
+
ensureDirectoryExists(tempEntryDir)
|
|
447
|
+
if artifacts.objectFilePath is not None:
|
|
448
|
+
dstFilePath = os.path.join(
|
|
449
|
+
tempEntryDir, CompilerArtifactsSection.OBJECT_FILE
|
|
450
|
+
)
|
|
451
|
+
copyOrLink(artifacts.objectFilePath, dstFilePath, True)
|
|
452
|
+
size = os.path.getsize(dstFilePath)
|
|
453
|
+
setCachedCompilerConsoleOutput(
|
|
454
|
+
os.path.join(tempEntryDir, CompilerArtifactsSection.STDOUT_FILE),
|
|
455
|
+
artifacts.stdout,
|
|
456
|
+
)
|
|
457
|
+
if artifacts.stderr != "":
|
|
458
|
+
setCachedCompilerConsoleOutput(
|
|
459
|
+
os.path.join(tempEntryDir, CompilerArtifactsSection.STDERR_FILE),
|
|
460
|
+
artifacts.stderr,
|
|
461
|
+
)
|
|
462
|
+
# Replace the full cache entry atomically
|
|
463
|
+
@decoratorRetries(
|
|
464
|
+
logger=general,
|
|
465
|
+
purpose="replace %r with %r" % (cacheEntryDir, tempEntryDir),
|
|
466
|
+
consequence="aborting",
|
|
467
|
+
)
|
|
468
|
+
def _replaceEntry():
|
|
469
|
+
os.replace(tempEntryDir, cacheEntryDir)
|
|
470
|
+
|
|
471
|
+
_replaceEntry()
|
|
472
|
+
return size
|
|
473
|
+
|
|
474
|
+
def getEntry(self, key):
|
|
475
|
+
assert self.hasEntry(key)
|
|
476
|
+
cacheEntryDir = self.cacheEntryDir(key)
|
|
477
|
+
return CompilerArtifacts(
|
|
478
|
+
os.path.join(cacheEntryDir, CompilerArtifactsSection.OBJECT_FILE),
|
|
479
|
+
getCachedCompilerConsoleOutput(
|
|
480
|
+
os.path.join(cacheEntryDir, CompilerArtifactsSection.STDOUT_FILE)
|
|
481
|
+
),
|
|
482
|
+
getCachedCompilerConsoleOutput(
|
|
483
|
+
os.path.join(cacheEntryDir, CompilerArtifactsSection.STDERR_FILE)
|
|
484
|
+
),
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
class CompilerArtifactsRepository(object):
|
|
489
|
+
def __init__(self, compilerArtifactsRootDir):
|
|
490
|
+
self._compilerArtifactsRootDir = compilerArtifactsRootDir
|
|
491
|
+
|
|
492
|
+
def section(self, key):
|
|
493
|
+
return CompilerArtifactsSection(
|
|
494
|
+
os.path.join(self._compilerArtifactsRootDir, key[:3])
|
|
495
|
+
)
|
|
496
|
+
|
|
497
|
+
def sections(self):
|
|
498
|
+
return (
|
|
499
|
+
CompilerArtifactsSection(path)
|
|
500
|
+
for path in childDirectories(self._compilerArtifactsRootDir)
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
def removeEntry(self, keyToBeRemoved):
|
|
504
|
+
compilerArtifactsDir = self.section(keyToBeRemoved).cacheEntryDir(
|
|
505
|
+
keyToBeRemoved
|
|
506
|
+
)
|
|
507
|
+
rmtree(compilerArtifactsDir, ignore_errors=True)
|
|
508
|
+
|
|
509
|
+
def clean(self, maxCompilerArtifactsSize):
|
|
510
|
+
objectInfos = []
|
|
511
|
+
for section in self.sections():
|
|
512
|
+
for cachekey in section.cacheEntries():
|
|
513
|
+
try:
|
|
514
|
+
objectStat = os.stat(section.cachedObjectName(cachekey))
|
|
515
|
+
objectInfos.append((objectStat, cachekey))
|
|
516
|
+
except OSError:
|
|
517
|
+
pass
|
|
518
|
+
|
|
519
|
+
objectInfos.sort(key=lambda t: t[0].st_atime)
|
|
520
|
+
|
|
521
|
+
# compute real current size to fix up the stored cacheSize
|
|
522
|
+
currentSizeObjects = sum(x[0].st_size for x in objectInfos)
|
|
523
|
+
|
|
524
|
+
removedItems = 0
|
|
525
|
+
for stat, cachekey in objectInfos:
|
|
526
|
+
self.removeEntry(cachekey)
|
|
527
|
+
removedItems += 1
|
|
528
|
+
currentSizeObjects -= stat.st_size
|
|
529
|
+
if currentSizeObjects < maxCompilerArtifactsSize:
|
|
530
|
+
break
|
|
531
|
+
|
|
532
|
+
return len(objectInfos) - removedItems, currentSizeObjects
|
|
533
|
+
|
|
534
|
+
@staticmethod
|
|
535
|
+
def computeKeyDirect(manifestHash, includesContentHash):
|
|
536
|
+
# We must take into account manifestHash to avoid
|
|
537
|
+
# collisions when different source files use the same
|
|
538
|
+
# set of includes.
|
|
539
|
+
return getStringHash(manifestHash + includesContentHash)
|
|
540
|
+
|
|
541
|
+
@staticmethod
|
|
542
|
+
def computeKeyNodirect(compilerBinary, commandLine, environment):
|
|
543
|
+
ppcmd = ["/EP"] + [arg for arg in commandLine if arg not in ("-c", "/c")]
|
|
544
|
+
|
|
545
|
+
returnCode, preprocessedSourceCode, ppStderrBinary = invokeRealCompiler(
|
|
546
|
+
compilerBinary,
|
|
547
|
+
ppcmd,
|
|
548
|
+
captureOutput=True,
|
|
549
|
+
outputAsString=False,
|
|
550
|
+
environment=environment,
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
if returnCode != 0:
|
|
554
|
+
errMsg = (
|
|
555
|
+
ppStderrBinary.decode(CL_DEFAULT_CODEC)
|
|
556
|
+
+ "\nclcache: preprocessor failed"
|
|
557
|
+
)
|
|
558
|
+
raise CompilerFailedException(returnCode, errMsg)
|
|
559
|
+
|
|
560
|
+
compilerHash = getCompilerHash(compilerBinary)
|
|
561
|
+
normalizedCmdLine = CompilerArtifactsRepository._normalizedCommandLine(
|
|
562
|
+
commandLine
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
h = HashAlgorithm()
|
|
566
|
+
h.update(compilerHash.encode("UTF-8"))
|
|
567
|
+
h.update(" ".join(normalizedCmdLine).encode("UTF-8"))
|
|
568
|
+
h.update(preprocessedSourceCode)
|
|
569
|
+
return h.hexdigest()
|
|
570
|
+
|
|
571
|
+
@staticmethod
|
|
572
|
+
def _normalizedCommandLine(cmdline):
|
|
573
|
+
# Remove all arguments from the command line which only influence the
|
|
574
|
+
# preprocessor; the preprocessor's output is already included into the
|
|
575
|
+
# hash sum so we don't have to care about these switches in the
|
|
576
|
+
# command line as well.
|
|
577
|
+
argsToStrip = (
|
|
578
|
+
"AI",
|
|
579
|
+
"C",
|
|
580
|
+
"E",
|
|
581
|
+
"P",
|
|
582
|
+
"FI",
|
|
583
|
+
"u",
|
|
584
|
+
"X",
|
|
585
|
+
"FU",
|
|
586
|
+
"D",
|
|
587
|
+
"EP",
|
|
588
|
+
"Fx",
|
|
589
|
+
"U",
|
|
590
|
+
"I",
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
# Also remove the switch for specifying the output file name; we don't
|
|
594
|
+
# want two invocations which are identical except for the output file
|
|
595
|
+
# name to be treated differently.
|
|
596
|
+
argsToStrip += ("Fo",)
|
|
597
|
+
|
|
598
|
+
# Also strip the switch for specifying the number of parallel compiler
|
|
599
|
+
# processes to use (when specifying multiple source files on the
|
|
600
|
+
# command line).
|
|
601
|
+
argsToStrip += ("MP",)
|
|
602
|
+
|
|
603
|
+
return [
|
|
604
|
+
arg
|
|
605
|
+
for arg in cmdline
|
|
606
|
+
if not (arg[0] in "/-" and arg[1:].startswith(argsToStrip))
|
|
607
|
+
]
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
class CacheFileStrategy(object):
|
|
611
|
+
def __init__(self, cacheDirectory=None):
|
|
612
|
+
self.dir = cacheDirectory
|
|
613
|
+
if not self.dir:
|
|
614
|
+
try:
|
|
615
|
+
self.dir = os.environ["CLCACHE_DIR"]
|
|
616
|
+
except KeyError:
|
|
617
|
+
self.dir = os.path.join(os.path.expanduser("~"), "clcache")
|
|
618
|
+
|
|
619
|
+
manifestsRootDir = os.path.join(self.dir, "manifests")
|
|
620
|
+
ensureDirectoryExists(manifestsRootDir)
|
|
621
|
+
self.manifestRepository = ManifestRepository(manifestsRootDir)
|
|
622
|
+
|
|
623
|
+
compilerArtifactsRootDir = os.path.join(self.dir, "objects")
|
|
624
|
+
ensureDirectoryExists(compilerArtifactsRootDir)
|
|
625
|
+
self.compilerArtifactsRepository = CompilerArtifactsRepository(
|
|
626
|
+
compilerArtifactsRootDir
|
|
627
|
+
)
|
|
628
|
+
|
|
629
|
+
self.configuration = Configuration(os.path.join(self.dir, "config.txt"))
|
|
630
|
+
|
|
631
|
+
stats_filename = os.environ.get(
|
|
632
|
+
"CLCACHE_STATS", os.path.join(self.dir, "stats.txt")
|
|
633
|
+
)
|
|
634
|
+
self.statistics = Statistics(stats_filename)
|
|
635
|
+
|
|
636
|
+
def __str__(self):
|
|
637
|
+
return "Disk cache at {}".format(self.dir)
|
|
638
|
+
|
|
639
|
+
@property # type: ignore
|
|
640
|
+
@contextlib.contextmanager
|
|
641
|
+
def lock(self):
|
|
642
|
+
with allSectionsLocked(self.manifestRepository), allSectionsLocked(
|
|
643
|
+
self.compilerArtifactsRepository
|
|
644
|
+
):
|
|
645
|
+
yield
|
|
646
|
+
|
|
647
|
+
def lockFor(self, key):
|
|
648
|
+
assert isinstance(self.compilerArtifactsRepository.section(key).lock, CacheLock)
|
|
649
|
+
return self.compilerArtifactsRepository.section(key).lock
|
|
650
|
+
|
|
651
|
+
def manifestLockFor(self, key):
|
|
652
|
+
return self.manifestRepository.section(key).lock
|
|
653
|
+
|
|
654
|
+
def getEntry(self, key):
|
|
655
|
+
return self.compilerArtifactsRepository.section(key).getEntry(key)
|
|
656
|
+
|
|
657
|
+
def setEntry(self, key, value):
|
|
658
|
+
return self.compilerArtifactsRepository.section(key).setEntry(key, value)
|
|
659
|
+
|
|
660
|
+
def pathForObject(self, key):
|
|
661
|
+
return self.compilerArtifactsRepository.section(key).cachedObjectName(key)
|
|
662
|
+
|
|
663
|
+
def directoryForCache(self, key):
|
|
664
|
+
return self.compilerArtifactsRepository.section(key).cacheEntryDir(key)
|
|
665
|
+
|
|
666
|
+
def deserializeCacheEntry(self, key, objectData):
|
|
667
|
+
path = self.pathForObject(key)
|
|
668
|
+
ensureDirectoryExists(self.directoryForCache(key))
|
|
669
|
+
with open(path, "wb") as f:
|
|
670
|
+
f.write(objectData)
|
|
671
|
+
return path
|
|
672
|
+
|
|
673
|
+
def hasEntry(self, cachekey):
|
|
674
|
+
return self.compilerArtifactsRepository.section(cachekey).hasEntry(cachekey)
|
|
675
|
+
|
|
676
|
+
def setManifest(self, manifestHash, manifest):
|
|
677
|
+
self.manifestRepository.section(manifestHash).setManifest(
|
|
678
|
+
manifestHash, manifest
|
|
679
|
+
)
|
|
680
|
+
|
|
681
|
+
def getManifest(self, manifestHash):
|
|
682
|
+
return self.manifestRepository.section(manifestHash).getManifest(manifestHash)
|
|
683
|
+
|
|
684
|
+
def clean(self, stats, maximumSize):
|
|
685
|
+
currentSize = stats.currentCacheSize()
|
|
686
|
+
if currentSize < maximumSize:
|
|
687
|
+
return
|
|
688
|
+
|
|
689
|
+
# Free at least 10% to avoid cleaning up too often which
|
|
690
|
+
# is a big performance hit with large caches.
|
|
691
|
+
effectiveMaximumSizeOverall = maximumSize * 0.9
|
|
692
|
+
|
|
693
|
+
# Split limit in manifests (10 %) and objects (90 %)
|
|
694
|
+
effectiveMaximumSizeManifests = effectiveMaximumSizeOverall * 0.1
|
|
695
|
+
effectiveMaximumSizeObjects = (
|
|
696
|
+
effectiveMaximumSizeOverall - effectiveMaximumSizeManifests
|
|
697
|
+
)
|
|
698
|
+
|
|
699
|
+
# Clean manifests
|
|
700
|
+
currentSizeManifests = self.manifestRepository.clean(
|
|
701
|
+
effectiveMaximumSizeManifests
|
|
702
|
+
)
|
|
703
|
+
|
|
704
|
+
# Clean artifacts
|
|
705
|
+
(
|
|
706
|
+
currentCompilerArtifactsCount,
|
|
707
|
+
currentCompilerArtifactsSize,
|
|
708
|
+
) = self.compilerArtifactsRepository.clean(effectiveMaximumSizeObjects)
|
|
709
|
+
|
|
710
|
+
stats.setCacheSize(currentCompilerArtifactsSize + currentSizeManifests)
|
|
711
|
+
stats.setNumCacheEntries(currentCompilerArtifactsCount)
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
class Cache(object):
|
|
715
|
+
def __init__(self, cacheDirectory=None):
|
|
716
|
+
if os.environ.get("CLCACHE_MEMCACHED"):
|
|
717
|
+
from .storage import CacheFileWithMemcacheFallbackStrategy
|
|
718
|
+
|
|
719
|
+
self.strategy = CacheFileWithMemcacheFallbackStrategy(
|
|
720
|
+
os.environ.get("CLCACHE_MEMCACHED"), cacheDirectory=cacheDirectory
|
|
721
|
+
)
|
|
722
|
+
else:
|
|
723
|
+
self.strategy = CacheFileStrategy(cacheDirectory=cacheDirectory)
|
|
724
|
+
|
|
725
|
+
def __str__(self):
|
|
726
|
+
return str(self.strategy)
|
|
727
|
+
|
|
728
|
+
@property
|
|
729
|
+
def lock(self):
|
|
730
|
+
return self.strategy.lock
|
|
731
|
+
|
|
732
|
+
@contextlib.contextmanager
|
|
733
|
+
def manifestLockFor(self, key):
|
|
734
|
+
with self.strategy.manifestLockFor(key):
|
|
735
|
+
yield
|
|
736
|
+
|
|
737
|
+
@property
|
|
738
|
+
def configuration(self):
|
|
739
|
+
return self.strategy.configuration
|
|
740
|
+
|
|
741
|
+
@property
|
|
742
|
+
def statistics(self):
|
|
743
|
+
return self.strategy.statistics
|
|
744
|
+
|
|
745
|
+
def clean(self, stats, maximumSize):
|
|
746
|
+
return self.strategy.clean(stats, maximumSize)
|
|
747
|
+
|
|
748
|
+
@contextlib.contextmanager
|
|
749
|
+
def lockFor(self, key):
|
|
750
|
+
with self.strategy.lockFor(key):
|
|
751
|
+
yield
|
|
752
|
+
|
|
753
|
+
def getEntry(self, key):
|
|
754
|
+
return self.strategy.getEntry(key)
|
|
755
|
+
|
|
756
|
+
def setEntry(self, key, value):
|
|
757
|
+
return self.strategy.setEntry(key, value)
|
|
758
|
+
|
|
759
|
+
def hasEntry(self, cachekey):
|
|
760
|
+
return self.strategy.hasEntry(cachekey)
|
|
761
|
+
|
|
762
|
+
def setManifest(self, manifestHash, manifest):
|
|
763
|
+
self.strategy.setManifest(manifestHash, manifest)
|
|
764
|
+
|
|
765
|
+
def getManifest(self, manifestHash):
|
|
766
|
+
return self.strategy.getManifest(manifestHash)
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
class PersistentJSONDict(object):
|
|
770
|
+
def __init__(self, fileName):
|
|
771
|
+
self._dirty = False
|
|
772
|
+
self._dict = {}
|
|
773
|
+
self._fileName = fileName
|
|
774
|
+
try:
|
|
775
|
+
with open(self._fileName, "r") as f:
|
|
776
|
+
self._dict = json.load(f)
|
|
777
|
+
except IOError:
|
|
778
|
+
pass
|
|
779
|
+
except ValueError:
|
|
780
|
+
printErrStr("clcache: persistent json file %s was broken" % fileName)
|
|
781
|
+
|
|
782
|
+
def save(self):
|
|
783
|
+
if self._dirty:
|
|
784
|
+
with atomic_write(self._fileName, overwrite=True) as f:
|
|
785
|
+
json.dump(self._dict, f, sort_keys=True, indent=4)
|
|
786
|
+
|
|
787
|
+
def __setitem__(self, key, value):
|
|
788
|
+
self._dict[key] = value
|
|
789
|
+
self._dirty = True
|
|
790
|
+
|
|
791
|
+
def __getitem__(self, key):
|
|
792
|
+
return self._dict[key]
|
|
793
|
+
|
|
794
|
+
def __contains__(self, key):
|
|
795
|
+
return key in self._dict
|
|
796
|
+
|
|
797
|
+
def __eq__(self, other):
|
|
798
|
+
return type(self) is type(other) and self.__dict__ == other.__dict__
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
class Configuration(object):
|
|
802
|
+
_defaultValues = {"MaximumCacheSize": 1073741824} # 1 GiB
|
|
803
|
+
|
|
804
|
+
def __init__(self, configurationFile):
|
|
805
|
+
self._configurationFile = configurationFile
|
|
806
|
+
self._cfg = dict(self._defaultValues)
|
|
807
|
+
|
|
808
|
+
def __enter__(self):
|
|
809
|
+
return self
|
|
810
|
+
|
|
811
|
+
def __exit__(self, typ, value, traceback):
|
|
812
|
+
# Does not write to disc when unchanged
|
|
813
|
+
pass
|
|
814
|
+
|
|
815
|
+
def maximumCacheSize(self):
|
|
816
|
+
return self._cfg["MaximumCacheSize"]
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
stats = None
|
|
820
|
+
|
|
821
|
+
class Statistics(object):
|
|
822
|
+
CALLS_WITH_INVALID_ARGUMENT = "CallsWithInvalidArgument"
|
|
823
|
+
CALLS_WITHOUT_SOURCE_FILE = "CallsWithoutSourceFile"
|
|
824
|
+
CALLS_WITH_MULTIPLE_SOURCE_FILES = "CallsWithMultipleSourceFiles"
|
|
825
|
+
CALLS_WITH_PCH = "CallsWithPch"
|
|
826
|
+
CALLS_FOR_LINKING = "CallsForLinking"
|
|
827
|
+
CALLS_FOR_EXTERNAL_DEBUG_INFO = "CallsForExternalDebugInfo"
|
|
828
|
+
CALLS_FOR_PREPROCESSING = "CallsForPreprocessing"
|
|
829
|
+
CACHE_HITS = "CacheHits"
|
|
830
|
+
CACHE_MISSES = "CacheMisses"
|
|
831
|
+
EVICTED_MISSES = "EvictedMisses"
|
|
832
|
+
HEADER_CHANGED_MISSES = "HeaderChangedMisses"
|
|
833
|
+
SOURCE_CHANGED_MISSES = "SourceChangedMisses"
|
|
834
|
+
CACHE_ENTRIES = "CacheEntries"
|
|
835
|
+
CACHE_SIZE = "CacheSize"
|
|
836
|
+
|
|
837
|
+
RESETTABLE_KEYS = {
|
|
838
|
+
CALLS_WITH_INVALID_ARGUMENT,
|
|
839
|
+
CALLS_WITHOUT_SOURCE_FILE,
|
|
840
|
+
CALLS_WITH_MULTIPLE_SOURCE_FILES,
|
|
841
|
+
CALLS_WITH_PCH,
|
|
842
|
+
CALLS_FOR_LINKING,
|
|
843
|
+
CALLS_FOR_EXTERNAL_DEBUG_INFO,
|
|
844
|
+
CALLS_FOR_PREPROCESSING,
|
|
845
|
+
CACHE_HITS,
|
|
846
|
+
CACHE_MISSES,
|
|
847
|
+
EVICTED_MISSES,
|
|
848
|
+
HEADER_CHANGED_MISSES,
|
|
849
|
+
SOURCE_CHANGED_MISSES,
|
|
850
|
+
}
|
|
851
|
+
NON_RESETTABLE_KEYS = {
|
|
852
|
+
CACHE_ENTRIES,
|
|
853
|
+
CACHE_SIZE,
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
def __init__(self, statsFile):
|
|
857
|
+
self._statsFile = statsFile
|
|
858
|
+
|
|
859
|
+
global stats
|
|
860
|
+
if stats is None:
|
|
861
|
+
stats = PersistentJSONDict(self._statsFile)
|
|
862
|
+
|
|
863
|
+
self._stats = stats
|
|
864
|
+
|
|
865
|
+
def __enter__(self):
|
|
866
|
+
for k in Statistics.RESETTABLE_KEYS | Statistics.NON_RESETTABLE_KEYS:
|
|
867
|
+
if k not in self._stats:
|
|
868
|
+
self._stats[k] = 0
|
|
869
|
+
return self
|
|
870
|
+
|
|
871
|
+
def __exit__(self, typ, value, traceback):
|
|
872
|
+
# Does not write to disc when unchanged
|
|
873
|
+
# Nuitka: Only write at the end.
|
|
874
|
+
# self._stats.save()
|
|
875
|
+
pass
|
|
876
|
+
|
|
877
|
+
def __eq__(self, other):
|
|
878
|
+
return type(self) is type(other) and self.__dict__ == other.__dict__
|
|
879
|
+
|
|
880
|
+
def numCallsWithInvalidArgument(self):
|
|
881
|
+
return self._stats[Statistics.CALLS_WITH_INVALID_ARGUMENT]
|
|
882
|
+
|
|
883
|
+
def registerCallWithInvalidArgument(self):
|
|
884
|
+
self._stats[Statistics.CALLS_WITH_INVALID_ARGUMENT] += 1
|
|
885
|
+
|
|
886
|
+
def numCallsWithoutSourceFile(self):
|
|
887
|
+
return self._stats[Statistics.CALLS_WITHOUT_SOURCE_FILE]
|
|
888
|
+
|
|
889
|
+
def registerCallWithoutSourceFile(self):
|
|
890
|
+
self._stats[Statistics.CALLS_WITHOUT_SOURCE_FILE] += 1
|
|
891
|
+
|
|
892
|
+
def numCallsWithMultipleSourceFiles(self):
|
|
893
|
+
return self._stats[Statistics.CALLS_WITH_MULTIPLE_SOURCE_FILES]
|
|
894
|
+
|
|
895
|
+
def registerCallWithMultipleSourceFiles(self):
|
|
896
|
+
self._stats[Statistics.CALLS_WITH_MULTIPLE_SOURCE_FILES] += 1
|
|
897
|
+
|
|
898
|
+
def numCallsWithPch(self):
|
|
899
|
+
return self._stats[Statistics.CALLS_WITH_PCH]
|
|
900
|
+
|
|
901
|
+
def registerCallWithPch(self):
|
|
902
|
+
self._stats[Statistics.CALLS_WITH_PCH] += 1
|
|
903
|
+
|
|
904
|
+
def numCallsForLinking(self):
|
|
905
|
+
return self._stats[Statistics.CALLS_FOR_LINKING]
|
|
906
|
+
|
|
907
|
+
def registerCallForLinking(self):
|
|
908
|
+
self._stats[Statistics.CALLS_FOR_LINKING] += 1
|
|
909
|
+
|
|
910
|
+
def numCallsForExternalDebugInfo(self):
|
|
911
|
+
return self._stats[Statistics.CALLS_FOR_EXTERNAL_DEBUG_INFO]
|
|
912
|
+
|
|
913
|
+
def registerCallForExternalDebugInfo(self):
|
|
914
|
+
self._stats[Statistics.CALLS_FOR_EXTERNAL_DEBUG_INFO] += 1
|
|
915
|
+
|
|
916
|
+
def numEvictedMisses(self):
|
|
917
|
+
return self._stats[Statistics.EVICTED_MISSES]
|
|
918
|
+
|
|
919
|
+
def registerEvictedMiss(self):
|
|
920
|
+
self.registerCacheMiss()
|
|
921
|
+
self._stats[Statistics.EVICTED_MISSES] += 1
|
|
922
|
+
|
|
923
|
+
def numHeaderChangedMisses(self):
|
|
924
|
+
return self._stats[Statistics.HEADER_CHANGED_MISSES]
|
|
925
|
+
|
|
926
|
+
def registerHeaderChangedMiss(self):
|
|
927
|
+
self.registerCacheMiss()
|
|
928
|
+
self._stats[Statistics.HEADER_CHANGED_MISSES] += 1
|
|
929
|
+
|
|
930
|
+
def numSourceChangedMisses(self):
|
|
931
|
+
return self._stats[Statistics.SOURCE_CHANGED_MISSES]
|
|
932
|
+
|
|
933
|
+
def registerSourceChangedMiss(self):
|
|
934
|
+
self.registerCacheMiss()
|
|
935
|
+
self._stats[Statistics.SOURCE_CHANGED_MISSES] += 1
|
|
936
|
+
|
|
937
|
+
def numCacheEntries(self):
|
|
938
|
+
return self._stats[Statistics.CACHE_ENTRIES]
|
|
939
|
+
|
|
940
|
+
def setNumCacheEntries(self, number):
|
|
941
|
+
self._stats[Statistics.CACHE_ENTRIES] = number
|
|
942
|
+
|
|
943
|
+
def registerCacheEntry(self, size):
|
|
944
|
+
self._stats[Statistics.CACHE_ENTRIES] += 1
|
|
945
|
+
self._stats[Statistics.CACHE_SIZE] += size
|
|
946
|
+
|
|
947
|
+
def unregisterCacheEntry(self, size):
|
|
948
|
+
self._stats[Statistics.CACHE_ENTRIES] -= 1
|
|
949
|
+
self._stats[Statistics.CACHE_SIZE] -= size
|
|
950
|
+
|
|
951
|
+
def currentCacheSize(self):
|
|
952
|
+
return self._stats[Statistics.CACHE_SIZE]
|
|
953
|
+
|
|
954
|
+
def setCacheSize(self, size):
|
|
955
|
+
self._stats[Statistics.CACHE_SIZE] = size
|
|
956
|
+
|
|
957
|
+
def numCacheHits(self):
|
|
958
|
+
return self._stats[Statistics.CACHE_HITS]
|
|
959
|
+
|
|
960
|
+
def registerCacheHit(self):
|
|
961
|
+
self._stats[Statistics.CACHE_HITS] += 1
|
|
962
|
+
|
|
963
|
+
def numCacheMisses(self):
|
|
964
|
+
return self._stats[Statistics.CACHE_MISSES]
|
|
965
|
+
|
|
966
|
+
def registerCacheMiss(self):
|
|
967
|
+
self._stats[Statistics.CACHE_MISSES] += 1
|
|
968
|
+
|
|
969
|
+
def numCallsForPreprocessing(self):
|
|
970
|
+
return self._stats[Statistics.CALLS_FOR_PREPROCESSING]
|
|
971
|
+
|
|
972
|
+
def registerCallForPreprocessing(self):
|
|
973
|
+
self._stats[Statistics.CALLS_FOR_PREPROCESSING] += 1
|
|
974
|
+
|
|
975
|
+
def resetCounters(self):
|
|
976
|
+
for k in Statistics.RESETTABLE_KEYS:
|
|
977
|
+
self._stats[k] = 0
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
class AnalysisError(Exception):
|
|
981
|
+
pass
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
class NoSourceFileError(AnalysisError):
|
|
985
|
+
pass
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
class MultipleSourceFilesComplexError(AnalysisError):
|
|
989
|
+
pass
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
class CalledForLinkError(AnalysisError):
|
|
993
|
+
pass
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
class CalledWithPchError(AnalysisError):
|
|
997
|
+
pass
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
class ExternalDebugInfoError(AnalysisError):
|
|
1001
|
+
pass
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
class CalledForPreprocessingError(AnalysisError):
|
|
1005
|
+
pass
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
class InvalidArgumentError(AnalysisError):
|
|
1009
|
+
pass
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
def getCompilerHash(compilerBinary):
|
|
1013
|
+
stat = os.stat(compilerBinary)
|
|
1014
|
+
data = "|".join(
|
|
1015
|
+
[
|
|
1016
|
+
str(stat.st_mtime),
|
|
1017
|
+
str(stat.st_size),
|
|
1018
|
+
VERSION,
|
|
1019
|
+
]
|
|
1020
|
+
)
|
|
1021
|
+
hasher = HashAlgorithm()
|
|
1022
|
+
hasher.update(data.encode("UTF-8"))
|
|
1023
|
+
return hasher.hexdigest()
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
def getFileHashes(filePaths):
|
|
1027
|
+
if "CLCACHE_SERVER" in os.environ:
|
|
1028
|
+
pipeName = r"\\.\pipe\clcache_srv"
|
|
1029
|
+
while True:
|
|
1030
|
+
try:
|
|
1031
|
+
with open(pipeName, "w+b") as f:
|
|
1032
|
+
f.write("\n".join(filePaths).encode("utf8"))
|
|
1033
|
+
f.write(b"\x00")
|
|
1034
|
+
response = f.read()
|
|
1035
|
+
if response.startswith(b"!"):
|
|
1036
|
+
raise pickle.loads(response[1:-1])
|
|
1037
|
+
return response[:-1].decode("utf8").splitlines()
|
|
1038
|
+
except OSError as e:
|
|
1039
|
+
if (
|
|
1040
|
+
e.errno == errno.EINVAL
|
|
1041
|
+
and windll.kernel32.GetLastError() == ERROR_PIPE_BUSY
|
|
1042
|
+
):
|
|
1043
|
+
windll.kernel32.WaitNamedPipeW(pipeName, NMPWAIT_WAIT_FOREVER)
|
|
1044
|
+
else:
|
|
1045
|
+
raise
|
|
1046
|
+
else:
|
|
1047
|
+
return [getFileHash(filePath) for filePath in filePaths]
|
|
1048
|
+
|
|
1049
|
+
|
|
1050
|
+
_hash_cache = {}
|
|
1051
|
+
|
|
1052
|
+
def getFileHash(filePath, additionalData=None):
|
|
1053
|
+
key = (filePath, additionalData)
|
|
1054
|
+
|
|
1055
|
+
if key in _hash_cache:
|
|
1056
|
+
return _hash_cache[key]
|
|
1057
|
+
|
|
1058
|
+
hasher = HashAlgorithm()
|
|
1059
|
+
with open(filePath, "rb") as inFile:
|
|
1060
|
+
hasher.update(inFile.read())
|
|
1061
|
+
if additionalData is not None:
|
|
1062
|
+
# Encoding of this additional data does not really matter
|
|
1063
|
+
# as long as we keep it fixed, otherwise hashes change.
|
|
1064
|
+
# The string should fit into ASCII, so UTF8 should not change anything
|
|
1065
|
+
hasher.update(additionalData.encode("UTF-8"))
|
|
1066
|
+
|
|
1067
|
+
_hash_cache[key] = hasher.hexdigest()
|
|
1068
|
+
return _hash_cache[key]
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
def getStringHash(dataString):
|
|
1072
|
+
hasher = HashAlgorithm()
|
|
1073
|
+
hasher.update(dataString.encode("UTF-8"))
|
|
1074
|
+
return hasher.hexdigest()
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
def expandBasedirPlaceholder(path):
|
|
1078
|
+
baseDir = normalizeBaseDir(os.environ.get("CLCACHE_BASEDIR"))
|
|
1079
|
+
if path.startswith(BASEDIR_REPLACEMENT):
|
|
1080
|
+
if not baseDir:
|
|
1081
|
+
print(
|
|
1082
|
+
"No CLCACHE_BASEDIR set, but found relative path " + path,
|
|
1083
|
+
file=sys.stderr,
|
|
1084
|
+
)
|
|
1085
|
+
sys.exit(1)
|
|
1086
|
+
return path.replace(BASEDIR_REPLACEMENT, baseDir, 1)
|
|
1087
|
+
else:
|
|
1088
|
+
return path
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
def collapseBasedirToPlaceholder(path):
|
|
1092
|
+
baseDir = normalizeBaseDir(os.environ.get("CLCACHE_BASEDIR"))
|
|
1093
|
+
if baseDir is None:
|
|
1094
|
+
return path
|
|
1095
|
+
else:
|
|
1096
|
+
assert path == os.path.normcase(path)
|
|
1097
|
+
assert baseDir == os.path.normcase(baseDir)
|
|
1098
|
+
if path.startswith(baseDir):
|
|
1099
|
+
return path.replace(baseDir, BASEDIR_REPLACEMENT, 1)
|
|
1100
|
+
else:
|
|
1101
|
+
return path
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
def ensureDirectoryExists(path):
|
|
1105
|
+
try:
|
|
1106
|
+
os.makedirs(path)
|
|
1107
|
+
except OSError as e:
|
|
1108
|
+
if e.errno != errno.EEXIST:
|
|
1109
|
+
raise
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
def copyOrLink(srcFilePath, dstFilePath, writeCache=False):
|
|
1113
|
+
ensureDirectoryExists(os.path.dirname(os.path.abspath(dstFilePath)))
|
|
1114
|
+
|
|
1115
|
+
if "CLCACHE_HARDLINK" in os.environ:
|
|
1116
|
+
ret = windll.kernel32.CreateHardLinkW(str(dstFilePath), str(srcFilePath), None)
|
|
1117
|
+
if ret != 0:
|
|
1118
|
+
# Touch the time stamp of the new link so that the build system
|
|
1119
|
+
# doesn't confused by a potentially old time on the file. The
|
|
1120
|
+
# hard link gets the same timestamp as the cached file.
|
|
1121
|
+
# Note that touching the time stamp of the link also touches
|
|
1122
|
+
# the time stamp on the cache (and hence on all over hard
|
|
1123
|
+
# links). This shouldn't be a problem though.
|
|
1124
|
+
os.utime(dstFilePath, None)
|
|
1125
|
+
return
|
|
1126
|
+
|
|
1127
|
+
# If hardlinking fails for some reason (or it's not enabled), just
|
|
1128
|
+
# fall back to moving bytes around. Always to a temporary path first to
|
|
1129
|
+
# lower the chances of corrupting it.
|
|
1130
|
+
tempDst = dstFilePath + ".tmp"
|
|
1131
|
+
|
|
1132
|
+
if "CLCACHE_COMPRESS" in os.environ:
|
|
1133
|
+
if "CLCACHE_COMPRESSLEVEL" in os.environ:
|
|
1134
|
+
compress = int(os.environ["CLCACHE_COMPRESSLEVEL"])
|
|
1135
|
+
else:
|
|
1136
|
+
compress = 6
|
|
1137
|
+
|
|
1138
|
+
if writeCache is True:
|
|
1139
|
+
with open(srcFilePath, "rb") as fileIn, gzip.open(
|
|
1140
|
+
tempDst, "wb", compress
|
|
1141
|
+
) as fileOut:
|
|
1142
|
+
copyfileobj(fileIn, fileOut)
|
|
1143
|
+
else:
|
|
1144
|
+
with gzip.open(srcFilePath, "rb", compress) as fileIn, open(
|
|
1145
|
+
tempDst, "wb"
|
|
1146
|
+
) as fileOut:
|
|
1147
|
+
copyfileobj(fileIn, fileOut)
|
|
1148
|
+
else:
|
|
1149
|
+
copyfile(srcFilePath, tempDst)
|
|
1150
|
+
os.replace(tempDst, dstFilePath)
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
def printTraceStatement(msg):
|
|
1154
|
+
if "CLCACHE_LOG" in os.environ:
|
|
1155
|
+
scriptDir = os.path.realpath(os.path.dirname(sys.argv[0]))
|
|
1156
|
+
with OUTPUT_LOCK:
|
|
1157
|
+
print(os.path.join(scriptDir, "clcache.py") + " " + msg)
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
class CommandLineTokenizer(object):
|
|
1161
|
+
def __init__(self, content):
|
|
1162
|
+
self.argv = []
|
|
1163
|
+
self._content = content
|
|
1164
|
+
self._pos = 0
|
|
1165
|
+
self._token = ""
|
|
1166
|
+
self._parser = self._initialState
|
|
1167
|
+
|
|
1168
|
+
while self._pos < len(self._content):
|
|
1169
|
+
self._parser = self._parser(self._content[self._pos])
|
|
1170
|
+
self._pos += 1
|
|
1171
|
+
|
|
1172
|
+
if self._token:
|
|
1173
|
+
self.argv.append(self._token)
|
|
1174
|
+
|
|
1175
|
+
def _initialState(self, currentChar):
|
|
1176
|
+
if currentChar.isspace():
|
|
1177
|
+
return self._initialState
|
|
1178
|
+
|
|
1179
|
+
if currentChar == '"':
|
|
1180
|
+
return self._quotedState
|
|
1181
|
+
|
|
1182
|
+
if currentChar == "\\":
|
|
1183
|
+
self._parseBackslash()
|
|
1184
|
+
return self._unquotedState
|
|
1185
|
+
|
|
1186
|
+
self._token += currentChar
|
|
1187
|
+
return self._unquotedState
|
|
1188
|
+
|
|
1189
|
+
def _unquotedState(self, currentChar):
|
|
1190
|
+
if currentChar.isspace():
|
|
1191
|
+
self.argv.append(self._token)
|
|
1192
|
+
self._token = ""
|
|
1193
|
+
return self._initialState
|
|
1194
|
+
|
|
1195
|
+
if currentChar == '"':
|
|
1196
|
+
return self._quotedState
|
|
1197
|
+
|
|
1198
|
+
if currentChar == "\\":
|
|
1199
|
+
self._parseBackslash()
|
|
1200
|
+
return self._unquotedState
|
|
1201
|
+
|
|
1202
|
+
self._token += currentChar
|
|
1203
|
+
return self._unquotedState
|
|
1204
|
+
|
|
1205
|
+
def _quotedState(self, currentChar):
|
|
1206
|
+
if currentChar == '"':
|
|
1207
|
+
return self._unquotedState
|
|
1208
|
+
|
|
1209
|
+
if currentChar == "\\":
|
|
1210
|
+
self._parseBackslash()
|
|
1211
|
+
return self._quotedState
|
|
1212
|
+
|
|
1213
|
+
self._token += currentChar
|
|
1214
|
+
return self._quotedState
|
|
1215
|
+
|
|
1216
|
+
def _parseBackslash(self):
|
|
1217
|
+
numBackslashes = 0
|
|
1218
|
+
while self._pos < len(self._content) and self._content[self._pos] == "\\":
|
|
1219
|
+
self._pos += 1
|
|
1220
|
+
numBackslashes += 1
|
|
1221
|
+
|
|
1222
|
+
followedByDoubleQuote = (
|
|
1223
|
+
self._pos < len(self._content) and self._content[self._pos] == '"'
|
|
1224
|
+
)
|
|
1225
|
+
if followedByDoubleQuote:
|
|
1226
|
+
self._token += "\\" * (numBackslashes // 2)
|
|
1227
|
+
if numBackslashes % 2 == 0:
|
|
1228
|
+
self._pos -= 1
|
|
1229
|
+
else:
|
|
1230
|
+
self._token += '"'
|
|
1231
|
+
else:
|
|
1232
|
+
self._token += "\\" * numBackslashes
|
|
1233
|
+
self._pos -= 1
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
def splitCommandsFile(content):
|
|
1237
|
+
return CommandLineTokenizer(content).argv
|
|
1238
|
+
|
|
1239
|
+
|
|
1240
|
+
def expandCommandLine(cmdline):
|
|
1241
|
+
ret = []
|
|
1242
|
+
|
|
1243
|
+
for arg in cmdline:
|
|
1244
|
+
if arg[0] == "@":
|
|
1245
|
+
includeFile = arg[1:]
|
|
1246
|
+
with open(includeFile, "rb") as f:
|
|
1247
|
+
rawBytes = f.read()
|
|
1248
|
+
|
|
1249
|
+
encoding = None
|
|
1250
|
+
|
|
1251
|
+
bomToEncoding = {
|
|
1252
|
+
codecs.BOM_UTF32_BE: "utf-32-be",
|
|
1253
|
+
codecs.BOM_UTF32_LE: "utf-32-le",
|
|
1254
|
+
codecs.BOM_UTF16_BE: "utf-16-be",
|
|
1255
|
+
codecs.BOM_UTF16_LE: "utf-16-le",
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
for bom, enc in bomToEncoding.items():
|
|
1259
|
+
if rawBytes.startswith(bom):
|
|
1260
|
+
encoding = enc
|
|
1261
|
+
rawBytes = rawBytes[len(bom) :]
|
|
1262
|
+
break
|
|
1263
|
+
|
|
1264
|
+
if encoding:
|
|
1265
|
+
includeFileContents = rawBytes.decode(encoding)
|
|
1266
|
+
else:
|
|
1267
|
+
includeFileContents = rawBytes.decode("UTF-8")
|
|
1268
|
+
|
|
1269
|
+
ret.extend(
|
|
1270
|
+
expandCommandLine(splitCommandsFile(includeFileContents.strip()))
|
|
1271
|
+
)
|
|
1272
|
+
else:
|
|
1273
|
+
ret.append(arg)
|
|
1274
|
+
|
|
1275
|
+
return ret
|
|
1276
|
+
|
|
1277
|
+
|
|
1278
|
+
def extendCommandLineFromEnvironment(cmdLine, environment):
|
|
1279
|
+
remainingEnvironment = environment.copy()
|
|
1280
|
+
|
|
1281
|
+
prependCmdLineString = remainingEnvironment.pop("CL", None)
|
|
1282
|
+
if prependCmdLineString is not None:
|
|
1283
|
+
cmdLine = splitCommandsFile(prependCmdLineString.strip()) + cmdLine
|
|
1284
|
+
|
|
1285
|
+
appendCmdLineString = remainingEnvironment.pop("_CL_", None)
|
|
1286
|
+
if appendCmdLineString is not None:
|
|
1287
|
+
cmdLine = cmdLine + splitCommandsFile(appendCmdLineString.strip())
|
|
1288
|
+
|
|
1289
|
+
return cmdLine, remainingEnvironment
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
class Argument(object):
|
|
1293
|
+
def __init__(self, name):
|
|
1294
|
+
self.name = name
|
|
1295
|
+
|
|
1296
|
+
def __len__(self):
|
|
1297
|
+
return len(self.name)
|
|
1298
|
+
|
|
1299
|
+
def __str__(self):
|
|
1300
|
+
return "/" + self.name
|
|
1301
|
+
|
|
1302
|
+
def __eq__(self, other):
|
|
1303
|
+
return type(self) == type(other) and self.name == other.name
|
|
1304
|
+
|
|
1305
|
+
def __hash__(self):
|
|
1306
|
+
key = (type(self), self.name)
|
|
1307
|
+
return hash(key)
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
# /NAMEparameter (no space, required parameter).
|
|
1311
|
+
class ArgumentT1(Argument):
|
|
1312
|
+
pass
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
# /NAME[parameter] (no space, optional parameter)
|
|
1316
|
+
class ArgumentT2(Argument):
|
|
1317
|
+
pass
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
# /NAME[ ]parameter (optional space)
|
|
1321
|
+
class ArgumentT3(Argument):
|
|
1322
|
+
pass
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
# /NAME parameter (required space)
|
|
1326
|
+
class ArgumentT4(Argument):
|
|
1327
|
+
pass
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
class CommandLineAnalyzer(object):
|
|
1331
|
+
argumentsWithParameter = {
|
|
1332
|
+
# /NAMEparameter
|
|
1333
|
+
ArgumentT1("Ob"),
|
|
1334
|
+
ArgumentT1("Yl"),
|
|
1335
|
+
ArgumentT1("Zm"),
|
|
1336
|
+
# /NAME[parameter]
|
|
1337
|
+
ArgumentT2("doc"),
|
|
1338
|
+
ArgumentT2("FA"),
|
|
1339
|
+
ArgumentT2("FR"),
|
|
1340
|
+
ArgumentT2("Fr"),
|
|
1341
|
+
ArgumentT2("Gs"),
|
|
1342
|
+
ArgumentT2("MP"),
|
|
1343
|
+
ArgumentT2("Yc"),
|
|
1344
|
+
ArgumentT2("Yu"),
|
|
1345
|
+
ArgumentT2("Zp"),
|
|
1346
|
+
ArgumentT2("Fa"),
|
|
1347
|
+
ArgumentT2("Fd"),
|
|
1348
|
+
ArgumentT2("Fe"),
|
|
1349
|
+
ArgumentT2("Fi"),
|
|
1350
|
+
ArgumentT2("Fm"),
|
|
1351
|
+
ArgumentT2("Fo"),
|
|
1352
|
+
ArgumentT2("Fp"),
|
|
1353
|
+
ArgumentT2("Wv"),
|
|
1354
|
+
# /NAME[ ]parameter
|
|
1355
|
+
ArgumentT3("AI"),
|
|
1356
|
+
ArgumentT3("D"),
|
|
1357
|
+
ArgumentT3("Tc"),
|
|
1358
|
+
ArgumentT3("Tp"),
|
|
1359
|
+
ArgumentT3("FI"),
|
|
1360
|
+
ArgumentT3("U"),
|
|
1361
|
+
ArgumentT3("I"),
|
|
1362
|
+
ArgumentT3("F"),
|
|
1363
|
+
ArgumentT3("FU"),
|
|
1364
|
+
ArgumentT3("w1"),
|
|
1365
|
+
ArgumentT3("w2"),
|
|
1366
|
+
ArgumentT3("w3"),
|
|
1367
|
+
ArgumentT3("w4"),
|
|
1368
|
+
ArgumentT3("wd"),
|
|
1369
|
+
ArgumentT3("we"),
|
|
1370
|
+
ArgumentT3("wo"),
|
|
1371
|
+
ArgumentT3("V"),
|
|
1372
|
+
ArgumentT3("imsvc"),
|
|
1373
|
+
# /NAME parameter
|
|
1374
|
+
ArgumentT4("Xclang"),
|
|
1375
|
+
}
|
|
1376
|
+
argumentsWithParameterSorted = sorted(argumentsWithParameter, key=len, reverse=True)
|
|
1377
|
+
|
|
1378
|
+
@staticmethod
|
|
1379
|
+
def _getParameterizedArgumentType(cmdLineArgument):
|
|
1380
|
+
# Sort by length to handle prefixes
|
|
1381
|
+
for arg in CommandLineAnalyzer.argumentsWithParameterSorted:
|
|
1382
|
+
if cmdLineArgument.startswith(arg.name, 1):
|
|
1383
|
+
return arg
|
|
1384
|
+
return None
|
|
1385
|
+
|
|
1386
|
+
@staticmethod
|
|
1387
|
+
def parseArgumentsAndInputFiles(cmdline):
|
|
1388
|
+
arguments = defaultdict(list)
|
|
1389
|
+
inputFiles = []
|
|
1390
|
+
i = 0
|
|
1391
|
+
while i < len(cmdline):
|
|
1392
|
+
cmdLineArgument = cmdline[i]
|
|
1393
|
+
|
|
1394
|
+
# Plain arguments starting with / or -
|
|
1395
|
+
if cmdLineArgument.startswith("/") or cmdLineArgument.startswith("-"):
|
|
1396
|
+
arg = CommandLineAnalyzer._getParameterizedArgumentType(cmdLineArgument)
|
|
1397
|
+
if arg is not None:
|
|
1398
|
+
if isinstance(arg, ArgumentT1):
|
|
1399
|
+
value = cmdLineArgument[len(arg) + 1 :]
|
|
1400
|
+
if not value:
|
|
1401
|
+
raise InvalidArgumentError(
|
|
1402
|
+
"Parameter for {} must not be empty".format(arg)
|
|
1403
|
+
)
|
|
1404
|
+
elif isinstance(arg, ArgumentT2):
|
|
1405
|
+
value = cmdLineArgument[len(arg) + 1 :]
|
|
1406
|
+
elif isinstance(arg, ArgumentT3):
|
|
1407
|
+
value = cmdLineArgument[len(arg) + 1 :]
|
|
1408
|
+
if not value:
|
|
1409
|
+
value = cmdline[i + 1]
|
|
1410
|
+
i += 1
|
|
1411
|
+
elif isinstance(arg, ArgumentT4):
|
|
1412
|
+
value = cmdline[i + 1]
|
|
1413
|
+
i += 1
|
|
1414
|
+
else:
|
|
1415
|
+
raise AssertionError("Unsupported argument type.")
|
|
1416
|
+
|
|
1417
|
+
arguments[arg.name].append(value)
|
|
1418
|
+
else:
|
|
1419
|
+
argumentName = cmdLineArgument[
|
|
1420
|
+
1:
|
|
1421
|
+
] # name not followed by parameter in this case
|
|
1422
|
+
arguments[argumentName].append("")
|
|
1423
|
+
|
|
1424
|
+
# Response file
|
|
1425
|
+
elif cmdLineArgument[0] == "@":
|
|
1426
|
+
raise AssertionError(
|
|
1427
|
+
"No response file arguments (starting with @) must be left here."
|
|
1428
|
+
)
|
|
1429
|
+
|
|
1430
|
+
# Source file arguments
|
|
1431
|
+
else:
|
|
1432
|
+
inputFiles.append(cmdLineArgument)
|
|
1433
|
+
|
|
1434
|
+
i += 1
|
|
1435
|
+
|
|
1436
|
+
return dict(arguments), inputFiles
|
|
1437
|
+
|
|
1438
|
+
@staticmethod
|
|
1439
|
+
def analyze(cmdline):
|
|
1440
|
+
options, inputFiles = CommandLineAnalyzer.parseArgumentsAndInputFiles(cmdline)
|
|
1441
|
+
# Use an override pattern to shadow input files that have
|
|
1442
|
+
# already been specified in the function above
|
|
1443
|
+
inputFiles = {inputFile: "" for inputFile in inputFiles}
|
|
1444
|
+
compl = False
|
|
1445
|
+
if "Tp" in options:
|
|
1446
|
+
inputFiles.update({inputFile: "/Tp" for inputFile in options["Tp"]})
|
|
1447
|
+
compl = True
|
|
1448
|
+
if "Tc" in options:
|
|
1449
|
+
inputFiles.update({inputFile: "/Tc" for inputFile in options["Tc"]})
|
|
1450
|
+
compl = True
|
|
1451
|
+
|
|
1452
|
+
# Now collect the inputFiles into the return format
|
|
1453
|
+
inputFiles = list(inputFiles.items())
|
|
1454
|
+
if not inputFiles:
|
|
1455
|
+
raise NoSourceFileError()
|
|
1456
|
+
|
|
1457
|
+
for opt in ["E", "EP", "P"]:
|
|
1458
|
+
if opt in options:
|
|
1459
|
+
raise CalledForPreprocessingError()
|
|
1460
|
+
|
|
1461
|
+
# Technically, it would be possible to support /Zi: we'd just need to
|
|
1462
|
+
# copy the generated .pdb files into/out of the cache.
|
|
1463
|
+
if "Zi" in options:
|
|
1464
|
+
raise ExternalDebugInfoError()
|
|
1465
|
+
|
|
1466
|
+
if "Yc" in options or "Yu" in options:
|
|
1467
|
+
raise CalledWithPchError()
|
|
1468
|
+
|
|
1469
|
+
if "link" in options or "c" not in options:
|
|
1470
|
+
raise CalledForLinkError()
|
|
1471
|
+
|
|
1472
|
+
if len(inputFiles) > 1 and compl:
|
|
1473
|
+
raise MultipleSourceFilesComplexError()
|
|
1474
|
+
|
|
1475
|
+
objectFiles = None
|
|
1476
|
+
prefix = ""
|
|
1477
|
+
if "Fo" in options and options["Fo"][0]:
|
|
1478
|
+
# Handle user input
|
|
1479
|
+
tmp = os.path.normpath(options["Fo"][0])
|
|
1480
|
+
if os.path.isdir(tmp):
|
|
1481
|
+
prefix = tmp
|
|
1482
|
+
elif len(inputFiles) == 1:
|
|
1483
|
+
objectFiles = [tmp]
|
|
1484
|
+
if objectFiles is None:
|
|
1485
|
+
# Generate from .c/.cpp filenames
|
|
1486
|
+
objectFiles = [
|
|
1487
|
+
os.path.join(prefix, basenameWithoutExtension(f)) + ".obj"
|
|
1488
|
+
for f, _ in inputFiles
|
|
1489
|
+
]
|
|
1490
|
+
|
|
1491
|
+
printTraceStatement("Compiler source files: {}".format(inputFiles))
|
|
1492
|
+
printTraceStatement("Compiler object file: {}".format(objectFiles))
|
|
1493
|
+
return inputFiles, objectFiles
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
def invokeRealCompiler(
|
|
1497
|
+
compilerBinary, cmdLine, captureOutput=False, outputAsString=True, environment=None
|
|
1498
|
+
):
|
|
1499
|
+
realCmdline = [compilerBinary] + cmdLine
|
|
1500
|
+
printTraceStatement("Invoking real compiler as {}".format(realCmdline))
|
|
1501
|
+
|
|
1502
|
+
environment = environment or os.environ
|
|
1503
|
+
|
|
1504
|
+
# Environment variable set by the Visual Studio IDE to make cl.exe write
|
|
1505
|
+
# Unicode output to named pipes instead of stdout. Unset it to make sure
|
|
1506
|
+
# we can catch stdout output.
|
|
1507
|
+
environment.pop("VS_UNICODE_OUTPUT", None)
|
|
1508
|
+
|
|
1509
|
+
returnCode = None
|
|
1510
|
+
stdout = b""
|
|
1511
|
+
stderr = b""
|
|
1512
|
+
if captureOutput:
|
|
1513
|
+
# Don't use subprocess.communicate() here, it's slow due to internal
|
|
1514
|
+
# threading.
|
|
1515
|
+
with TemporaryFile() as stdoutFile, TemporaryFile() as stderrFile:
|
|
1516
|
+
compilerProcess = subprocess.Popen(
|
|
1517
|
+
realCmdline, stdout=stdoutFile, stderr=stderrFile, env=environment
|
|
1518
|
+
)
|
|
1519
|
+
returnCode = compilerProcess.wait()
|
|
1520
|
+
stdoutFile.seek(0)
|
|
1521
|
+
stdout = stdoutFile.read()
|
|
1522
|
+
stderrFile.seek(0)
|
|
1523
|
+
stderr = stderrFile.read()
|
|
1524
|
+
else:
|
|
1525
|
+
returnCode = subprocess.call(realCmdline, env=environment)
|
|
1526
|
+
|
|
1527
|
+
printTraceStatement("Real compiler returned code {0:d}".format(returnCode))
|
|
1528
|
+
|
|
1529
|
+
if outputAsString:
|
|
1530
|
+
stdoutString = stdout.decode(CL_DEFAULT_CODEC)
|
|
1531
|
+
stderrString = stderr.decode(CL_DEFAULT_CODEC)
|
|
1532
|
+
return returnCode, stdoutString, stderrString
|
|
1533
|
+
|
|
1534
|
+
return returnCode, stdout, stderr
|
|
1535
|
+
|
|
1536
|
+
|
|
1537
|
+
# Returns the amount of jobs which should be run in parallel when
|
|
1538
|
+
# invoked in batch mode as determined by the /MP argument
|
|
1539
|
+
def jobCount(cmdLine):
|
|
1540
|
+
mpSwitches = [arg for arg in cmdLine if re.match(r"^/MP(\d+)?$", arg)]
|
|
1541
|
+
if not mpSwitches:
|
|
1542
|
+
return 1
|
|
1543
|
+
|
|
1544
|
+
# the last instance of /MP takes precedence
|
|
1545
|
+
mpSwitch = mpSwitches.pop()
|
|
1546
|
+
|
|
1547
|
+
count = mpSwitch[3:]
|
|
1548
|
+
if count != "":
|
|
1549
|
+
return int(count)
|
|
1550
|
+
|
|
1551
|
+
# /MP, but no count specified; use CPU count
|
|
1552
|
+
try:
|
|
1553
|
+
return multiprocessing.cpu_count()
|
|
1554
|
+
except NotImplementedError:
|
|
1555
|
+
# not expected to happen
|
|
1556
|
+
return 2
|
|
1557
|
+
|
|
1558
|
+
|
|
1559
|
+
def printStatistics(cache):
|
|
1560
|
+
template = """
|
|
1561
|
+
clcache statistics:
|
|
1562
|
+
current cache dir : {}
|
|
1563
|
+
cache size : {:,} bytes
|
|
1564
|
+
maximum cache size : {:,} bytes
|
|
1565
|
+
cache entries : {}
|
|
1566
|
+
cache hits : {}
|
|
1567
|
+
cache misses
|
|
1568
|
+
total : {}
|
|
1569
|
+
evicted : {}
|
|
1570
|
+
header changed : {}
|
|
1571
|
+
source changed : {}
|
|
1572
|
+
passed to real compiler
|
|
1573
|
+
called w/ invalid argument : {}
|
|
1574
|
+
called for preprocessing : {}
|
|
1575
|
+
called for linking : {}
|
|
1576
|
+
called for external debug : {}
|
|
1577
|
+
called w/o source : {}
|
|
1578
|
+
called w/ multiple sources : {}
|
|
1579
|
+
called w/ PCH : {}""".strip()
|
|
1580
|
+
|
|
1581
|
+
with cache.statistics as stats, cache.configuration as cfg:
|
|
1582
|
+
print(
|
|
1583
|
+
template.format(
|
|
1584
|
+
str(cache),
|
|
1585
|
+
stats.currentCacheSize(),
|
|
1586
|
+
cfg.maximumCacheSize(),
|
|
1587
|
+
stats.numCacheEntries(),
|
|
1588
|
+
stats.numCacheHits(),
|
|
1589
|
+
stats.numCacheMisses(),
|
|
1590
|
+
stats.numEvictedMisses(),
|
|
1591
|
+
stats.numHeaderChangedMisses(),
|
|
1592
|
+
stats.numSourceChangedMisses(),
|
|
1593
|
+
stats.numCallsWithInvalidArgument(),
|
|
1594
|
+
stats.numCallsForPreprocessing(),
|
|
1595
|
+
stats.numCallsForLinking(),
|
|
1596
|
+
stats.numCallsForExternalDebugInfo(),
|
|
1597
|
+
stats.numCallsWithoutSourceFile(),
|
|
1598
|
+
stats.numCallsWithMultipleSourceFiles(),
|
|
1599
|
+
stats.numCallsWithPch(),
|
|
1600
|
+
)
|
|
1601
|
+
)
|
|
1602
|
+
|
|
1603
|
+
|
|
1604
|
+
def resetStatistics(cache):
|
|
1605
|
+
with cache.statistics as stats:
|
|
1606
|
+
stats.resetCounters()
|
|
1607
|
+
|
|
1608
|
+
|
|
1609
|
+
def cleanCache(cache):
|
|
1610
|
+
with cache.lock, cache.statistics as stats, cache.configuration as cfg:
|
|
1611
|
+
cache.clean(stats, cfg.maximumCacheSize())
|
|
1612
|
+
|
|
1613
|
+
|
|
1614
|
+
def clearCache(cache):
|
|
1615
|
+
with cache.lock, cache.statistics as stats:
|
|
1616
|
+
cache.clean(stats, 0)
|
|
1617
|
+
|
|
1618
|
+
|
|
1619
|
+
# Returns pair:
|
|
1620
|
+
# 1. set of include filepaths
|
|
1621
|
+
# 2. new compiler output
|
|
1622
|
+
# Output changes if strip is True in that case all lines with include
|
|
1623
|
+
# directives are stripped from it
|
|
1624
|
+
def parseIncludesSet(compilerOutput, sourceFile, strip):
|
|
1625
|
+
newOutput = []
|
|
1626
|
+
includesSet = set()
|
|
1627
|
+
|
|
1628
|
+
# Example lines
|
|
1629
|
+
# Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\limits.h
|
|
1630
|
+
# Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\iterator
|
|
1631
|
+
#
|
|
1632
|
+
# So we match
|
|
1633
|
+
# - one word (translation of "note")
|
|
1634
|
+
# - colon
|
|
1635
|
+
# - space
|
|
1636
|
+
# - a phrase containing characters and spaces (translation of "including file")
|
|
1637
|
+
# - colon
|
|
1638
|
+
# - one or more spaces
|
|
1639
|
+
# - the file path, starting with a non-whitespace character
|
|
1640
|
+
reFilePath = re.compile(r"^(\w+): ([ \w]+):( +)(?P<file_path>\S.*)$")
|
|
1641
|
+
|
|
1642
|
+
absSourceFile = os.path.normcase(os.path.abspath(sourceFile))
|
|
1643
|
+
for line in compilerOutput.splitlines(True):
|
|
1644
|
+
match = reFilePath.match(line.rstrip("\r\n"))
|
|
1645
|
+
if match is not None:
|
|
1646
|
+
filePath = match.group("file_path")
|
|
1647
|
+
filePath = os.path.normcase(os.path.abspath(filePath))
|
|
1648
|
+
if filePath != absSourceFile:
|
|
1649
|
+
includesSet.add(filePath)
|
|
1650
|
+
elif strip:
|
|
1651
|
+
newOutput.append(line)
|
|
1652
|
+
if strip:
|
|
1653
|
+
return includesSet, "".join(newOutput)
|
|
1654
|
+
else:
|
|
1655
|
+
return includesSet, compilerOutput
|
|
1656
|
+
|
|
1657
|
+
|
|
1658
|
+
def addObjectToCache(stats, cache, cachekey, artifacts):
|
|
1659
|
+
# This function asserts that the caller locked 'section' and 'stats'
|
|
1660
|
+
# already and also saves them
|
|
1661
|
+
printTraceStatement(
|
|
1662
|
+
"Adding file {} to cache using key {}".format(
|
|
1663
|
+
artifacts.objectFilePath, cachekey
|
|
1664
|
+
)
|
|
1665
|
+
)
|
|
1666
|
+
|
|
1667
|
+
size = cache.setEntry(cachekey, artifacts)
|
|
1668
|
+
if size is None:
|
|
1669
|
+
size = os.path.getsize(artifacts.objectFilePath)
|
|
1670
|
+
stats.registerCacheEntry(size)
|
|
1671
|
+
|
|
1672
|
+
with cache.configuration as cfg:
|
|
1673
|
+
return stats.currentCacheSize() >= cfg.maximumCacheSize()
|
|
1674
|
+
|
|
1675
|
+
|
|
1676
|
+
def processCacheHit(cache, objectFile, cachekey):
|
|
1677
|
+
printTraceStatement(
|
|
1678
|
+
"Reusing cached object for key {} for object file {}".format(
|
|
1679
|
+
cachekey, objectFile
|
|
1680
|
+
)
|
|
1681
|
+
)
|
|
1682
|
+
|
|
1683
|
+
with cache.lockFor(cachekey):
|
|
1684
|
+
with cache.statistics as stats:
|
|
1685
|
+
stats.registerCacheHit()
|
|
1686
|
+
|
|
1687
|
+
if os.path.exists(objectFile):
|
|
1688
|
+
os.remove(objectFile)
|
|
1689
|
+
|
|
1690
|
+
cachedArtifacts = cache.getEntry(cachekey)
|
|
1691
|
+
copyOrLink(cachedArtifacts.objectFilePath, objectFile)
|
|
1692
|
+
printTraceStatement("Finished. Exit code 0")
|
|
1693
|
+
return 0, cachedArtifacts.stdout, cachedArtifacts.stderr, False
|
|
1694
|
+
|
|
1695
|
+
|
|
1696
|
+
def createManifestEntry(manifestHash, includePaths):
|
|
1697
|
+
sortedIncludePaths = sorted(set(includePaths))
|
|
1698
|
+
includeHashes = getFileHashes(sortedIncludePaths)
|
|
1699
|
+
|
|
1700
|
+
safeIncludes = [collapseBasedirToPlaceholder(path) for path in sortedIncludePaths]
|
|
1701
|
+
includesContentHash = ManifestRepository.getIncludesContentHashForHashes(
|
|
1702
|
+
includeHashes
|
|
1703
|
+
)
|
|
1704
|
+
cachekey = CompilerArtifactsRepository.computeKeyDirect(
|
|
1705
|
+
manifestHash, includesContentHash
|
|
1706
|
+
)
|
|
1707
|
+
|
|
1708
|
+
return ManifestEntry(safeIncludes, includesContentHash, cachekey)
|
|
1709
|
+
|
|
1710
|
+
|
|
1711
|
+
def run(cache, compiler, compiler_args, env):
|
|
1712
|
+
printTraceStatement("Found real compiler binary at '{0!s}'".format(compiler))
|
|
1713
|
+
|
|
1714
|
+
if "CLCACHE_DISABLE" in os.environ:
|
|
1715
|
+
exit_code, out, err = invokeRealCompiler(compiler, compiler_args, env)
|
|
1716
|
+
return exit_code, [out], [err]
|
|
1717
|
+
else:
|
|
1718
|
+
return processCompileRequest(cache, compiler, compiler_args, env)
|
|
1719
|
+
|
|
1720
|
+
|
|
1721
|
+
cache = None
|
|
1722
|
+
|
|
1723
|
+
|
|
1724
|
+
def runClCache(compiler, compiler_args, env):
|
|
1725
|
+
""" Entry point, designed to be used by external tools like Nuitka's scons. """
|
|
1726
|
+
global cache # This is a singleton if this is called multiple times, pylint: disable=global-statement
|
|
1727
|
+
|
|
1728
|
+
if cache is None:
|
|
1729
|
+
cache = Cache()
|
|
1730
|
+
|
|
1731
|
+
exit_code, out, err = run(cache, compiler, compiler_args, env)
|
|
1732
|
+
|
|
1733
|
+
assert len(out) == 1 == len(err)
|
|
1734
|
+
|
|
1735
|
+
# Preferred order in Nuitka scons is output, error, exit_code and we expect
|
|
1736
|
+
# bytes.
|
|
1737
|
+
return out[0].encode(CL_DEFAULT_CODEC), err[0].encode(CL_DEFAULT_CODEC), exit_code
|
|
1738
|
+
|
|
1739
|
+
|
|
1740
|
+
def updateCacheStatistics(cache, method):
|
|
1741
|
+
with cache.statistics as stats:
|
|
1742
|
+
method(stats)
|
|
1743
|
+
|
|
1744
|
+
|
|
1745
|
+
def printOutAndErr(out, err):
|
|
1746
|
+
if "CLCACHE_HIDE_OUTPUTS" not in os.environ:
|
|
1747
|
+
printBinary(sys.stdout, out.encode(CL_DEFAULT_CODEC))
|
|
1748
|
+
printBinary(sys.stderr, err.encode(CL_DEFAULT_CODEC))
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
def printErrStr(message):
|
|
1752
|
+
with OUTPUT_LOCK:
|
|
1753
|
+
print(message, file=sys.stderr)
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
def processCompileRequest(cache, compiler, args, env):
|
|
1757
|
+
printTraceStatement("Parsing given commandline '{0!s}'".format(args))
|
|
1758
|
+
|
|
1759
|
+
cmdLine, environment = extendCommandLineFromEnvironment(args, env)
|
|
1760
|
+
cmdLine = expandCommandLine(cmdLine)
|
|
1761
|
+
printTraceStatement("Expanded commandline '{0!s}'".format(cmdLine))
|
|
1762
|
+
|
|
1763
|
+
try:
|
|
1764
|
+
sourceFiles, objectFiles = CommandLineAnalyzer.analyze(cmdLine)
|
|
1765
|
+
return scheduleJobs(
|
|
1766
|
+
cache, compiler, cmdLine, environment, sourceFiles, objectFiles
|
|
1767
|
+
)
|
|
1768
|
+
except InvalidArgumentError:
|
|
1769
|
+
printTraceStatement(
|
|
1770
|
+
"Cannot cache invocation as {}: invalid argument".format(cmdLine)
|
|
1771
|
+
)
|
|
1772
|
+
updateCacheStatistics(cache, Statistics.registerCallWithInvalidArgument)
|
|
1773
|
+
except NoSourceFileError:
|
|
1774
|
+
printTraceStatement(
|
|
1775
|
+
"Cannot cache invocation as {}: no source file found".format(cmdLine)
|
|
1776
|
+
)
|
|
1777
|
+
updateCacheStatistics(cache, Statistics.registerCallWithoutSourceFile)
|
|
1778
|
+
except MultipleSourceFilesComplexError:
|
|
1779
|
+
printTraceStatement(
|
|
1780
|
+
"Cannot cache invocation as {}: multiple source files found".format(cmdLine)
|
|
1781
|
+
)
|
|
1782
|
+
updateCacheStatistics(cache, Statistics.registerCallWithMultipleSourceFiles)
|
|
1783
|
+
except CalledWithPchError:
|
|
1784
|
+
printTraceStatement(
|
|
1785
|
+
"Cannot cache invocation as {}: precompiled headers in use".format(cmdLine)
|
|
1786
|
+
)
|
|
1787
|
+
updateCacheStatistics(cache, Statistics.registerCallWithPch)
|
|
1788
|
+
except CalledForLinkError:
|
|
1789
|
+
printTraceStatement(
|
|
1790
|
+
"Cannot cache invocation as {}: called for linking".format(cmdLine)
|
|
1791
|
+
)
|
|
1792
|
+
updateCacheStatistics(cache, Statistics.registerCallForLinking)
|
|
1793
|
+
except ExternalDebugInfoError:
|
|
1794
|
+
printTraceStatement(
|
|
1795
|
+
"Cannot cache invocation as {}: external debug information (/Zi) is not supported".format(
|
|
1796
|
+
cmdLine
|
|
1797
|
+
)
|
|
1798
|
+
)
|
|
1799
|
+
updateCacheStatistics(cache, Statistics.registerCallForExternalDebugInfo)
|
|
1800
|
+
except CalledForPreprocessingError:
|
|
1801
|
+
printTraceStatement(
|
|
1802
|
+
"Cannot cache invocation as {}: called for preprocessing".format(cmdLine)
|
|
1803
|
+
)
|
|
1804
|
+
updateCacheStatistics(cache, Statistics.registerCallForPreprocessing)
|
|
1805
|
+
|
|
1806
|
+
exitCode, out, err = invokeRealCompiler(compiler, args, env)
|
|
1807
|
+
printOutAndErr(out, err)
|
|
1808
|
+
return exitCode, [out], [err]
|
|
1809
|
+
|
|
1810
|
+
|
|
1811
|
+
def filterSourceFiles(
|
|
1812
|
+
cmdLine, sourceFiles
|
|
1813
|
+
):
|
|
1814
|
+
setOfSources = set(sourceFile for sourceFile, _ in sourceFiles)
|
|
1815
|
+
skippedArgs = ("/Tc", "/Tp", "-Tp", "-Tc")
|
|
1816
|
+
return (
|
|
1817
|
+
arg
|
|
1818
|
+
for arg in cmdLine
|
|
1819
|
+
if not (arg in setOfSources or arg.startswith(skippedArgs))
|
|
1820
|
+
)
|
|
1821
|
+
|
|
1822
|
+
|
|
1823
|
+
def scheduleJobs(
|
|
1824
|
+
cache,
|
|
1825
|
+
compiler,
|
|
1826
|
+
cmdLine,
|
|
1827
|
+
environment,
|
|
1828
|
+
sourceFiles,
|
|
1829
|
+
objectFiles,
|
|
1830
|
+
):
|
|
1831
|
+
result_out = []
|
|
1832
|
+
result_err = []
|
|
1833
|
+
|
|
1834
|
+
# Filter out all source files from the command line to form baseCmdLine
|
|
1835
|
+
baseCmdLine = [
|
|
1836
|
+
arg
|
|
1837
|
+
for arg in filterSourceFiles(cmdLine, sourceFiles)
|
|
1838
|
+
if not arg.startswith("/MP")
|
|
1839
|
+
]
|
|
1840
|
+
|
|
1841
|
+
exitCode = 0
|
|
1842
|
+
cleanupRequired = False
|
|
1843
|
+
with concurrent.futures.ThreadPoolExecutor(
|
|
1844
|
+
max_workers=jobCount(cmdLine)
|
|
1845
|
+
) as executor:
|
|
1846
|
+
jobs = []
|
|
1847
|
+
for (srcFile, srcLanguage), objFile in zip(sourceFiles, objectFiles):
|
|
1848
|
+
jobCmdLine = baseCmdLine + [srcLanguage + srcFile]
|
|
1849
|
+
jobs.append(
|
|
1850
|
+
executor.submit(
|
|
1851
|
+
processSingleSource,
|
|
1852
|
+
compiler,
|
|
1853
|
+
jobCmdLine,
|
|
1854
|
+
srcFile,
|
|
1855
|
+
objFile,
|
|
1856
|
+
environment,
|
|
1857
|
+
)
|
|
1858
|
+
)
|
|
1859
|
+
for future in concurrent.futures.as_completed(jobs):
|
|
1860
|
+
exitCode, out, err, doCleanup = future.result()
|
|
1861
|
+
printTraceStatement("Finished. Exit code {0:d}".format(exitCode))
|
|
1862
|
+
cleanupRequired |= doCleanup
|
|
1863
|
+
printOutAndErr(out, err)
|
|
1864
|
+
|
|
1865
|
+
result_out.append(out)
|
|
1866
|
+
result_err.append(err)
|
|
1867
|
+
|
|
1868
|
+
if exitCode != 0:
|
|
1869
|
+
break
|
|
1870
|
+
|
|
1871
|
+
if cleanupRequired:
|
|
1872
|
+
cleanCache(cache)
|
|
1873
|
+
|
|
1874
|
+
return exitCode, result_out, result_err
|
|
1875
|
+
|
|
1876
|
+
|
|
1877
|
+
def processSingleSource(compiler, cmdLine, sourceFile, objectFile, environment):
|
|
1878
|
+
try:
|
|
1879
|
+
assert objectFile is not None
|
|
1880
|
+
cache = Cache()
|
|
1881
|
+
|
|
1882
|
+
if "CLCACHE_NODIRECT" in os.environ and os.environ["CLCACHE_NODIRECT"] != "0":
|
|
1883
|
+
return processNoDirect(cache, objectFile, compiler, cmdLine, environment)
|
|
1884
|
+
else:
|
|
1885
|
+
return processDirect(
|
|
1886
|
+
cache, objectFile, compiler, cmdLine, sourceFile, environment
|
|
1887
|
+
)
|
|
1888
|
+
|
|
1889
|
+
except IncludeNotFoundException:
|
|
1890
|
+
return invokeRealCompiler(compiler, cmdLine, environment=environment), False
|
|
1891
|
+
except CompilerFailedException as e:
|
|
1892
|
+
return e.getReturnTuple()
|
|
1893
|
+
|
|
1894
|
+
|
|
1895
|
+
def processDirect(cache, objectFile, compiler, cmdLine, sourceFile, env):
|
|
1896
|
+
manifestHash = ManifestRepository.getManifestHash(compiler, cmdLine, sourceFile)
|
|
1897
|
+
manifestHit = None
|
|
1898
|
+
with cache.manifestLockFor(manifestHash):
|
|
1899
|
+
manifest = cache.getManifest(manifestHash)
|
|
1900
|
+
if manifest:
|
|
1901
|
+
for entryIndex, entry in enumerate(manifest.entries()):
|
|
1902
|
+
# NOTE: command line options already included in hash for manifest name
|
|
1903
|
+
try:
|
|
1904
|
+
includesContentHash = (
|
|
1905
|
+
ManifestRepository.getIncludesContentHashForFiles(
|
|
1906
|
+
[
|
|
1907
|
+
expandBasedirPlaceholder(path)
|
|
1908
|
+
for path in entry.includeFiles
|
|
1909
|
+
]
|
|
1910
|
+
)
|
|
1911
|
+
)
|
|
1912
|
+
|
|
1913
|
+
if entry.includesContentHash == includesContentHash:
|
|
1914
|
+
cachekey = entry.objectHash
|
|
1915
|
+
assert cachekey is not None
|
|
1916
|
+
if entryIndex > 0:
|
|
1917
|
+
# Move manifest entry to the top of the entries in the manifest
|
|
1918
|
+
manifest.touchEntry(cachekey)
|
|
1919
|
+
cache.setManifest(manifestHash, manifest)
|
|
1920
|
+
|
|
1921
|
+
manifestHit = True
|
|
1922
|
+
with cache.lockFor(cachekey):
|
|
1923
|
+
if cache.hasEntry(cachekey):
|
|
1924
|
+
return processCacheHit(cache, objectFile, cachekey)
|
|
1925
|
+
|
|
1926
|
+
except IncludeNotFoundException:
|
|
1927
|
+
pass
|
|
1928
|
+
|
|
1929
|
+
unusableManifestMissReason = Statistics.registerHeaderChangedMiss
|
|
1930
|
+
else:
|
|
1931
|
+
unusableManifestMissReason = Statistics.registerSourceChangedMiss
|
|
1932
|
+
|
|
1933
|
+
if manifestHit is None:
|
|
1934
|
+
stripIncludes = False
|
|
1935
|
+
if "/showIncludes" not in cmdLine:
|
|
1936
|
+
cmdLine = list(cmdLine)
|
|
1937
|
+
cmdLine.insert(0, "/showIncludes")
|
|
1938
|
+
stripIncludes = True
|
|
1939
|
+
compilerResult = invokeRealCompiler(
|
|
1940
|
+
compiler, cmdLine, captureOutput=True, environment=env
|
|
1941
|
+
)
|
|
1942
|
+
if manifestHit is None:
|
|
1943
|
+
includePaths, compilerOutput = parseIncludesSet(
|
|
1944
|
+
compilerResult[1], sourceFile, stripIncludes
|
|
1945
|
+
)
|
|
1946
|
+
compilerResult = (compilerResult[0], compilerOutput, compilerResult[2])
|
|
1947
|
+
|
|
1948
|
+
with cache.manifestLockFor(manifestHash):
|
|
1949
|
+
if manifestHit is not None:
|
|
1950
|
+
return ensureArtifactsExist(
|
|
1951
|
+
cache, cachekey, unusableManifestMissReason, objectFile, compilerResult
|
|
1952
|
+
)
|
|
1953
|
+
|
|
1954
|
+
entry = createManifestEntry(manifestHash, includePaths)
|
|
1955
|
+
cachekey = entry.objectHash
|
|
1956
|
+
|
|
1957
|
+
def addManifest():
|
|
1958
|
+
manifest = cache.getManifest(manifestHash) or Manifest()
|
|
1959
|
+
manifest.addEntry(entry)
|
|
1960
|
+
cache.setManifest(manifestHash, manifest)
|
|
1961
|
+
|
|
1962
|
+
return ensureArtifactsExist(
|
|
1963
|
+
cache,
|
|
1964
|
+
cachekey,
|
|
1965
|
+
unusableManifestMissReason,
|
|
1966
|
+
objectFile,
|
|
1967
|
+
compilerResult,
|
|
1968
|
+
addManifest,
|
|
1969
|
+
)
|
|
1970
|
+
|
|
1971
|
+
|
|
1972
|
+
def processNoDirect(cache, objectFile, compiler, cmdLine, environment):
|
|
1973
|
+
cachekey = CompilerArtifactsRepository.computeKeyNodirect(
|
|
1974
|
+
compiler, cmdLine, environment
|
|
1975
|
+
)
|
|
1976
|
+
with cache.lockFor(cachekey):
|
|
1977
|
+
if cache.hasEntry(cachekey):
|
|
1978
|
+
return processCacheHit(cache, objectFile, cachekey)
|
|
1979
|
+
|
|
1980
|
+
compilerResult = invokeRealCompiler(
|
|
1981
|
+
compiler, cmdLine, captureOutput=True, environment=environment
|
|
1982
|
+
)
|
|
1983
|
+
|
|
1984
|
+
return ensureArtifactsExist(
|
|
1985
|
+
cache, cachekey, Statistics.registerCacheMiss, objectFile, compilerResult
|
|
1986
|
+
)
|
|
1987
|
+
|
|
1988
|
+
|
|
1989
|
+
def ensureArtifactsExist(
|
|
1990
|
+
cache, cachekey, reason, objectFile, compilerResult, extraCallable=None
|
|
1991
|
+
):
|
|
1992
|
+
cleanupRequired = False
|
|
1993
|
+
returnCode, compilerOutput, compilerStderr = compilerResult
|
|
1994
|
+
correctCompiliation = returnCode == 0 and os.path.exists(objectFile)
|
|
1995
|
+
with cache.lockFor(cachekey):
|
|
1996
|
+
if not cache.hasEntry(cachekey):
|
|
1997
|
+
with cache.statistics as stats:
|
|
1998
|
+
reason(stats)
|
|
1999
|
+
if correctCompiliation:
|
|
2000
|
+
artifacts = CompilerArtifacts(
|
|
2001
|
+
objectFile, compilerOutput, compilerStderr
|
|
2002
|
+
)
|
|
2003
|
+
cleanupRequired = addObjectToCache(
|
|
2004
|
+
stats, cache, cachekey, artifacts
|
|
2005
|
+
)
|
|
2006
|
+
if extraCallable and correctCompiliation:
|
|
2007
|
+
extraCallable()
|
|
2008
|
+
return returnCode, compilerOutput, compilerStderr, cleanupRequired
|