diff options
author | Eli Schwartz <eschwartz@archlinux.org> | 2023-06-25 02:49:33 -0400 |
---|---|---|
committer | Eli Schwartz <eschwartz@archlinux.org> | 2023-06-26 13:08:57 -0400 |
commit | 620bdf5895131f9e58da4c980a28dc96986d0b57 (patch) | |
tree | 084152f85bfb8558cb616f504b6aa97502a4837d | |
parent | 25f5f3554de6c80ace9ed211fa8c851505d95770 (diff) | |
download | meson-620bdf5895131f9e58da4c980a28dc96986d0b57.zip meson-620bdf5895131f9e58da4c980a28dc96986d0b57.tar.gz meson-620bdf5895131f9e58da4c980a28dc96986d0b57.tar.bz2 |
add profiling startup import check and testcase to count it
-rw-r--r-- | mesonbuild/msetup.py | 28 | ||||
-rw-r--r-- | test cases/unit/113 empty project/expected_mods.json | 277 | ||||
-rw-r--r-- | test cases/unit/113 empty project/meson.build | 1 | ||||
-rw-r--r-- | unittests/platformagnostictests.py | 27 |
4 files changed, 318 insertions, 15 deletions
diff --git a/mesonbuild/msetup.py b/mesonbuild/msetup.py index 263ce19..edc6330 100644 --- a/mesonbuild/msetup.py +++ b/mesonbuild/msetup.py @@ -13,25 +13,14 @@ # limitations under the License. from __future__ import annotations -import typing as T -import time -import sys -import datetime -import os.path -import platform +import argparse, datetime, glob, json, os, platform, shutil, sys, tempfile, time import cProfile as profile -import argparse -import tempfile -import shutil -import glob from pathlib import Path +import typing as T -from . import environment, interpreter, mesonlib -from . import build -from . import mlog, coredata -from . import mintro -from .mesonlib import MesonException, MachineChoice +from . import build, coredata, environment, interpreter, mesonlib, mintro, mlog from .dependencies import PkgConfigDependency +from .mesonlib import MachineChoice, MesonException git_ignore_file = '''# This file is autogenerated by Meson. If you change or delete it, it won't be recreated. * @@ -291,6 +280,15 @@ class MesonApp: 'Please consider using `meson devenv` instead. See https://github.com/mesonbuild/meson/pull/9243 ' 'for details.') + if self.options.profile: + fname = os.path.join(self.build_dir, 'meson-logs', 'profile-startup-modules.json') + mods = set(sys.modules.keys()) + mesonmods = {mod for mod in mods if (mod+'.').startswith('mesonbuild.')} + stdmods = sorted(mods - mesonmods) + data = {'stdlib': {'modules': stdmods, 'count': len(stdmods)}, 'meson': {'modules': sorted(mesonmods), 'count': len(mesonmods)}} + with open(fname, 'w', encoding='utf-8') as f: + json.dump(data, f) + except Exception as e: mintro.write_meson_info_file(b, [e]) if cdf is not None: diff --git a/test cases/unit/113 empty project/expected_mods.json b/test cases/unit/113 empty project/expected_mods.json new file mode 100644 index 0000000..2e7c289 --- /dev/null +++ b/test cases/unit/113 empty project/expected_mods.json @@ -0,0 +1,277 @@ +{ + "stdlib": { + "modules": [ + "__future__", + "__main__", + "_abc", + "_ast", + "_bisect", + "_blake2", + "_bz2", + "_codecs", + "_collections", + "_collections_abc", + "_compat_pickle", + "_compression", + "_datetime", + "_frozen_importlib", + "_frozen_importlib_external", + "_functools", + "_hashlib", + "_imp", + "_io", + "_json", + "_locale", + "_lsprof", + "_lzma", + "_opcode", + "_operator", + "_pickle", + "_posixsubprocess", + "_random", + "_sha512", + "_signal", + "_sitebuiltins", + "_socket", + "_sre", + "_ssl", + "_stat", + "_string", + "_struct", + "_thread", + "_uuid", + "_warnings", + "_weakref", + "_weakrefset", + "abc", + "argparse", + "array", + "ast", + "base64", + "binascii", + "bisect", + "builtins", + "bz2", + "cProfile", + "calendar", + "codecs", + "collections", + "collections.abc", + "configparser", + "contextlib", + "copy", + "copyreg", + "dataclasses", + "datetime", + "dis", + "email", + "email._encoded_words", + "email._parseaddr", + "email._policybase", + "email.base64mime", + "email.charset", + "email.encoders", + "email.errors", + "email.feedparser", + "email.header", + "email.iterators", + "email.message", + "email.parser", + "email.quoprimime", + "email.utils", + "encodings", + "encodings.aliases", + "encodings.utf_8", + "enum", + "errno", + "fcntl", + "fnmatch", + "functools", + "genericpath", + "gettext", + "glob", + "hashlib", + "http", + "http.client", + "importlib", + "importlib._abc", + "importlib._adapters", + "importlib._bootstrap", + "importlib._bootstrap_external", + "importlib._common", + "importlib.abc", + "importlib.machinery", + "importlib.resources", + "inspect", + "io", + "itertools", + "json", + "json.decoder", + "json.encoder", + "json.scanner", + "keyword", + "linecache", + "locale", + "lzma", + "marshal", + "math", + "netrc", + "ntpath", + "opcode", + "operator", + "os", + "os.path", + "pathlib", + "pickle", + "platform", + "posix", + "posixpath", + "profile", + "quopri", + "random", + "re", + "reprlib", + "select", + "selectors", + "shlex", + "shutil", + "signal", + "site", + "socket", + "sre_compile", + "sre_constants", + "sre_parse", + "ssl", + "stat", + "string", + "struct", + "subprocess", + "sys", + "tempfile", + "textwrap", + "threading", + "time", + "token", + "tokenize", + "types", + "typing", + "typing.io", + "typing.re", + "urllib", + "urllib.error", + "urllib.parse", + "urllib.request", + "urllib.response", + "uu", + "uuid", + "warnings", + "weakref", + "zipimport", + "zlib" + ], + "count": 167 + }, + "meson": { + "modules": [ + "mesonbuild", + "mesonbuild._pathlib", + "mesonbuild.arglist", + "mesonbuild.ast", + "mesonbuild.ast.interpreter", + "mesonbuild.ast.introspection", + "mesonbuild.ast.postprocess", + "mesonbuild.ast.printer", + "mesonbuild.ast.visitor", + "mesonbuild.backend", + "mesonbuild.backend.backends", + "mesonbuild.backend.ninjabackend", + "mesonbuild.build", + "mesonbuild.cmake", + "mesonbuild.cmake.common", + "mesonbuild.cmake.executor", + "mesonbuild.cmake.fileapi", + "mesonbuild.cmake.generator", + "mesonbuild.cmake.interpreter", + "mesonbuild.cmake.toolchain", + "mesonbuild.cmake.traceparser", + "mesonbuild.cmake.tracetargets", + "mesonbuild.compilers", + "mesonbuild.compilers.compilers", + "mesonbuild.compilers.detect", + "mesonbuild.coredata", + "mesonbuild.dependencies", + "mesonbuild.dependencies.base", + "mesonbuild.dependencies.boost", + "mesonbuild.dependencies.cmake", + "mesonbuild.dependencies.coarrays", + "mesonbuild.dependencies.configtool", + "mesonbuild.dependencies.cuda", + "mesonbuild.dependencies.detect", + "mesonbuild.dependencies.dev", + "mesonbuild.dependencies.dub", + "mesonbuild.dependencies.factory", + "mesonbuild.dependencies.framework", + "mesonbuild.dependencies.hdf5", + "mesonbuild.dependencies.misc", + "mesonbuild.dependencies.mpi", + "mesonbuild.dependencies.pkgconfig", + "mesonbuild.dependencies.platform", + "mesonbuild.dependencies.python", + "mesonbuild.dependencies.qt", + "mesonbuild.dependencies.scalapack", + "mesonbuild.dependencies.ui", + "mesonbuild.depfile", + "mesonbuild.envconfig", + "mesonbuild.environment", + "mesonbuild.interpreter", + "mesonbuild.interpreter.compiler", + "mesonbuild.interpreter.dependencyfallbacks", + "mesonbuild.interpreter.interpreter", + "mesonbuild.interpreter.interpreterobjects", + "mesonbuild.interpreter.mesonmain", + "mesonbuild.interpreter.primitives", + "mesonbuild.interpreter.primitives.array", + "mesonbuild.interpreter.primitives.boolean", + "mesonbuild.interpreter.primitives.dict", + "mesonbuild.interpreter.primitives.integer", + "mesonbuild.interpreter.primitives.range", + "mesonbuild.interpreter.primitives.string", + "mesonbuild.interpreter.type_checking", + "mesonbuild.interpreterbase", + "mesonbuild.interpreterbase._unholder", + "mesonbuild.interpreterbase.baseobjects", + "mesonbuild.interpreterbase.decorators", + "mesonbuild.interpreterbase.disabler", + "mesonbuild.interpreterbase.exceptions", + "mesonbuild.interpreterbase.helpers", + "mesonbuild.interpreterbase.interpreterbase", + "mesonbuild.interpreterbase.operator", + "mesonbuild.linkers", + "mesonbuild.linkers.detect", + "mesonbuild.linkers.linkers", + "mesonbuild.mesondata", + "mesonbuild.mesonlib", + "mesonbuild.mesonmain", + "mesonbuild.mintro", + "mesonbuild.mlog", + "mesonbuild.modules", + "mesonbuild.modules.gnome", + "mesonbuild.mparser", + "mesonbuild.msetup", + "mesonbuild.optinterpreter", + "mesonbuild.programs", + "mesonbuild.scripts", + "mesonbuild.scripts.gettext", + "mesonbuild.scripts.meson_exe", + "mesonbuild.utils", + "mesonbuild.utils.core", + "mesonbuild.utils.platform", + "mesonbuild.utils.posix", + "mesonbuild.utils.universal", + "mesonbuild.utils.vsenv", + "mesonbuild.wrap", + "mesonbuild.wrap.wrap" + ], + "count": 98 + } +} diff --git a/test cases/unit/113 empty project/meson.build b/test cases/unit/113 empty project/meson.build new file mode 100644 index 0000000..b92b9b4 --- /dev/null +++ b/test cases/unit/113 empty project/meson.build @@ -0,0 +1 @@ +project('empty project') diff --git a/unittests/platformagnostictests.py b/unittests/platformagnostictests.py index a3ff715..bbc34c9 100644 --- a/unittests/platformagnostictests.py +++ b/unittests/platformagnostictests.py @@ -206,6 +206,9 @@ class PlatformAgnosticTests(BasePlatformTests): output. The script will print all python modules loaded and we verify that it contains only an acceptable subset. Loading too many modules slows down the build when many custom targets get wrapped. + + This list must not be edited without a clear rationale for why it is + acceptable to do so! ''' es = ExecutableSerialisation(python_command + ['-c', 'exit(0)'], env=EnvironmentVariables()) p = Path(self.builddir, 'exe.dat') @@ -227,3 +230,27 @@ class PlatformAgnosticTests(BasePlatformTests): 'mesonbuild.scripts.test_loaded_modules' ] self.assertEqual(sorted(expected_meson_modules), sorted(meson_modules)) + + def test_setup_loaded_modules(self): + ''' + Execute a very basic meson.build and capture a list of all python + modules loaded. We verify that it contains only an acceptable subset. + Loading too many modules slows down `meson setup` startup time and + gives a perception that meson is slow. + + Adding more modules to the default startup flow is not an unreasonable + thing to do as new features are added, but keeping track of them is + good. + ''' + testdir = os.path.join(self.unit_test_dir, '113 empty project') + + self.init(testdir) + self._run(self.meson_command + ['--internal', 'regenerate', '--profile-self', testdir, self.builddir]) + with open(os.path.join(self.builddir, 'meson-logs', 'profile-startup-modules.json')) as f: + data = json.load(f)['meson'] + + with open(os.path.join(testdir, 'expected_mods.json')) as f: + expected = json.load(f)['meson']['modules'] + + self.assertEqual(data['modules'], expected) + self.assertEqual(data['count'], 98) |