aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Schwartz <eschwartz@archlinux.org>2023-06-25 02:49:33 -0400
committerEli Schwartz <eschwartz@archlinux.org>2023-06-26 13:08:57 -0400
commit620bdf5895131f9e58da4c980a28dc96986d0b57 (patch)
tree084152f85bfb8558cb616f504b6aa97502a4837d
parent25f5f3554de6c80ace9ed211fa8c851505d95770 (diff)
downloadmeson-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.py28
-rw-r--r--test cases/unit/113 empty project/expected_mods.json277
-rw-r--r--test cases/unit/113 empty project/meson.build1
-rw-r--r--unittests/platformagnostictests.py27
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)