From 4540474fd5be4000ed33c3df537274d955094d52 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 18 Jul 2023 11:22:21 -0400 Subject: [PATCH 01/99] ci: Skip test_generate_gir_with_address_sanitizer It fails with glib >= 2.76 and gobject-introspection <= 1.76.1. Fixes: #11754 (cherry picked from commit 9d88d0d5cc92de04cb33cac4ddaedff622b65c40) --- test cases/frameworks/7 gnome/meson.build | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test cases/frameworks/7 gnome/meson.build b/test cases/frameworks/7 gnome/meson.build index 4638d4dfbc29..4d54e774b121 100644 --- a/test cases/frameworks/7 gnome/meson.build +++ b/test cases/frameworks/7 gnome/meson.build @@ -51,6 +51,15 @@ gobj = dependency('gobject-2.0') gir = dependency('gobject-introspection-1.0') gmod = dependency('gmodule-2.0') +# GLib >= 2.76 removed slice allocator which causes a leak in g-i to now be +# visible to asan. The leak should be fixed in g-i >= 1.76.2: +# https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/411 +if get_option('b_sanitize') != 'none' and \ + gir.version().version_compare('<=1.76.1') and \ + glib.version().version_compare('>=2.76') + error('MESON_SKIP_TEST gobject-introspection >=1.76.2 is required with address sanitizer.') +endif + # Test that static deps don't error out when static libraries aren't found glib_static = dependency('glib-2.0', static : true) From ccea7af5c942be3a485b2f4c2e0c4391fce61f03 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Sun, 7 May 2023 20:57:24 -0400 Subject: [PATCH 02/99] tests: mark gpgme test skippable on Ubuntu rolling It has been rebuilt to no longer provide the deprecated gpgme-config tool. (cherry picked from commit 0a40e591d3b9665a63ef243f78450a6e97304669) --- test cases/frameworks/27 gpgme/test.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test cases/frameworks/27 gpgme/test.json b/test cases/frameworks/27 gpgme/test.json index aa7d932dd607..59eb0e24d871 100644 --- a/test cases/frameworks/27 gpgme/test.json +++ b/test cases/frameworks/27 gpgme/test.json @@ -1,3 +1,3 @@ { - "skip_on_jobname": ["azure", "cygwin", "macos", "msys2", "linux-arch"] + "skip_on_jobname": ["azure", "cygwin", "macos", "msys2", "linux-arch", "ubuntu"] } From 0f6d6303ba967495f3b496ff742645c9eee4e452 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 18 Jul 2023 16:01:29 -0400 Subject: [PATCH 03/99] tests: bump the C++ std for protobuf tests Based on https://opensource.google/documentation/policies/cplusplus-support Google no longer supports C++11, and protobuf spawns an `#error` if you don't have at least 14. So, perform our currently scheduled automatic bump. (cherry picked from commit a8b9bd2b74030863d61761483dbc3f6db8803c68) --- test cases/frameworks/5 protocol buffers/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test cases/frameworks/5 protocol buffers/meson.build b/test cases/frameworks/5 protocol buffers/meson.build index 046847a89297..9a4154b652f3 100644 --- a/test cases/frameworks/5 protocol buffers/meson.build +++ b/test cases/frameworks/5 protocol buffers/meson.build @@ -1,4 +1,4 @@ -project('protocol buffer test', 'cpp', default_options: ['cpp_std=c++11']) +project('protocol buffer test', 'cpp', default_options: ['cpp_std=c++14']) protoc = find_program('protoc', required : false) dep = dependency('protobuf', required : false) From 3270855e3454dcf386b2a16766d580a9b90f158d Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 18 Jul 2023 16:32:36 -0400 Subject: [PATCH 04/99] mtest: avoid meddling with stdout by default The original point of specifying Optional was to default to None... oops. The practical effect of this change is that the testsuite no longer repeatedly logs "No tests defined." in between more meaningful output. (cherry picked from commit 6894bb5a30a05dbd9d30eb4ce5720f6c2a7df83d) --- mesonbuild/mtest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index eb56c42be555..88995c0fedeb 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -1933,7 +1933,7 @@ def tests_from_args(self, tests: T.List[TestSerialisation]) -> T.Generator[TestS # succeed on an invalid pattern. raise MesonException(f'{arg} test name does not match any test') - def get_tests(self, errorfile: T.Optional[T.IO] = sys.stdout) -> T.List[TestSerialisation]: + def get_tests(self, errorfile: T.Optional[T.IO] = None) -> T.List[TestSerialisation]: if not self.tests: print('No tests defined.', file=errorfile) return [] From 46bc59f328033ced8ddb45f8648855adc31b8b3e Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 18 Jul 2023 17:29:41 -0400 Subject: [PATCH 05/99] CI: change ubuntu cross exe_wrapper to un-suffixed wine wine64 used to be the way to run a 64-bit wineserver. It was removed due to https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1029536 despite that bug report being about a bug in an unrelated symlink -- apparently there's no recommended solution to starting a specific bitness of wine on demand. The automagic `wine` I believe creates a wineprefix with both, which is... probably not exactly efficient here? But whatever, not worth fighting it. Just get this more or less working again. (cherry picked from commit d048bbfbe7c3d287e9b1e61c39313862caf9fd52) --- cross/linux-mingw-w64-64bit.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cross/linux-mingw-w64-64bit.txt b/cross/linux-mingw-w64-64bit.txt index f49fb35bfbd3..7403803b4c05 100644 --- a/cross/linux-mingw-w64-64bit.txt +++ b/cross/linux-mingw-w64-64bit.txt @@ -6,7 +6,7 @@ ar = '/usr/bin/x86_64-w64-mingw32-ar' strip = '/usr/bin/x86_64-w64-mingw32-strip' pkgconfig = '/usr/bin/x86_64-w64-mingw32-pkg-config' windres = '/usr/bin/x86_64-w64-mingw32-windres' -exe_wrapper = 'wine64' +exe_wrapper = 'wine' cmake = '/usr/bin/cmake' [properties] From 57d0b7e25bc014ca5f5558d886d65b759e83106d Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Fri, 21 Jul 2023 01:00:44 -0400 Subject: [PATCH 06/99] do better sanity check for vs_module_defs input We allow custom_target() but check for it based on hasattr, ever since the initial implementation way back in the day, in commit 66a6ea984bc43d9ac144e22cf411c16e9f911bb3. This is a bit broken because various objects might support that but still aren't supposed to work. We can actually just use isintance checks like we do immediately above, which are more accurate and avoid crashes on things that aren't even targets at all, like run_target(). Although custom_target indexes are actually targets those didn't work either. Fixes #9648 (cherry picked from commit 404312c6ddc44b1e8f09a95a5c889184a25a384b) --- mesonbuild/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 0a4160fb1c6b..29213b62c8c7 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -2402,7 +2402,7 @@ def process_kwargs(self, kwargs): elif isinstance(path, File): # When passing a generated file. self.vs_module_defs = path - elif hasattr(path, 'get_filename'): + elif isinstance(path, CustomTarget): # When passing output of a Custom Target self.vs_module_defs = File.from_built_file(path.subdir, path.get_filename()) else: From 2bba476cee37592b4e68a8b9af69fedd13c81296 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Sun, 30 Jul 2023 20:28:59 -0400 Subject: [PATCH 07/99] fix lint errors revealed by pycodestyle 2.11 When performing isinstance checks, an identity comparison is automatically done, but we don't use isinstance here because we need strict identity equality *without allowing subtypes*. Comparing type() == type() is a value comparison, but could produce effectively the same results as an identity comparison, usually, despite being semantically off. pycodestyle learned to detect this and warn you to do strict identity comparison. (cherry picked from commit d4615369ffbfc0f9a769ca1fd3566056cfa5ef81) --- mesonbuild/coredata.py | 2 +- mesonbuild/interpreterbase/baseobjects.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index c1d59637d108..2c7c39e1c50b 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -807,7 +807,7 @@ def update_project_options(self, options: 'MutableKeyedOptionDictType') -> None: continue oldval = self.options[key] - if type(oldval) != type(value): + if type(oldval) is not type(value): self.options[key] = value elif oldval.choices != value.choices: # If the choices have changed, use the new value, but attempt diff --git a/mesonbuild/interpreterbase/baseobjects.py b/mesonbuild/interpreterbase/baseobjects.py index d5b8c947624c..4966978a0c2b 100644 --- a/mesonbuild/interpreterbase/baseobjects.py +++ b/mesonbuild/interpreterbase/baseobjects.py @@ -119,12 +119,12 @@ def op_equals(self, other: TYPE_var) -> bool: # We use `type(...) == type(...)` here to enforce an *exact* match for comparison. We # don't want comparisons to be possible where `isinstance(derived_obj, type(base_obj))` # would pass because this comparison must never be true: `derived_obj == base_obj` - if type(self) != type(other): + if type(self) is not type(other): self._throw_comp_exception(other, '==') return self == other def op_not_equals(self, other: TYPE_var) -> bool: - if type(self) != type(other): + if type(self) is not type(other): self._throw_comp_exception(other, '!=') return self != other @@ -157,12 +157,12 @@ def display_name(self) -> str: # Override default comparison operators for the held object def op_equals(self, other: TYPE_var) -> bool: # See the comment from InterpreterObject why we are using `type()` here. - if type(self.held_object) != type(other): + if type(self.held_object) is not type(other): self._throw_comp_exception(other, '==') return self.held_object == other def op_not_equals(self, other: TYPE_var) -> bool: - if type(self.held_object) != type(other): + if type(self.held_object) is not type(other): self._throw_comp_exception(other, '!=') return self.held_object != other From e3a2af07ce02c2ce5a8918c805885f6a91089b22 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 18 Jul 2023 18:13:27 -0400 Subject: [PATCH 08/99] CI image builder: log commands a bit (cherry picked from commit 1d84989078026acbfd256f294f5359361d2f1b0d) --- ci/ciimage/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/ciimage/build.py b/ci/ciimage/build.py index 1e1f23811c3d..01979556dcfb 100755 --- a/ci/ciimage/build.py +++ b/ci/ciimage/build.py @@ -175,7 +175,7 @@ def do_test(self, tty: bool = False) -> None: else: test_cmd = [ self.docker, 'run', '--rm', '-t', 'meson_test_image', - '/bin/bash', '-c', 'source /ci/env_vars.sh; cd meson; ./run_tests.py $CI_ARGS' + '/bin/bash', '-xc', 'source /ci/env_vars.sh; cd meson; ./run_tests.py $CI_ARGS' ] if subprocess.run(test_cmd).returncode != 0 and not tty: From 65ecc80d111b278e01f8e4dd25d9bdd567d672c8 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Fri, 28 Jul 2023 17:43:50 +0200 Subject: [PATCH 09/99] tests: skip a test that fails with new Python 3.11 from MSYS2 For some (atm unknown) reason mingw Python fails to load some modules when MSYS2 is removed from PATH, like in this test. Skip for now to make the test suite pass again. Once https://github.com/msys2-contrib/cpython-mingw/issues/141 is fixed this can be reverted. (cherry picked from commit 68dce66bf9a2bcb3d23c291beb2354225a74b954) --- unittests/windowstests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/unittests/windowstests.py b/unittests/windowstests.py index 37e92996d97a..c201953276cc 100644 --- a/unittests/windowstests.py +++ b/unittests/windowstests.py @@ -462,6 +462,9 @@ def test_non_utf8_fails(self): @unittest.skipIf(is_cygwin(), "Needs visual studio") def test_vsenv_option(self): + if mesonbuild.environment.detect_msys2_arch(): + # https://github.com/msys2-contrib/cpython-mingw/issues/141 + raise SkipTest('mingw python fails with /bin being removed from PATH') if self.backend is not Backend.ninja: raise SkipTest('Only ninja backend is valid for test') env = os.environ.copy() From f7b9f5bd233d033fec17895336f253b7a02f872a Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sat, 29 Jul 2023 20:53:31 +0200 Subject: [PATCH 10/99] Revert "CI: add potential workaround for python crashes in MSYS2" This reverts commit e945f35cd72402d0d204ff10870e2a95c59b6192. With MSYS2 udpating to Python 3.11, this should no longer be needed. See https://github.com/msys2/MINGW-packages/issues/17415#issuecomment-1606085553 (cherry picked from commit 3752041c8d56c7667bc0fe644fda6c2834d6aaf8) --- .github/workflows/msys2.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/msys2.yml b/.github/workflows/msys2.yml index 8f1823d70633..2bdcdd30e6f4 100644 --- a/.github/workflows/msys2.yml +++ b/.github/workflows/msys2.yml @@ -51,9 +51,6 @@ jobs: TOOLCHAIN: clang env: MESON_CI_JOBNAME: msys2-${{ matrix.NAME }} - # XXX: For some reason enabling jit debugging "fixes" random python crashes - # see https://github.com/msys2/MINGW-packages/issues/11864 - MSYS: "winjitdebug" defaults: run: From 5a37895b2b89e9743b16c1ebcbf8e05cce60ebf3 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 24 Jul 2023 19:34:19 -0700 Subject: [PATCH 11/99] modules/pkgconfig: Don't insert None into devenv list When the pkgconfig module is imported, but not used, it will insert None on the end of the devenv list. This list is not expected to contain None, and causes Meson to crash. This can happen in complex build setups (reported from mesa), where pkgconfig is only used in some configurations Fixes: #12032 --- mesonbuild/modules/pkgconfig.py | 3 ++- test cases/unit/90 devenv/meson.build | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py index 921fb666167b..63025a502a3a 100644 --- a/mesonbuild/modules/pkgconfig.py +++ b/mesonbuild/modules/pkgconfig.py @@ -391,7 +391,8 @@ def __init__(self) -> None: }) def postconf_hook(self, b: build.Build) -> None: - b.devenv.append(self.devenv) + if self.devenv is not None: + b.devenv.append(self.devenv) def _get_lname(self, l: T.Union[build.SharedLibrary, build.StaticLibrary, build.CustomTarget, build.CustomTargetIndex], msg: str, pcfile: str) -> str: diff --git a/test cases/unit/90 devenv/meson.build b/test cases/unit/90 devenv/meson.build index 72d8fdc33ca8..316b20c62a39 100644 --- a/test cases/unit/90 devenv/meson.build +++ b/test cases/unit/90 devenv/meson.build @@ -20,3 +20,6 @@ env = environment({'TEST_C': ['/prefix']}, method: 'prepend') meson.add_devenv(env) env = environment({'TEST_C': ['/suffix']}, method: 'append') meson.add_devenv(env) + +# Reproducer for https://github.com/mesonbuild/meson/issues/12032 +pkgconf = import('pkgconfig') From 42723f123c4783fcd648066ec06ac151c0558530 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 25 Jul 2023 13:28:34 -0400 Subject: [PATCH 12/99] packaging: fix regression that prevented pyinstaller from getting custom deps mesonbuild.dependencies.* is now lazy-imported and not automatically detected. Add them as hidden imports. Fixes #12036 --- packaging/hook-mesonbuild.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packaging/hook-mesonbuild.py b/packaging/hook-mesonbuild.py index 86e74639f03b..d6b06cd26213 100644 --- a/packaging/hook-mesonbuild.py +++ b/packaging/hook-mesonbuild.py @@ -25,7 +25,11 @@ def get_all_modules_from_dir(dirname): datas += collect_data_files('mesonbuild.cmake.data') datas += collect_data_files('mesonbuild.dependencies.data') +# lazy-loaded +hiddenimports += get_all_modules_from_dir('mesonbuild/dependencies') +# imported by meson.build files hiddenimports += get_all_modules_from_dir('mesonbuild/modules') +# executed when named on CLI hiddenimports += get_all_modules_from_dir('mesonbuild/scripts') # Python packagers want to be minimal and only copy the things From 97a3317d99e9894bce48a81630e793eebc77f421 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Mon, 31 Jul 2023 17:31:11 +0300 Subject: [PATCH 13/99] Upgrade MSI builder from WiX3 to WiX 4. --- packaging/createmsi.py | 98 +++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 45 deletions(-) diff --git a/packaging/createmsi.py b/packaging/createmsi.py index 4febc393dda6..6f198f3088b6 100755 --- a/packaging/createmsi.py +++ b/packaging/createmsi.py @@ -31,7 +31,7 @@ from mesonbuild import coredata # Elementtree does not support CDATA. So hack it. -WINVER_CHECK = ' 602)]]>' +WINVER_CHECK = 'Installed OR (VersionNT64 > 602)>' def gen_guid(): ''' @@ -102,7 +102,7 @@ def __init__(self): 'Title': 'Meson', 'Description': 'Meson executables', 'Level': '1', - 'Absent': 'disallow', + 'AllowAbsent': 'no', }, self.staging_dirs[1]: { 'Id': 'NinjaProgram', @@ -160,49 +160,44 @@ def generate_files(self): ''' Generate package files for MSI installer package ''' - self.root = ET.Element('Wix', {'xmlns': 'http://schemas.microsoft.com/wix/2006/wi'}) - product = ET.SubElement(self.root, 'Product', { + self.root = ET.Element('Wix', { + 'xmlns': 'http://wixtoolset.org/schemas/v4/wxs', + 'xmlns:ui': 'http://wixtoolset.org/schemas/v4/wxs/ui' + }) + + package = ET.SubElement(self.root, 'Package', { 'Name': self.product_name, 'Manufacturer': 'The Meson Development Team', - 'Id': self.guid, 'UpgradeCode': self.update_guid, 'Language': '1033', 'Codepage': '1252', 'Version': self.version, }) - package = ET.SubElement(product, 'Package', { - 'Id': '*', + ET.SubElement(package, 'SummaryInformation', { 'Keywords': 'Installer', 'Description': f'Meson {self.version} installer', - 'Comments': 'Meson is a high performance build system', 'Manufacturer': 'The Meson Development Team', - 'InstallerVersion': '500', - 'Languages': '1033', - 'Compressed': 'yes', - 'SummaryCodepage': '1252', }) - condition = ET.SubElement(product, 'Condition', {'Message': 'This application is only supported on Windows 10 or higher.'}) + ET.SubElement(package, + 'Launch', + {'Message': 'This application is only supported on Windows 10 or higher.', + 'Condition': 'X'*len(WINVER_CHECK)}) - condition.text = 'X'*len(WINVER_CHECK) - ET.SubElement(product, 'MajorUpgrade', - {'DowngradeErrorMessage': 'A newer version of Meson is already installed.'}) + ET.SubElement(package, 'MajorUpgrade', + {'DowngradeErrorMessage': + 'A newer version of Meson is already installed.'}) - package.set('Platform', 'x64') - ET.SubElement(product, 'Media', { + ET.SubElement(package, 'Media', { 'Id': '1', 'Cabinet': 'meson.cab', 'EmbedCab': 'yes', }) - targetdir = ET.SubElement(product, 'Directory', { - 'Id': 'TARGETDIR', - 'Name': 'SourceDir', + targetdir = ET.SubElement(package, 'StandardDirectory', { + 'Id': 'ProgramFiles64Folder', }) - progfiledir = ET.SubElement(targetdir, 'Directory', { - 'Id': self.progfile_dir, - }) - installdir = ET.SubElement(progfiledir, 'Directory', { + installdir = ET.SubElement(targetdir, 'Directory', { 'Id': 'INSTALLDIR', 'Name': 'Meson', }) @@ -213,16 +208,12 @@ def generate_files(self): 'Language': '0', }) - ET.SubElement(product, 'Property', { - 'Id': 'WIXUI_INSTALLDIR', - 'Value': 'INSTALLDIR', - }) - ET.SubElement(product, 'UIRef', { + ET.SubElement(package, 'ui:WixUI', { 'Id': 'WixUI_FeatureTree', }) for s_d in self.staging_dirs: assert os.path.isdir(s_d) - top_feature = ET.SubElement(product, 'Feature', { + top_feature = ET.SubElement(package, 'Feature', { 'Id': 'Complete', 'Title': 'Meson ' + self.version, 'Description': 'The complete package', @@ -277,10 +268,10 @@ def create_xml(self, nodes, current_dir, parent_xml_node, staging_dir): component_id = f'ApplicationFiles{self.component_num}' comp_xml_node = ET.SubElement(parent_xml_node, 'Component', { 'Id': component_id, + 'Bitness': 'always64', 'Guid': gen_guid(), }) self.feature_components[staging_dir].append(component_id) - comp_xml_node.set('Win64', 'yes') if self.component_num == 0: ET.SubElement(comp_xml_node, 'Environment', { 'Id': 'Environment', @@ -311,23 +302,40 @@ def build_package(self): ''' Generate the Meson build MSI package. ''' - wixdir = 'c:\\Program Files\\Wix Toolset v3.11\\bin' - if not os.path.isdir(wixdir): - wixdir = 'c:\\Program Files (x86)\\Wix Toolset v3.11\\bin' - if not os.path.isdir(wixdir): - print("ERROR: This script requires WIX") - sys.exit(1) - subprocess.check_call([os.path.join(wixdir, 'candle'), self.main_xml]) - subprocess.check_call([os.path.join(wixdir, 'light'), - '-ext', 'WixUIExtension', - '-cultures:en-us', - '-dWixUILicenseRtf=packaging\\License.rtf', - '-out', self.final_output, - self.main_o]) + subprocess.check_call(['wix', + 'build', + '-bindvariable', 'WixUILicenseRtf=packaging\\License.rtf', + '-ext', 'WixToolset.UI.wixext', + '-culture', 'en-us', + '-arch', 'x64', + '-o', + self.final_output, + self.main_xml, + ]) + + +def install_wix(): + subprocess.check_call(['dotnet', + 'nuget', + 'add', + 'source', + 'https://api.nuget.org/v3/index.json']) + subprocess.check_call(['dotnet', + 'tool', + 'install', + '--global', + 'wix']) + subprocess.check_call(['wix', + 'extension', + 'add', + 'WixToolset.UI.wixext', + ]) if __name__ == '__main__': if not os.path.exists('meson.py'): sys.exit(print('Run me in the top level source dir.')) + if not shutil.which('wix'): + install_wix() subprocess.check_call(['pip', 'install', '--upgrade', 'pyinstaller']) p = PackageGenerator() From fe25c9940fd1c84614c4f93dfa33f5b5fe90fb34 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 1 Aug 2023 14:23:57 -0400 Subject: [PATCH 14/99] treewide: internally avoid deprecated machine file uses of "pkgconfig" We support this in a machine file: ``` [binaries] pkgconfig = 'pkg-config' pkg-config = 'pkg-config' ``` and you can use either one, because internally we look up both. If you only set *one* of them, this plays awkwardly with setting $PKG_CONFIG, since we don't know which one you set in the machine file and the *other* one will be initialized from the environment instead. In commit 22df45a31981874310a78dde0df59a6a7c5ebb29 we changed program lookup of config-tool style dependencies to use the regular tool names and only fall back on the strange internal names. This affected the pkg-config class too. The result is that instead of preferring `pkgconfig =` followed by $PKG_CONFIG followed by `pkg-config =`, we inverted the lookup order. This is a good idea anyway, because now it behaves consistently with `find_program('pkg-config')`. Unfortunately, we documented the wrong name in a bunch of places, and also used the wrong name in various testsuite bits, which meant that if you set $PKG_CONFIG and then ran the testsuite, it would fail. Correct these references, because they are buggy. One test case expected to find_program() a native copy for convenience of testing against natively installed glib. Force it to resolve a native copy. --- cross/armclang-linux.txt | 2 +- cross/linux-mingw-w64-32bit.txt | 2 +- cross/linux-mingw-w64-64bit.txt | 2 +- cross/none.txt | 2 +- cross/ubuntu-armhf.txt | 2 +- docs/markdown/Machine-files.md | 6 +++--- mesonbuild/scripts/env2mfile.py | 2 +- test cases/common/44 pkgconfig-gen/meson.build | 2 +- .../ubuntu-armhf-overrides.txt | 2 +- test cases/unit/36 exe_wrapper behaviour/broken-cross.txt | 2 +- unittests/allplatformstests.py | 4 ++-- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cross/armclang-linux.txt b/cross/armclang-linux.txt index 863b355c345f..36927b882b5b 100644 --- a/cross/armclang-linux.txt +++ b/cross/armclang-linux.txt @@ -22,7 +22,7 @@ c = ['/opt/arm/developmentstudio-2019.0/sw/ARMCompiler6.12/bin/armclang', '--tar #cpp = '/usr/bin/arm-linux-gnueabihf-g++' ar = '/opt/arm/developmentstudio-2019.0/sw/ARMCompiler6.12/bin/armar' #strip = '/usr/arm-linux-gnueabihf/bin/strip' -#pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config' +#pkg-config = '/usr/bin/arm-linux-gnueabihf-pkg-config' [host_machine] system = 'baremetal' diff --git a/cross/linux-mingw-w64-32bit.txt b/cross/linux-mingw-w64-32bit.txt index caf1da1a045f..91ad9c5029a4 100644 --- a/cross/linux-mingw-w64-32bit.txt +++ b/cross/linux-mingw-w64-32bit.txt @@ -4,7 +4,7 @@ cpp = '/usr/bin/i686-w64-mingw32-g++' objc = '/usr/bin/i686-w64-mingw32-gcc' ar = '/usr/bin/i686-w64-mingw32-ar' strip = '/usr/bin/i686-w64-mingw32-strip' -pkgconfig = '/usr/bin/i686-w64-mingw32-pkg-config' +pkg-config = '/usr/bin/i686-w64-mingw32-pkg-config' windres = '/usr/bin/i686-w64-mingw32-windres' exe_wrapper = 'wine' ld = '/usr/bin/i686-w64-mingw32-ld' diff --git a/cross/linux-mingw-w64-64bit.txt b/cross/linux-mingw-w64-64bit.txt index 7403803b4c05..08fa70410430 100644 --- a/cross/linux-mingw-w64-64bit.txt +++ b/cross/linux-mingw-w64-64bit.txt @@ -4,7 +4,7 @@ cpp = '/usr/bin/x86_64-w64-mingw32-g++' objc = '/usr/bin/x86_64-w64-mingw32-gcc' ar = '/usr/bin/x86_64-w64-mingw32-ar' strip = '/usr/bin/x86_64-w64-mingw32-strip' -pkgconfig = '/usr/bin/x86_64-w64-mingw32-pkg-config' +pkg-config = '/usr/bin/x86_64-w64-mingw32-pkg-config' windres = '/usr/bin/x86_64-w64-mingw32-windres' exe_wrapper = 'wine' cmake = '/usr/bin/cmake' diff --git a/cross/none.txt b/cross/none.txt index 1fbe4713ac09..9eadf974c321 100644 --- a/cross/none.txt +++ b/cross/none.txt @@ -15,5 +15,5 @@ fc = ['false'] objc = ['false'] objcpp = ['false'] ar = ['false'] -pkgconfig = ['false'] +pkg-config = ['false'] cmake = ['false'] diff --git a/cross/ubuntu-armhf.txt b/cross/ubuntu-armhf.txt index 408c2ceaecba..6409e396b577 100644 --- a/cross/ubuntu-armhf.txt +++ b/cross/ubuntu-armhf.txt @@ -6,7 +6,7 @@ cpp = ['/usr/bin/arm-linux-gnueabihf-g++'] rust = ['rustc', '--target', 'arm-unknown-linux-gnueabihf', '-C', 'linker=/usr/bin/arm-linux-gnueabihf-gcc-7'] ar = '/usr/arm-linux-gnueabihf/bin/ar' strip = '/usr/arm-linux-gnueabihf/bin/strip' -pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config' +pkg-config = '/usr/bin/arm-linux-gnueabihf-pkg-config' ld = '/usr/bin/arm-linux/gnueabihf-ld' [built-in options] diff --git a/docs/markdown/Machine-files.md b/docs/markdown/Machine-files.md index 9e4b0c2a5f4e..c30076919f5e 100644 --- a/docs/markdown/Machine-files.md +++ b/docs/markdown/Machine-files.md @@ -90,7 +90,7 @@ arch = 'aarch64-linux-gnu' c = arch + '-gcc' cpp = arch + '-g++' strip = arch + '-strip' -pkgconfig = arch + '-pkg-config' +pkg-config = arch + '-pkg-config' ... ``` @@ -165,7 +165,7 @@ c_ld = 'gold' cpp_ld = 'gold' ar = '/usr/i586-mingw32msvc/bin/ar' strip = '/usr/i586-mingw32msvc/bin/strip' -pkgconfig = '/usr/bin/i586-mingw32msvc-pkg-config' +pkg-config = '/usr/bin/i586-mingw32msvc-pkg-config' ``` An incomplete list of internally used programs that can be overridden @@ -179,7 +179,7 @@ here is: - libwmf-config - llvm-config - pcap-config -- pkgconfig +- pkg-config - sdl2-config - wx-config (or wx-3.0-config or wx-config-gtk) diff --git a/mesonbuild/scripts/env2mfile.py b/mesonbuild/scripts/env2mfile.py index 27a7dd969841..df93730424de 100755 --- a/mesonbuild/scripts/env2mfile.py +++ b/mesonbuild/scripts/env2mfile.py @@ -213,7 +213,7 @@ def detect_cross_debianlike(options: T.Any) -> MachineInfo: except ValueError: pass try: - infos.binaries['pkgconfig'] = locate_path("%s-pkg-config" % host_arch) + infos.binaries['pkg-config'] = locate_path("%s-pkg-config" % host_arch) except ValueError: pass # pkg-config is optional try: diff --git a/test cases/common/44 pkgconfig-gen/meson.build b/test cases/common/44 pkgconfig-gen/meson.build index adf3e2765e81..fd6371ef4b92 100644 --- a/test cases/common/44 pkgconfig-gen/meson.build +++ b/test cases/common/44 pkgconfig-gen/meson.build @@ -8,7 +8,7 @@ if not cc.find_library('z', required: false).found() endif # First check we have pkg-config >= 0.29 -pkgconfig = find_program('pkg-config', required: false) +pkgconfig = find_program('pkg-config', native: true, required: false) if not pkgconfig.found() error('MESON_SKIP_TEST: pkg-config not found') endif diff --git a/test cases/unit/33 cross file overrides always args/ubuntu-armhf-overrides.txt b/test cases/unit/33 cross file overrides always args/ubuntu-armhf-overrides.txt index a00a7d1366c7..d687b29817a7 100644 --- a/test cases/unit/33 cross file overrides always args/ubuntu-armhf-overrides.txt +++ b/test cases/unit/33 cross file overrides always args/ubuntu-armhf-overrides.txt @@ -6,7 +6,7 @@ cpp = '/usr/bin/arm-linux-gnueabihf-g++' rust = ['rustc', '--target', 'arm-unknown-linux-gnueabihf', '-C', 'linker=/usr/bin/arm-linux-gnueabihf-gcc-7'] ar = '/usr/arm-linux-gnueabihf/bin/ar' strip = '/usr/arm-linux-gnueabihf/bin/strip' -pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config' +pkg-config = '/usr/bin/arm-linux-gnueabihf-pkg-config' [properties] root = '/usr/arm-linux-gnueabihf' diff --git a/test cases/unit/36 exe_wrapper behaviour/broken-cross.txt b/test cases/unit/36 exe_wrapper behaviour/broken-cross.txt index a5a39318d2c8..3615f92f763d 100644 --- a/test cases/unit/36 exe_wrapper behaviour/broken-cross.txt +++ b/test cases/unit/36 exe_wrapper behaviour/broken-cross.txt @@ -3,7 +3,7 @@ c = '/usr/bin/x86_64-w64-mingw32-gcc' cpp = '/usr/bin/x86_64-w64-mingw32-g++' ar = '/usr/bin/x86_64-w64-mingw32-ar' strip = '/usr/bin/x86_64-w64-mingw32-strip' -pkgconfig = '/usr/bin/x86_64-w64-mingw32-pkg-config' +pkg-config = '/usr/bin/x86_64-w64-mingw32-pkg-config' windres = '/usr/bin/x86_64-w64-mingw32-windres' exe_wrapper = 'broken' diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index b4bf3714a4e8..34bb60fbd099 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -2721,7 +2721,7 @@ def test_native_dep_pkgconfig(self): with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as crossfile: crossfile.write(textwrap.dedent( '''[binaries] - pkgconfig = '{}' + pkg-config = '{}' [properties] @@ -2748,7 +2748,7 @@ def test_pkg_config_libdir(self): with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as crossfile: crossfile.write(textwrap.dedent( '''[binaries] - pkgconfig = 'pkg-config' + pkg-config = 'pkg-config' [properties] pkg_config_libdir = ['{}'] From 01636220dea21a7e3b820d1bb37b4787124424c6 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 5 Aug 2023 11:35:56 +0100 Subject: [PATCH 15/99] tests: Pass a mock C compiler to detect_cpu(), detect_cpu_family() In some cases the desired result can be different if there are no compilers at all. The expectations here are based on there being at least one compiler, so reflect that by providing one; a later test enhancement can cover the case where there are no compilers provided. As a result of the mock any_compiler_has_define(), all that matters will be the distinction between an empty or non-empty dict: the compiler object itself is unused. Signed-off-by: Simon McVittie --- unittests/internaltests.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/unittests/internaltests.py b/unittests/internaltests.py index 672a5a069bc6..ea4231a7c0a0 100644 --- a/unittests/internaltests.py +++ b/unittests/internaltests.py @@ -1596,16 +1596,18 @@ def mock_trial(value: str) -> T.Iterable[None]: ('aarch64_be', 'aarch64'), ] + cc = ClangCCompiler([], [], 'fake', MachineChoice.HOST, False, mock.Mock()) + with mock.patch('mesonbuild.environment.any_compiler_has_define', mock.Mock(return_value=False)): for test, expected in cases: with self.subTest(test, has_define=False), mock_trial(test): - actual = mesonbuild.environment.detect_cpu_family({}) + actual = mesonbuild.environment.detect_cpu_family({'c': cc}) self.assertEqual(actual, expected) with mock.patch('mesonbuild.environment.any_compiler_has_define', mock.Mock(return_value=True)): for test, expected in [('x86_64', 'x86'), ('aarch64', 'arm'), ('ppc', 'ppc64'), ('mips64', 'mips64')]: with self.subTest(test, has_define=True), mock_trial(test): - actual = mesonbuild.environment.detect_cpu_family({}) + actual = mesonbuild.environment.detect_cpu_family({'c': cc}) self.assertEqual(actual, expected) def test_detect_cpu(self) -> None: @@ -1633,16 +1635,18 @@ def mock_trial(value: str) -> T.Iterable[None]: ('aarch64_be', 'aarch64'), ] + cc = ClangCCompiler([], [], 'fake', MachineChoice.HOST, False, mock.Mock()) + with mock.patch('mesonbuild.environment.any_compiler_has_define', mock.Mock(return_value=False)): for test, expected in cases: with self.subTest(test, has_define=False), mock_trial(test): - actual = mesonbuild.environment.detect_cpu({}) + actual = mesonbuild.environment.detect_cpu({'c': cc}) self.assertEqual(actual, expected) with mock.patch('mesonbuild.environment.any_compiler_has_define', mock.Mock(return_value=True)): for test, expected in [('x86_64', 'i686'), ('aarch64', 'arm'), ('ppc', 'ppc64'), ('mips64', 'mips64')]: with self.subTest(test, has_define=True), mock_trial(test): - actual = mesonbuild.environment.detect_cpu({}) + actual = mesonbuild.environment.detect_cpu({'c': cc}) self.assertEqual(actual, expected) def test_interpreter_unpicklable(self) -> None: From fe59f71ac4a20e3250ea10881a2f32b15c1beec9 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 5 Aug 2023 11:13:53 +0100 Subject: [PATCH 16/99] environment: Assume that mips64 can run 32-bit mips binaries The relationship between mips64 and mips is similar to the relationship between x86_64 and x86. Representing it here is necessary so that we will not require an exe_wrapper when cross-compiling for 32-bit mips on mips64, or when a complete 32-bit mips user-space runs on a 64-bit kernel without using linux32 to alter uname(2) to pretend to be 32-bit. Signed-off-by: Simon McVittie --- mesonbuild/environment.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index ff7ae3ae997b..b22539653b0b 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -468,6 +468,7 @@ def machine_info_can_run(machine_info: MachineInfo): return \ (machine_info.cpu_family == true_build_cpu_family) or \ ((true_build_cpu_family == 'x86_64') and (machine_info.cpu_family == 'x86')) or \ + ((true_build_cpu_family == 'mips64') and (machine_info.cpu_family == 'mips')) or \ ((true_build_cpu_family == 'aarch64') and (machine_info.cpu_family == 'arm')) class Environment: From 903020907797411f711c217859bfd8c4d574f0b2 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 5 Aug 2023 11:34:29 +0100 Subject: [PATCH 17/99] environment: Don't override mips64 to mips if no compilers are available If we have a build- or host-architecture compiler, we can detect mips64 vs. mips by the fact that mips64 compilers define __mips64. However, machine_info_can_run() doesn't provide any compilers, because it is interested in the architecture of the underlying kernel. If we don't return mips64 when running on a mips64 kernel, machine_info_can_run() will wrongly say that we can't run mips64 binaries. If we're running a complete 32-bit mips user-space on a mips64 kernel, it's OK to return mips64 in the absence of any compilers, as a result of the previous commit "environment: Assume that mips64 can run 32-bit mips binaries". Resolves: https://github.com/mesonbuild/meson/issues/12017 Bug-Debian: https://bugs.debian.org/1041499 Fixes: 6def03c7 "detect_cpu: Fix mips32 detection on mips64" Signed-off-by: Simon McVittie --- mesonbuild/environment.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index b22539653b0b..e212c7a9919d 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -342,7 +342,7 @@ def detect_cpu_family(compilers: CompilersDict) -> str: # MIPS64 is able to run MIPS32 code natively, so there is a chance that # such mixture mentioned above exists. elif trial == 'mips64': - if not any_compiler_has_define(compilers, '__mips64'): + if compilers and not any_compiler_has_define(compilers, '__mips64'): trial = 'mips' if trial not in known_cpu_families: @@ -382,7 +382,7 @@ def detect_cpu(compilers: CompilersDict) -> str: if '64' not in trial: trial = 'mips' else: - if not any_compiler_has_define(compilers, '__mips64'): + if compilers and not any_compiler_has_define(compilers, '__mips64'): trial = 'mips' else: trial = 'mips64' From 37e6e4dd2343eb3a2f4d2ab0a4c2d901762c3889 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 5 Aug 2023 11:40:04 +0100 Subject: [PATCH 18/99] tests: Assert that mips64 kernel is detected as mips64 with no compilers Reproduces: https://github.com/mesonbuild/meson/issues/12017 Signed-off-by: Simon McVittie --- unittests/internaltests.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/unittests/internaltests.py b/unittests/internaltests.py index ea4231a7c0a0..b4d090dd29c3 100644 --- a/unittests/internaltests.py +++ b/unittests/internaltests.py @@ -1610,6 +1610,16 @@ def mock_trial(value: str) -> T.Iterable[None]: actual = mesonbuild.environment.detect_cpu_family({'c': cc}) self.assertEqual(actual, expected) + # machine_info_can_run calls detect_cpu_family with no compilers at all + with mock.patch( + 'mesonbuild.environment.any_compiler_has_define', + mock.Mock(side_effect=AssertionError('Should not be called')), + ): + for test, expected in [('mips64', 'mips64')]: + with self.subTest(test, has_compiler=False), mock_trial(test): + actual = mesonbuild.environment.detect_cpu_family({}) + self.assertEqual(actual, expected) + def test_detect_cpu(self) -> None: @contextlib.contextmanager @@ -1649,6 +1659,15 @@ def mock_trial(value: str) -> T.Iterable[None]: actual = mesonbuild.environment.detect_cpu({'c': cc}) self.assertEqual(actual, expected) + with mock.patch( + 'mesonbuild.environment.any_compiler_has_define', + mock.Mock(side_effect=AssertionError('Should not be called')), + ): + for test, expected in [('mips64', 'mips64')]: + with self.subTest(test, has_compiler=False), mock_trial(test): + actual = mesonbuild.environment.detect_cpu({}) + self.assertEqual(actual, expected) + def test_interpreter_unpicklable(self) -> None: build = mock.Mock() build.environment = mock.Mock() From 2ad7fe54858b9217bb766228ace19afc34ebb15b Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 21 Jul 2023 16:01:49 -0700 Subject: [PATCH 19/99] build: remove BuildTarget.need_install This would be either the value `kwargs['install']`, or `False`. There isn't any case that `BuildTarget.need_install` handles that `BuildTarget.install` doesn't handle, if we just initialized it correctly. So, just set Target.install correctly in the super initializer, and do away with need_install. --- mesonbuild/build.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 29213b62c8c7..cb931221ed4c 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -719,7 +719,7 @@ def __init__( environment: environment.Environment, compilers: T.Dict[str, 'Compiler'], kwargs): - super().__init__(name, subdir, subproject, True, for_machine, environment) + super().__init__(name, subdir, subproject, True, for_machine, environment, install=kwargs.get('install', False)) self.all_compilers = compilers self.compilers = OrderedDict() # type: OrderedDict[str, Compiler] self.objects: T.List[ObjectTypes] = [] @@ -737,7 +737,6 @@ def __init__( # The list of all files outputted by this target. Useful in cases such # as Vala which generates .vapi and .h besides the compiled output. self.outputs = [self.filename] - self.need_install = False self.pch: T.Dict[str, T.List[str]] = {} self.extra_args: T.Dict[str, T.List['FileOrString']] = {} self.sources: T.List[File] = [] @@ -803,7 +802,7 @@ def is_unity(self) -> bool: return unity_opt == 'on' or (unity_opt == 'subprojects' and self.subproject != '') def validate_install(self): - if self.for_machine is MachineChoice.BUILD and self.need_install: + if self.for_machine is MachineChoice.BUILD and self.install: if self.environment.is_cross_build(): raise InvalidArguments('Tried to install a target for the build machine in a cross build.') else: @@ -1090,7 +1089,6 @@ def process_kwargs(self, kwargs): self.process_kwargs_base(kwargs) self.original_kwargs = kwargs kwargs.get('modules', []) - self.need_install = kwargs.get('install', self.need_install) for lang in all_languages: lang_args = extract_as_list(kwargs, f'{lang}_args') @@ -1325,7 +1323,7 @@ def get_generated_sources(self) -> T.List['GeneratedTypes']: return self.generated def should_install(self) -> bool: - return self.need_install + return self.install def has_pch(self) -> bool: return bool(self.pch) @@ -1400,7 +1398,7 @@ def is_internal(self) -> bool: def link(self, targets): for t in targets: - if isinstance(self, StaticLibrary) and self.need_install: + if isinstance(self, StaticLibrary) and self.install: if isinstance(t, (CustomTarget, CustomTargetIndex)): if not t.should_install(): mlog.warning(f'Try to link an installed static library target {self.name} with a' @@ -1470,7 +1468,7 @@ def link_whole(self, targets): self.objects += [t.extract_all_objects()] # If we install this static library we also need to include objects # from all uninstalled static libraries it depends on. - if self.need_install: + if self.install: for lib in t.get_internal_static_libraries(): self.objects += [lib.extract_all_objects()] self.link_whole_targets.append(t) @@ -2135,7 +2133,7 @@ def is_linkable_target(self): return True def is_internal(self) -> bool: - return not self.need_install + return not self.install class SharedLibrary(BuildTarget): known_kwargs = known_shlib_kwargs From 7f73fc6bdc4fbcbe9e7f4f6e70ece6c99b8f01f2 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 21 Jul 2023 16:03:42 -0700 Subject: [PATCH 20/99] build: remove useless method call This does nothing, so just delete it. --- mesonbuild/build.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index cb931221ed4c..baf6104cdc9a 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1088,7 +1088,6 @@ def get_custom_install_mode(self) -> T.Optional['FileMode']: def process_kwargs(self, kwargs): self.process_kwargs_base(kwargs) self.original_kwargs = kwargs - kwargs.get('modules', []) for lang in all_languages: lang_args = extract_as_list(kwargs, f'{lang}_args') From 10ab9dc6f9f4e4eb0a09d2e31822560fb201f1ae Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 24 Jul 2023 09:45:17 -0700 Subject: [PATCH 21/99] interpreter: stop setting member out of initializer that isn't even used --- mesonbuild/interpreter/interpreter.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 363de547f8a3..b18421d2505a 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -3284,7 +3284,6 @@ def build_target_decorator_caller(self, node, args, kwargs): kwargs['include_directories'] = self.extract_incdirs(kwargs) target = targetclass(name, self.subdir, self.subproject, for_machine, srcs, struct, objs, self.environment, self.compilers[for_machine], kwargs) - target.project_version = self.project_version self.add_target(name, target) self.project_args_frozen = True From 8f6fdb72fd099af1290953ccc272d80794d37bc3 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 18 Jul 2023 21:20:32 -0400 Subject: [PATCH 22/99] Error when an installed static library links to internal custom target When an installed static library A links to an internal static library B built using a custom_target(), raise an error instead of a warning. This is because to be usable, A needs to contain B which would require to extract the archive to get its objects files. This used to work, but was printing a warning and was installing a broken static library, because we used to overlink in many cases, and that got fixed in Meson 1.2.0. It now fails at link time with symbols from the custom target not being defined. It's better to turn the warning into a hard error at configure time. While at it, noticed this situation can happen for any internal custom or rust target we link to, recursively. get_internal_static_libraries_recurse() could be called on CustomTarget objects which do not implement it, and even if we did not call that method, it would still fail when trying to call extract_all_objects() on it. Fixes: #12006 --- mesonbuild/build.py | 59 ++++++++++--------- test cases/rust/5 polyglot static/meson.build | 2 +- .../unit/113 complex link cases/meson.build | 51 ++++++++++++++++ unittests/linuxliketests.py | 3 + 4 files changed, 86 insertions(+), 29 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index baf6104cdc9a..2b537e0b0db5 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1397,17 +1397,6 @@ def is_internal(self) -> bool: def link(self, targets): for t in targets: - if isinstance(self, StaticLibrary) and self.install: - if isinstance(t, (CustomTarget, CustomTargetIndex)): - if not t.should_install(): - mlog.warning(f'Try to link an installed static library target {self.name} with a' - 'custom target that is not installed, this might cause problems' - 'when you try to use this static library') - elif t.is_internal(): - # When we're a static library and we link_with to an - # internal/convenience library, promote to link_whole. - self.link_whole([t]) - continue if not isinstance(t, (Target, CustomTargetIndex)): if isinstance(t, dependencies.ExternalLibrary): raise MesonException(textwrap.dedent('''\ @@ -1420,6 +1409,11 @@ def link(self, targets): raise InvalidArguments(f'{t!r} is not a target.') if not t.is_linkable_target(): raise InvalidArguments(f"Link target '{t!s}' is not linkable.") + if isinstance(self, StaticLibrary) and self.install and t.is_internal(): + # When we're a static library and we link_with to an + # internal/convenience library, promote to link_whole. + self.link_whole([t], promoted=True) + continue if isinstance(self, SharedLibrary) and isinstance(t, StaticLibrary) and not t.pic: msg = f"Can't link non-PIC static library {t.name!r} into shared library {self.name!r}. " msg += "Use the 'pic' option to static_library to build with PIC." @@ -1432,7 +1426,7 @@ def link(self, targets): mlog.warning(msg + ' This will fail in cross build.') self.link_targets.append(t) - def link_whole(self, targets): + def link_whole(self, targets, promoted: bool = False): for t in targets: if isinstance(t, (CustomTarget, CustomTargetIndex)): if not t.is_linkable_target(): @@ -1452,40 +1446,49 @@ def link_whole(self, targets): else: mlog.warning(msg + ' This will fail in cross build.') if isinstance(self, StaticLibrary) and not self.uses_rust(): - if isinstance(t, (CustomTarget, CustomTargetIndex)) or t.uses_rust(): - # There are cases we cannot do this, however. In Rust, for - # example, this can't be done with Rust ABI libraries, though - # it could be done with C ABI libraries, though there are - # several meson issues that need to be fixed: - # https://github.com/mesonbuild/meson/issues/10722 - # https://github.com/mesonbuild/meson/issues/10723 - # https://github.com/mesonbuild/meson/issues/10724 - # FIXME: We could extract the .a archive to get object files - raise InvalidArguments('Cannot link_whole a custom or Rust target into a static library') # When we're a static library and we link_whole: to another static # library, we need to add that target's objects to ourselves. + self.check_can_extract_objects(t, origin=self, promoted=promoted) self.objects += [t.extract_all_objects()] # If we install this static library we also need to include objects # from all uninstalled static libraries it depends on. if self.install: - for lib in t.get_internal_static_libraries(): + for lib in t.get_internal_static_libraries(origin=self): self.objects += [lib.extract_all_objects()] self.link_whole_targets.append(t) @lru_cache(maxsize=None) - def get_internal_static_libraries(self) -> OrderedSet[Target]: + def get_internal_static_libraries(self, origin: StaticLibrary) -> OrderedSet[Target]: result: OrderedSet[Target] = OrderedSet() - self.get_internal_static_libraries_recurse(result) + self.get_internal_static_libraries_recurse(result, origin) return result - def get_internal_static_libraries_recurse(self, result: OrderedSet[Target]) -> None: + def get_internal_static_libraries_recurse(self, result: OrderedSet[Target], origin: StaticLibrary) -> None: for t in self.link_targets: if t.is_internal() and t not in result: + self.check_can_extract_objects(t, origin, promoted=True) result.add(t) - t.get_internal_static_libraries_recurse(result) + t.get_internal_static_libraries_recurse(result, origin) for t in self.link_whole_targets: if t.is_internal(): - t.get_internal_static_libraries_recurse(result) + t.get_internal_static_libraries_recurse(result, origin) + + def check_can_extract_objects(self, t: T.Union[Target, CustomTargetIndex], origin: StaticLibrary, promoted: bool = False) -> None: + if isinstance(t, (CustomTarget, CustomTargetIndex)) or t.uses_rust(): + # To extract objects from a custom target we would have to extract + # the archive, WIP implementation can be found in + # https://github.com/mesonbuild/meson/pull/9218. + # For Rust C ABI we could in theory have access to objects, but there + # are several meson issues that need to be fixed: + # https://github.com/mesonbuild/meson/issues/10722 + # https://github.com/mesonbuild/meson/issues/10723 + # https://github.com/mesonbuild/meson/issues/10724 + m = (f'Cannot link_whole a custom or Rust target {t.name!r} into a static library {origin.name!r}. ' + 'Instead, pass individual object files with the "objects:" keyword argument if possible.') + if promoted: + m += (f' Meson had to promote link to link_whole because {origin.name!r} is installed but not {t.name!r},' + f' and thus has to include objects from {t.name!r} to be usable.') + raise InvalidArguments(m) def add_pch(self, language: str, pchlist: T.List[str]) -> None: if not pchlist: diff --git a/test cases/rust/5 polyglot static/meson.build b/test cases/rust/5 polyglot static/meson.build index 5d1f02368c20..54f383cd3872 100644 --- a/test cases/rust/5 polyglot static/meson.build +++ b/test cases/rust/5 polyglot static/meson.build @@ -7,7 +7,7 @@ r = static_library('stuff', 'stuff.rs', rust_crate_type : 'staticlib') # as it would do with C libraries, but then cannot extract objects from stuff and # thus should error out. # FIXME: We should support this use-case in the future. -testcase expect_error('Cannot link_whole a custom or Rust target into a static library') +testcase expect_error('Cannot link_whole a custom or Rust target \'stuff\' into a static library \'clib\'. Instead, pass individual object files with the "objects:" keyword argument if possible. Meson had to promote link to link_whole because \'clib\' is installed but not \'stuff\', and thus has to include objects from \'stuff\' to be usable.') l = static_library('clib', 'clib.c', link_with : r, install : true) endtestcase diff --git a/test cases/unit/113 complex link cases/meson.build b/test cases/unit/113 complex link cases/meson.build index 04e6281775d5..3b4b898df748 100644 --- a/test cases/unit/113 complex link cases/meson.build +++ b/test cases/unit/113 complex link cases/meson.build @@ -1,5 +1,7 @@ project('complex link cases', 'c') +cc = meson.get_compiler('c') + # In all tests, e1 uses s3 which uses s2 which uses s1. # Executable links with s3 and s1 but not s2 because it is included in s3. @@ -58,3 +60,52 @@ e = executable('t8-e1', 'main.c', link_with: [s1, s2], dependencies: declare_dependency(link_with: s3), ) + +if cc.get_argument_syntax() == 'gcc' + # s1 is an internal static library, using custom target. + s1_o = custom_target( + input: 's1.c', + output: 's1.c.o', + command: [cc.cmd_array(), '-c', '-o', '@OUTPUT@', '@INPUT@'] + ) + s1 = custom_target( + output: 'libt9-s1.a', + command: ['ar', 'rcs', '@OUTPUT@', s1_o], + ) + + # Executable needs to link with s1, s2 and s3. + s2 = static_library('t9-s2', 's2.c', link_with: s1) + s3 = static_library('t9-s3', 's3.c', link_with: s2) + e = executable('t9-e1', 'main.c', link_with: s3) + + # s2 cannot be installed because s1 is not being installed and Meson cannot + # extract object files from the custom target. + testcase expect_error('Cannot link_whole a custom or Rust target \'libt9-s1.a\' into a static library \'t10-s2\'. Instead, pass individual object files with the "objects:" keyword argument if possible. Meson had to promote link to link_whole because \'t10-s2\' is installed but not \'libt9-s1.a\', and thus has to include objects from \'libt9-s1.a\' to be usable.') + s2 = static_library('t10-s2', 's2.c', link_with: s1, install: true) + endtestcase + + # s3 cannot be installed because s1 is not being installed and Meson cannot + # extract object files from the custom target. + testcase expect_error('Cannot link_whole a custom or Rust target \'libt9-s1.a\' into a static library \'t11-s3\'. Instead, pass individual object files with the "objects:" keyword argument if possible. Meson had to promote link to link_whole because \'t11-s3\' is installed but not \'libt9-s1.a\', and thus has to include objects from \'libt9-s1.a\' to be usable.') + s2 = static_library('t11-s2', 's2.c', link_with: s1) + s3 = static_library('t11-s3', 's3.c', link_with: s2, install: true) + endtestcase + + # s1 is an installed static library, using custom target. + s1 = custom_target( + output: 'libt12-s1.a', + command: ['ar', 'rcs', '@OUTPUT@', s1_o], + install: true, + install_dir: get_option('libdir'), + ) + + # Executable needs to link with s1, s2 and s3. + s2 = static_library('t12-s2', 's2.c', link_with: s1, install: true) + s3 = static_library('t12-s3', 's3.c', link_with: s2) + e = executable('t12-e1', 'main.c', link_with: s3) + + # Executable links with s3 and s1 but not s2 because it is included in s3. + s2 = static_library('t13-s2', 's2.c', link_with: s1) + s3 = static_library('t13-s3', 's3.c', link_with: s2, install: true) + e = executable('t13-e1', 'main.c', link_with: s3) +endif diff --git a/unittests/linuxliketests.py b/unittests/linuxliketests.py index 373887401f0d..b5c9b4ee3146 100644 --- a/unittests/linuxliketests.py +++ b/unittests/linuxliketests.py @@ -1847,3 +1847,6 @@ def test_complex_link_cases(self): self.assertIn('build t6-e1: c_LINKER t6-e1.p/main.c.o | libt6-s2.a libt6-s3.a\n', content) self.assertIn('build t7-e1: c_LINKER t7-e1.p/main.c.o | libt7-s3.a\n', content) self.assertIn('build t8-e1: c_LINKER t8-e1.p/main.c.o | libt8-s1.a libt8-s2.a libt8-s3.a\n', content) + self.assertIn('build t9-e1: c_LINKER t9-e1.p/main.c.o | libt9-s1.a libt9-s2.a libt9-s3.a\n', content) + self.assertIn('build t12-e1: c_LINKER t12-e1.p/main.c.o | libt12-s1.a libt12-s2.a libt12-s3.a\n', content) + self.assertIn('build t13-e1: c_LINKER t13-e1.p/main.c.o | libt12-s1.a libt13-s3.a\n', content) From a3d5ec0f2e68da50624a2584a549c6b07a9cc915 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Sun, 6 Aug 2023 13:15:12 -0400 Subject: [PATCH 23/99] machine file: Fix crash on empty value Fixes: #12025 --- mesonbuild/coredata.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 2c7c39e1c50b..1c031c29d8dc 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -992,9 +992,11 @@ def _parse_section(self, s): value = value.replace('\\', '\\\\') try: ast = mparser.Parser(value, 'machinefile').parse() + if not ast.lines: + raise EnvironmentException('value cannot be empty') res = self._evaluate_statement(ast.lines[0]) - except MesonException: - raise EnvironmentException(f'Malformed value in machine file variable {entry!r}.') + except MesonException as e: + raise EnvironmentException(f'Malformed value in machine file variable {entry!r}: {str(e)}.') except KeyError as e: raise EnvironmentException(f'Undefined constant {e.args[0]!r} in machine file variable {entry!r}.') section[entry] = res From da78b969ee3635bbea81909aa9ebdad3c77257a5 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Tue, 8 Aug 2023 02:10:24 +0530 Subject: [PATCH 24/99] Bump versions to 1.2.1 for release --- man/meson.1 | 2 +- mesonbuild/coredata.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/meson.1 b/man/meson.1 index c2c49cfbda40..f59a22714fc0 100644 --- a/man/meson.1 +++ b/man/meson.1 @@ -1,4 +1,4 @@ -.TH MESON "1" "July 2023" "meson 1.2.0" "User Commands" +.TH MESON "1" "August 2023" "meson 1.2.1" "User Commands" .SH NAME meson - a high productivity build system .SH DESCRIPTION diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 1c031c29d8dc..ec6a048d7caf 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -59,7 +59,7 @@ # # Pip requires that RCs are named like this: '0.1.0.rc1' # But the corresponding Git tag needs to be '0.1.0rc1' -version = '1.2.0' +version = '1.2.1' # The next stable version when we are in dev. This is used to allow projects to # require meson version >=1.2.0 when using 1.1.99. FeatureNew won't warn when From f4bd4c311529e31ac6039b642d2c63781d1b38f5 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Wed, 16 Aug 2023 10:18:25 -0400 Subject: [PATCH 25/99] fs.read(): Catch FileNotFoundError --- mesonbuild/modules/fs.py | 4 +++- test cases/common/220 fs module/meson.build | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/mesonbuild/modules/fs.py b/mesonbuild/modules/fs.py index 7d969958838d..53174d2316aa 100644 --- a/mesonbuild/modules/fs.py +++ b/mesonbuild/modules/fs.py @@ -261,8 +261,10 @@ def read(self, state: 'ModuleState', args: T.Tuple['FileOrString'], kwargs: 'Rea try: with open(path, encoding=encoding) as f: data = f.read() + except FileNotFoundError: + raise MesonException(f'File {args[0]} does not exist.') except UnicodeDecodeError: - raise MesonException(f'decoding failed for {path}') + raise MesonException(f'decoding failed for {args[0]}') # Reconfigure when this file changes as it can contain data used by any # part of the build configuration (e.g. `project(..., version: # fs.read_file('VERSION')` or `configure_file(...)` diff --git a/test cases/common/220 fs module/meson.build b/test cases/common/220 fs module/meson.build index a1e9c44fc468..b860fc8a32c8 100644 --- a/test cases/common/220 fs module/meson.build +++ b/test cases/common/220 fs module/meson.build @@ -142,3 +142,7 @@ assert(fs.stem('foo/bar/baz.dll.a') == 'baz.dll', 'failed to get stem with compo subdir('subdir') subproject('subbie') + +testcase expect_error('File notfound does not exist.') + fs.read('notfound') +endtestcase From cc08e3608239de38110aeac120c62a64fa065399 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Thu, 17 Aug 2023 11:14:05 -0400 Subject: [PATCH 26/99] README: Document python requirement history This documents useful to target Meson versions for projects that want to support older Python versions. --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 868728d4181e..f3a2657b7d05 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,11 @@ build system. - [Python](https://python.org) (version 3.7 or newer) - [Ninja](https://ninja-build.org) (version 1.8.2 or newer) +Latest Meson version supporting previous Python versions: +- Python 3.6: **0.61.5** +- Python 3.5: **0.56.2** +- Python 3.4: **0.45.1** + #### Installing from source Meson is available on [PyPi](https://pypi.python.org/pypi/meson), so From 2be9342c662d2cd6c80134bad1fb03fa008079dc Mon Sep 17 00:00:00 2001 From: Tristan Partin Date: Mon, 14 Aug 2023 09:03:42 -0500 Subject: [PATCH 27/99] Remove XML filter from testlog.{json,txt} and std streams This was an unintended consequence of the original patch in #11977. Co-authored-by: Benoit Pierre --- mesonbuild/mtest.py | 12 ++++++------ .../110 replace unencodable xml chars/meson.build | 2 +- unittests/allplatformstests.py | 14 ++++++++++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index 88995c0fedeb..24cf08233299 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -867,10 +867,10 @@ def log(self, harness: 'TestHarness', test: 'TestRun') -> None: et.SubElement(testcase, 'system-out').text = subtest.explanation if test.stdo: out = et.SubElement(suite, 'system-out') - out.text = test.stdo.rstrip() + out.text = replace_unencodable_xml_chars(test.stdo.rstrip()) if test.stde: err = et.SubElement(suite, 'system-err') - err.text = test.stde.rstrip() + err.text = replace_unencodable_xml_chars(test.stde.rstrip()) else: if test.project not in self.suites: suite = self.suites[test.project] = et.Element( @@ -893,10 +893,10 @@ def log(self, harness: 'TestHarness', test: 'TestRun') -> None: suite.attrib['failures'] = str(int(suite.attrib['failures']) + 1) if test.stdo: out = et.SubElement(testcase, 'system-out') - out.text = test.stdo.rstrip() + out.text = replace_unencodable_xml_chars(test.stdo.rstrip()) if test.stde: err = et.SubElement(testcase, 'system-err') - err.text = test.stde.rstrip() + err.text = replace_unencodable_xml_chars(test.stde.rstrip()) async def finish(self, harness: 'TestHarness') -> None: """Calculate total test counts and write out the xml result.""" @@ -1180,9 +1180,9 @@ def decode(stream: T.Union[None, bytes]) -> str: if stream is None: return '' try: - return replace_unencodable_xml_chars(stream.decode('utf-8')) + return stream.decode('utf-8') except UnicodeDecodeError: - return replace_unencodable_xml_chars(stream.decode('iso-8859-1', errors='ignore')) + return stream.decode('iso-8859-1', errors='ignore') async def read_decode(reader: asyncio.StreamReader, queue: T.Optional['asyncio.Queue[T.Optional[str]]'], diff --git a/test cases/unit/110 replace unencodable xml chars/meson.build b/test cases/unit/110 replace unencodable xml chars/meson.build index 2e6b1b7930ad..73485b07325b 100644 --- a/test cases/unit/110 replace unencodable xml chars/meson.build +++ b/test cases/unit/110 replace unencodable xml chars/meson.build @@ -1,4 +1,4 @@ project('replace unencodable xml chars') test_script = find_program('script.py') -test('main', test_script) +test('main', test_script, verbose: true) diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index 34bb60fbd099..82bfca9b3d51 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -431,9 +431,8 @@ def test_replace_unencodable_xml_chars(self): valid_string = base_string_valid + repr(invalid_string)[1:-1] + base_string_valid invalid_string = base_string_invalid + invalid_string + base_string_invalid - broken_xml_stream = invalid_string.encode() - decoded_broken_stream = mtest.decode(broken_xml_stream) - self.assertEqual(decoded_broken_stream, valid_string) + fixed_string = mtest.replace_unencodable_xml_chars(invalid_string) + self.assertEqual(fixed_string, valid_string) def test_replace_unencodable_xml_chars_unit(self): ''' @@ -445,9 +444,16 @@ def test_replace_unencodable_xml_chars_unit(self): raise SkipTest('xmllint not installed') testdir = os.path.join(self.unit_test_dir, '110 replace unencodable xml chars') self.init(testdir) - self.run_tests() + tests_command_output = self.run_tests() junit_xml_logs = Path(self.logdir, 'testlog.junit.xml') subprocess.run(['xmllint', junit_xml_logs], check=True) + # Ensure command output and JSON / text logs are not mangled. + raw_output_sample = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b' + assert raw_output_sample in tests_command_output + text_log = Path(self.logdir, 'testlog.txt').read_text() + assert raw_output_sample in text_log + json_log = json.loads(Path(self.logdir, 'testlog.json').read_bytes()) + assert raw_output_sample in json_log['stdout'] def test_run_target_files_path(self): ''' From 0c5652b4ebc5edd00187a92ea8bab8697bd3761b Mon Sep 17 00:00:00 2001 From: Benoit Pierre Date: Mon, 14 Aug 2023 19:45:35 +0200 Subject: [PATCH 28/99] tests: fix assertion rewriting when pytest is used --- run_unittests.py | 2 +- setup.cfg | 2 +- unittests/__init__.py | 0 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 unittests/__init__.py diff --git a/run_unittests.py b/run_unittests.py index 4dd674d346e1..7a2502a6e886 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -136,7 +136,7 @@ def main(): # Let there be colors! if 'CI' in os.environ: pytest_args += ['--color=yes'] - pytest_args += ['./run_unittests.py'] + pytest_args += ['unittests'] pytest_args += convert_args(sys.argv[1:]) # Always disable pytest-cov because we use a custom setup try: diff --git a/setup.cfg b/setup.cfg index a23af07c6cd3..dfaba76dd194 100644 --- a/setup.cfg +++ b/setup.cfg @@ -62,4 +62,4 @@ include = mesonbuild, mesonbuild.* [tool:pytest] python_classes = python_files = - run_unittests.py + unittests/*tests.py diff --git a/unittests/__init__.py b/unittests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 From 453c6df10ffa8cf1788db7de21a012d874f45a08 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 15 Aug 2023 13:06:45 -0400 Subject: [PATCH 29/99] ninja backend: fix the automatic restat of outputs when reconfiguring The most notable problem this causes is that when running `meson setup --reconfigure` the build.ninja file is erroneously seen as out of date, so ninja immediately tries to regenerate it again as it didn't see the file get updated. There are two problems. The first problem is that we looked for the wrong file. Ninja creates a few internal files, and one of them is the one we care about: `.ninja_log`, which contains stat'ed timestamps for build outputs to aid in checking when things are out of date. But the thing we actually checked for is `.ninja_deps`, a file that contains a compressed database of depfile outputs. If the latter exists, then the former surely exists too. Checking for the wrong file meant that we would restat outputs, but only when some build edges were previously built that had depfile outputs. The second problem is that we checked for this in os.getcwd() instead of the configured build directory. This very easily fails to be correct, except when reconfigure is triggered directly by ninja itself, in which case we didn't need the restat to begin with. --- mesonbuild/backend/ninjabackend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index f211f168c365..c583c3e5cca2 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -658,9 +658,9 @@ def generate(self, capture: bool = False, vslite_ctx: dict = None) -> T.Optional os.replace(tempfilename, outfilename) mlog.cmd_ci_include(outfilename) # For CI debugging # Refresh Ninja's caches. https://github.com/ninja-build/ninja/pull/1685 - if mesonlib.version_compare(self.ninja_version, '>=1.10.0') and os.path.exists('.ninja_deps'): - subprocess.call(self.ninja_command + ['-t', 'restat']) - subprocess.call(self.ninja_command + ['-t', 'cleandead']) + if mesonlib.version_compare(self.ninja_version, '>=1.10.0') and os.path.exists(os.path.join(self.environment.build_dir, '.ninja_log')): + subprocess.call(self.ninja_command + ['-t', 'restat'], cwd=self.environment.build_dir) + subprocess.call(self.ninja_command + ['-t', 'cleandead'], cwd=self.environment.build_dir) self.generate_compdb() self.generate_rust_project_json() From 05919c7d8b373df38f8c23ea3c70991cd216e9eb Mon Sep 17 00:00:00 2001 From: David Seifert Date: Tue, 22 Aug 2023 18:34:02 +0200 Subject: [PATCH 30/99] Fix completely broken support for `static: true` with dependency('cuda') --- mesonbuild/dependencies/cuda.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mesonbuild/dependencies/cuda.py b/mesonbuild/dependencies/cuda.py index af0ae4b1f569..fac66de535de 100644 --- a/mesonbuild/dependencies/cuda.py +++ b/mesonbuild/dependencies/cuda.py @@ -45,8 +45,16 @@ def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> No super().__init__('cuda', environment, kwargs, language=language) self.lib_modules: T.Dict[str, T.List[str]] = {} self.requested_modules = self.get_requested(kwargs) - if 'cudart' not in self.requested_modules: - self.requested_modules = ['cudart'] + self.requested_modules + if not any(runtime in self.requested_modules for runtime in ['cudart', 'cudart_static']): + req_modules = ['cudart'] + if kwargs.get('static', False): + req_modules = ['cudart_static'] + machine = self.env.machines[self.for_machine] + if machine.is_linux(): + # extracted by running + # nvcc -v foo.o + req_modules += ['rt', 'pthread', 'dl'] + self.requested_modules = req_modules + self.requested_modules (self.cuda_path, self.version, self.is_found) = self._detect_cuda_path_and_version() if not self.is_found: From d58ceeb65b2d31e3c0037246f97253b595f59dc9 Mon Sep 17 00:00:00 2001 From: David Seifert Date: Tue, 22 Aug 2023 18:34:03 +0200 Subject: [PATCH 31/99] Use `cudart_static` by default in dependency('cuda') * Without this, using nvcc as the sole driver vs dependency('cuda') and host compiler driver yields differently linked binaries. --- mesonbuild/dependencies/cuda.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mesonbuild/dependencies/cuda.py b/mesonbuild/dependencies/cuda.py index fac66de535de..f1c890ba807b 100644 --- a/mesonbuild/dependencies/cuda.py +++ b/mesonbuild/dependencies/cuda.py @@ -46,8 +46,10 @@ def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> No self.lib_modules: T.Dict[str, T.List[str]] = {} self.requested_modules = self.get_requested(kwargs) if not any(runtime in self.requested_modules for runtime in ['cudart', 'cudart_static']): + # By default, we prefer to link the static CUDA runtime, since this is what nvcc also does by default: + # https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#cudart-none-shared-static-cudart req_modules = ['cudart'] - if kwargs.get('static', False): + if kwargs.get('static', True): req_modules = ['cudart_static'] machine = self.env.machines[self.for_machine] if machine.is_linux(): From f34d227e9cfb75d2e47bcbec793532f1986c0a91 Mon Sep 17 00:00:00 2001 From: M Henning Date: Tue, 8 Aug 2023 00:54:30 -0400 Subject: [PATCH 32/99] Suggest fix in MesonVersionMismatchException Every time I update meson, I spend about 20 minutes on frustrated googling to figure out how to update my build directory to work with the new version. I'm forgetful, okay? Ease this pain point by suggesting a potential fix in the error message. --- mesonbuild/coredata.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index ec6a048d7caf..346941b039fd 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -91,7 +91,8 @@ class MesonVersionMismatchException(MesonException): '''Build directory generated with Meson version is incompatible with current version''' def __init__(self, old_version: str, current_version: str) -> None: super().__init__(f'Build directory has been generated with Meson version {old_version}, ' - f'which is incompatible with the current version {current_version}.') + f'which is incompatible with the current version {current_version}. ' + f'Consider reconfiguring the directory with meson setup --reconfigure.') self.old_version = old_version self.current_version = current_version From f381764ee3fa61c2e982a0ab5374e8a969f00ebf Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Wed, 23 Aug 2023 09:09:06 -0400 Subject: [PATCH 33/99] Suggest using --reconfigure only when not already using it --- mesonbuild/coredata.py | 10 +++++----- mesonbuild/environment.py | 4 ++-- mesonbuild/utils/universal.py | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 346941b039fd..ddce45c02ff5 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -89,10 +89,10 @@ def get_genvs_default_buildtype_list() -> list: class MesonVersionMismatchException(MesonException): '''Build directory generated with Meson version is incompatible with current version''' - def __init__(self, old_version: str, current_version: str) -> None: + def __init__(self, old_version: str, current_version: str, extra_msg: str = '') -> None: super().__init__(f'Build directory has been generated with Meson version {old_version}, ' - f'which is incompatible with the current version {current_version}. ' - f'Consider reconfiguring the directory with meson setup --reconfigure.') + f'which is incompatible with the current version {current_version}.' + + extra_msg) self.old_version = old_version self.current_version = current_version @@ -1093,9 +1093,9 @@ def major_versions_differ(v1: str, v2: str) -> bool: # Major version differ, or one is development version but not the other. return v1_major != v2_major or ('99' in {v1_minor, v2_minor} and v1_minor != v2_minor) -def load(build_dir: str) -> CoreData: +def load(build_dir: str, suggest_reconfigure: bool = True) -> CoreData: filename = os.path.join(build_dir, 'meson-private', 'coredata.dat') - return pickle_load(filename, 'Coredata', CoreData) + return pickle_load(filename, 'Coredata', CoreData, suggest_reconfigure) def save(obj: CoreData, build_dir: str) -> str: diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index e212c7a9919d..e24cff054431 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -489,7 +489,7 @@ def __init__(self, source_dir: T.Optional[str], build_dir: T.Optional[str], opti os.makedirs(self.log_dir, exist_ok=True) os.makedirs(self.info_dir, exist_ok=True) try: - self.coredata = coredata.load(self.get_build_dir()) # type: coredata.CoreData + self.coredata: coredata.CoreData = coredata.load(self.get_build_dir(), suggest_reconfigure=False) self.first_invocation = False except FileNotFoundError: self.create_new_coredata(options) @@ -507,7 +507,7 @@ def __init__(self, source_dir: T.Optional[str], build_dir: T.Optional[str], opti coredata.read_cmd_line_file(self.build_dir, options) self.create_new_coredata(options) else: - raise e + raise MesonException(f'{str(e)} Try regenerating using "meson setup --wipe".') else: # Just create a fresh coredata in this case self.scratch_dir = '' diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py index 8cfc04d53285..509565876bf9 100644 --- a/mesonbuild/utils/universal.py +++ b/mesonbuild/utils/universal.py @@ -2383,22 +2383,22 @@ def is_base(self) -> bool: return self.type is OptionType.BASE -def pickle_load(filename: str, object_name: str, object_type: T.Type[_PL]) -> _PL: - load_fail_msg = f'{object_name} file {filename!r} is corrupted. Try with a fresh build tree.' +def pickle_load(filename: str, object_name: str, object_type: T.Type[_PL], suggest_reconfigure: bool = True) -> _PL: + load_fail_msg = f'{object_name} file {filename!r} is corrupted.' + extra_msg = ' Consider reconfiguring the directory with "meson setup --reconfigure".' if suggest_reconfigure else '' try: with open(filename, 'rb') as f: obj = pickle.load(f) except (pickle.UnpicklingError, EOFError): - raise MesonException(load_fail_msg) + raise MesonException(load_fail_msg + extra_msg) except (TypeError, ModuleNotFoundError, AttributeError): - build_dir = os.path.dirname(os.path.dirname(filename)) raise MesonException( f"{object_name} file {filename!r} references functions or classes that don't " "exist. This probably means that it was generated with an old " - "version of meson. Try running from the source directory " - f'meson setup {build_dir} --wipe') + "version of meson." + extra_msg) + if not isinstance(obj, object_type): - raise MesonException(load_fail_msg) + raise MesonException(load_fail_msg + extra_msg) # Because these Protocols are not available at runtime (and cannot be made # available at runtime until we drop support for Python < 3.8), we have to @@ -2412,7 +2412,7 @@ def pickle_load(filename: str, object_name: str, object_type: T.Type[_PL]) -> _P from ..coredata import version as coredata_version from ..coredata import major_versions_differ, MesonVersionMismatchException if major_versions_differ(version, coredata_version): - raise MesonVersionMismatchException(version, coredata_version) + raise MesonVersionMismatchException(version, coredata_version, extra_msg) return obj From 698a0cab52469c7eaff49fa511e38c59a65a8269 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Sun, 27 Aug 2023 11:02:09 -0400 Subject: [PATCH 34/99] gnome: Fix crash in gtkdoc and generate_gir in C++ projects gtkdoc() and generate_gir() methods assumes there is a C compiler, but pure C++ projects might not add it explicitly. Fixes: #12162 --- mesonbuild/modules/__init__.py | 2 ++ mesonbuild/modules/gnome.py | 6 ++++++ .../frameworks/36 gtkdoc cpp/foo-docs.xml | 16 ++++++++++++++++ test cases/frameworks/36 gtkdoc cpp/foo.cpp | 5 +++++ test cases/frameworks/36 gtkdoc cpp/foo.h | 1 + test cases/frameworks/36 gtkdoc cpp/meson.build | 13 +++++++++++++ test cases/frameworks/36 gtkdoc cpp/test.json | 17 +++++++++++++++++ test cases/frameworks/37 gir cpp/foo.cpp | 5 +++++ test cases/frameworks/37 gir cpp/foo.h | 1 + test cases/frameworks/37 gir cpp/meson.build | 16 ++++++++++++++++ test cases/frameworks/37 gir cpp/test.json | 3 +++ 11 files changed, 85 insertions(+) create mode 100644 test cases/frameworks/36 gtkdoc cpp/foo-docs.xml create mode 100644 test cases/frameworks/36 gtkdoc cpp/foo.cpp create mode 100644 test cases/frameworks/36 gtkdoc cpp/foo.h create mode 100644 test cases/frameworks/36 gtkdoc cpp/meson.build create mode 100644 test cases/frameworks/36 gtkdoc cpp/test.json create mode 100644 test cases/frameworks/37 gir cpp/foo.cpp create mode 100644 test cases/frameworks/37 gir cpp/foo.h create mode 100644 test cases/frameworks/37 gir cpp/meson.build create mode 100644 test cases/frameworks/37 gir cpp/test.json diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index daac9edb6dab..7ef87b23a130 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -167,6 +167,8 @@ def process_include_dirs(self, dirs: T.Iterable[T.Union[str, IncludeDirs]]) -> T else: yield self._interpreter.build_incdir_object([d]) + def add_language(self, lang: str, for_machine: MachineChoice) -> None: + self._interpreter.add_languages([lang], True, for_machine) class ModuleObject(HoldableObject): """Base class for all objects returned by modules diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 7a9acea0009f..d9b6bf1a54d6 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -1113,6 +1113,9 @@ def _get_scanner_ldflags(ldflags: T.Iterable[str]) -> T.Iterable[str]: ) def generate_gir(self, state: 'ModuleState', args: T.Tuple[T.List[T.Union[build.Executable, build.SharedLibrary, build.StaticLibrary]]], kwargs: 'GenerateGir') -> ModuleReturnValue: + # Ensure we have a C compiler even in C++ projects. + state.add_language('c', MachineChoice.HOST) + girtargets = [self._unwrap_gir_target(arg, state) for arg in args[0]] if len(girtargets) > 1 and any(isinstance(el, build.Executable) for el in girtargets): raise MesonException('generate_gir only accepts a single argument when one of the arguments is an executable') @@ -1427,6 +1430,9 @@ def gtkdoc(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'GtkDoc') -> namespace = kwargs['namespace'] + # Ensure we have a C compiler even in C++ projects. + state.add_language('c', MachineChoice.HOST) + def abs_filenames(files: T.Iterable['FileOrString']) -> T.Iterator[str]: for f in files: if isinstance(f, mesonlib.File): diff --git a/test cases/frameworks/36 gtkdoc cpp/foo-docs.xml b/test cases/frameworks/36 gtkdoc cpp/foo-docs.xml new file mode 100644 index 000000000000..85c673c57b4b --- /dev/null +++ b/test cases/frameworks/36 gtkdoc cpp/foo-docs.xml @@ -0,0 +1,16 @@ + + + +]> + + + Foo Reference Manual + + + + GLib Core Application Support + + + diff --git a/test cases/frameworks/36 gtkdoc cpp/foo.cpp b/test cases/frameworks/36 gtkdoc cpp/foo.cpp new file mode 100644 index 000000000000..15fa269806a2 --- /dev/null +++ b/test cases/frameworks/36 gtkdoc cpp/foo.cpp @@ -0,0 +1,5 @@ +#include "foo.h" + +int foo_do_something(void) { + return 42; +} diff --git a/test cases/frameworks/36 gtkdoc cpp/foo.h b/test cases/frameworks/36 gtkdoc cpp/foo.h new file mode 100644 index 000000000000..cac03d3c1a70 --- /dev/null +++ b/test cases/frameworks/36 gtkdoc cpp/foo.h @@ -0,0 +1 @@ +int foo_do_something(void); diff --git a/test cases/frameworks/36 gtkdoc cpp/meson.build b/test cases/frameworks/36 gtkdoc cpp/meson.build new file mode 100644 index 000000000000..747eae546741 --- /dev/null +++ b/test cases/frameworks/36 gtkdoc cpp/meson.build @@ -0,0 +1,13 @@ +project('gnome module without C', 'cpp') + +gtkdoc = find_program('gtkdoc-scan', required: false) +if not gtkdoc.found() + error('MESON_SKIP_TEST gtkdoc not found.') +endif + +gnome = import('gnome') + +lib = library('foo++', 'foo.cpp') +gnome.gtkdoc('foo', + src_dir: '.', + main_xml : 'foo-docs.xml',) diff --git a/test cases/frameworks/36 gtkdoc cpp/test.json b/test cases/frameworks/36 gtkdoc cpp/test.json new file mode 100644 index 000000000000..b2d9bc88f6a0 --- /dev/null +++ b/test cases/frameworks/36 gtkdoc cpp/test.json @@ -0,0 +1,17 @@ +{ + "installed": [ + {"type": "file", "file": "usr/share/gtk-doc/html/foo/up-insensitive.png"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/home.png"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/foo.html"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/foo-foo.html"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/style.css"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/index.html"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/foo.devhelp2"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/left.png"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/left-insensitive.png"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/right-insensitive.png"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/up.png"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foo/right.png"} + ], + "skip_on_jobname": ["azure", "msys2"] +} diff --git a/test cases/frameworks/37 gir cpp/foo.cpp b/test cases/frameworks/37 gir cpp/foo.cpp new file mode 100644 index 000000000000..15fa269806a2 --- /dev/null +++ b/test cases/frameworks/37 gir cpp/foo.cpp @@ -0,0 +1,5 @@ +#include "foo.h" + +int foo_do_something(void) { + return 42; +} diff --git a/test cases/frameworks/37 gir cpp/foo.h b/test cases/frameworks/37 gir cpp/foo.h new file mode 100644 index 000000000000..cac03d3c1a70 --- /dev/null +++ b/test cases/frameworks/37 gir cpp/foo.h @@ -0,0 +1 @@ +int foo_do_something(void); diff --git a/test cases/frameworks/37 gir cpp/meson.build b/test cases/frameworks/37 gir cpp/meson.build new file mode 100644 index 000000000000..c8bf4281250c --- /dev/null +++ b/test cases/frameworks/37 gir cpp/meson.build @@ -0,0 +1,16 @@ +project('gnome module without C', 'cpp') + +gi = dependency('gobject-introspection-1.0', required: false) +if not gi.found() + error('MESON_SKIP_TEST gobject-introspection not found.') +endif + +gnome = import('gnome') + +lib = library('foo++', 'foo.cpp') +gnome.generate_gir( + lib, + sources: ['foo.cpp', 'foo.h'], + namespace: 'foo', + nsversion: meson.project_version(), +) diff --git a/test cases/frameworks/37 gir cpp/test.json b/test cases/frameworks/37 gir cpp/test.json new file mode 100644 index 000000000000..a9d74fb8a9b0 --- /dev/null +++ b/test cases/frameworks/37 gir cpp/test.json @@ -0,0 +1,3 @@ +{ + "skip_on_jobname": ["azure", "macos", "msys2"] +} From 2fe793a37cc05249b8cee24c4d38f25ed7e620be Mon Sep 17 00:00:00 2001 From: Charles Brunet Date: Wed, 30 Aug 2023 10:37:40 -0400 Subject: [PATCH 35/99] Disable failing test on cygwin due to broken cmake See https://gitlab.kitware.com/cmake/cmake/-/issues/25200. --- test cases/linuxlike/13 cmake dependency/meson.build | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test cases/linuxlike/13 cmake dependency/meson.build b/test cases/linuxlike/13 cmake dependency/meson.build index 193ad184b637..f612e1d52d6d 100644 --- a/test cases/linuxlike/13 cmake dependency/meson.build +++ b/test cases/linuxlike/13 cmake dependency/meson.build @@ -2,13 +2,20 @@ # due to use of setup_env.json project('external CMake dependency', ['c', 'cpp']) -if not find_program('cmake', required: false).found() +cmake = find_program('cmake', required: false) +if not cmake.found() error('MESON_SKIP_TEST cmake binary not available.') endif # Zlib is probably on all dev machines. dep = dependency('ZLIB', version : '>=1.2', method : 'cmake') + +if '#define' in dep.version() and cmake.version().version_compare('< 3.27.4') + # ZLIB 1.3 version is broken with those cmake versions + error('MESON_SKIP_TEST known bug in cmake (https://gitlab.kitware.com/cmake/cmake/-/issues/25200)') +endif + exe = executable('zlibprog', 'prog-checkver.c', dependencies : dep, c_args : '-DFOUND_ZLIB="' + dep.version() + '"') From 2c80162ca01c9124e9da97e558f240e2fdbe91c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Fri, 1 Sep 2023 02:08:53 +0100 Subject: [PATCH 36/99] compilers: fix compiler detection when the "ccache" string is in the path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- mesonbuild/compilers/detect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py index 210ec4d4065a..58d6f4e64e58 100644 --- a/mesonbuild/compilers/detect.py +++ b/mesonbuild/compilers/detect.py @@ -1034,7 +1034,7 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust extra_args['machine'] = cc.linker.machine else: exelist = cc.linker.exelist + cc.linker.get_always_args() - if 'ccache' in exelist[0]: + if os.path.basename(exelist[0]) in {'ccache', 'sccache'}: del exelist[0] c = exelist.pop(0) compiler.extend(cls.use_linker_args(c, '')) From 6dba828b92093dc04bda541505f46503ab7a17bd Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Wed, 30 Aug 2023 13:36:31 -0400 Subject: [PATCH 37/99] tests: make run_project_tests finish off the verbose logs with a summary List each testcase name that failed so we can see at a glance which ones they are. --- run_project_tests.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/run_project_tests.py b/run_project_tests.py index facf1e98f6af..42fee6efcc2f 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -288,6 +288,7 @@ def __lt__(self, other: object) -> bool: return (s_id, self.path, self.name or '') < (o_id, other.path, other.name or '') return NotImplemented +failing_testcases: T.List[str] = [] failing_logs: T.List[str] = [] print_debug = 'MESON_PRINT_TEST_OUTPUT' in os.environ under_ci = 'CI' in os.environ @@ -1369,6 +1370,7 @@ def tqdm_print(*args: mlog.TV_Loggable, sep: str = ' ') -> None: left_w = max(3, left_w) right_w = cols - left_w - name_len - 2 right_w = max(3, right_w) + failing_testcases.append(name_str) failing_logs.append(f'\n\x1b[31m{"="*left_w}\x1b[0m {name_str} \x1b[31m{"="*right_w}\x1b[0m\n') if result.step == BuildStep.configure and result.mlog != no_meson_log_msg: # For configure failures, instead of printing stdout, @@ -1635,6 +1637,9 @@ def clear_transitive_files() -> None: print(l, '\n') except UnicodeError: print(l.encode('ascii', errors='replace').decode(), '\n') + print('All failures:') + for c in failing_testcases: + print(f' -> {c}') for name, dirs, _ in all_tests: dir_names = list({x.path.name for x in dirs}) for k, g in itertools.groupby(dir_names, key=lambda x: x.split()[0]): From f0546249311e0df3c1d6305f67b940fee1124fea Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Wed, 30 Aug 2023 13:58:34 -0400 Subject: [PATCH 38/99] tests: make summary section for project tests more like pytest Logs for failing tests come first, then the list of pass/fail. --- run_project_tests.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/run_project_tests.py b/run_project_tests.py index 42fee6efcc2f..0bb4206b5f83 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -1626,10 +1626,6 @@ def clear_transitive_files() -> None: (passing_tests, failing_tests, skipped_tests) = res except StopException: pass - print() - print('Total passed tests: ', green(str(passing_tests))) - print('Total failed tests: ', red(str(failing_tests))) - print('Total skipped tests:', yellow(str(skipped_tests))) if failing_tests > 0: print('\nMesonlogs of failing tests\n') for l in failing_logs: @@ -1637,7 +1633,12 @@ def clear_transitive_files() -> None: print(l, '\n') except UnicodeError: print(l.encode('ascii', errors='replace').decode(), '\n') - print('All failures:') + print() + print('Total passed tests: ', green(str(passing_tests))) + print('Total failed tests: ', red(str(failing_tests))) + print('Total skipped tests:', yellow(str(skipped_tests))) + if failing_tests > 0: + print('\nAll failures:') for c in failing_testcases: print(f' -> {c}') for name, dirs, _ in all_tests: From fa91413f349ffa8cfc5ea4aaa227acf42129fdcc Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Wed, 30 Aug 2023 14:04:40 -0400 Subject: [PATCH 39/99] tests: sync ninja stdout/stderr instead of listing them separately It is fairly confusing for all the "ninja explain" to be the last thing you see, instead of the compile error. --- run_project_tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run_project_tests.py b/run_project_tests.py index 0bb4206b5f83..7aa991672901 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -699,8 +699,8 @@ def _run_test(test: TestDef, # Build with subprocess def build_step() -> None: build_start = time.time() - pc, o, e = Popen_safe(compile_commands + dir_args, cwd=test_build_dir) - testresult.add_step(BuildStep.build, o, e, '', time.time() - build_start) + pc, o, _ = Popen_safe(compile_commands + dir_args, cwd=test_build_dir, stderr=subprocess.STDOUT) + testresult.add_step(BuildStep.build, o, '', '', time.time() - build_start) if should_fail == 'build': if pc.returncode != 0: raise testresult From 36e20691530a4ab5737b19ad6933be4d22f16cad Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Wed, 30 Aug 2023 16:47:46 -0400 Subject: [PATCH 40/99] tests: move the newline to the right place in ci includes Make sure this is generic enough to be properly usable --- run_project_tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/run_project_tests.py b/run_project_tests.py index 7aa991672901..ae2696b0a730 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -433,9 +433,9 @@ def _run_ci_include(args: T.List[str]) -> str: return 'At least one parameter required' try: data = Path(args[0]).read_text(errors='ignore', encoding='utf-8') - return f'{header}\n{data}\n{footer}' + return f'{header}\n{data}\n{footer}\n' except Exception: - return 'Failed to open {}'.format(args[0]) + return 'Failed to open {}\n'.format(args[0]) ci_commands = { 'ci_include': _run_ci_include @@ -449,7 +449,7 @@ def run_ci_commands(raw_log: str) -> T.List[str]: cmd = shlex.split(l[11:]) if not cmd or cmd[0] not in ci_commands: continue - res += ['CI COMMAND {}:\n{}\n'.format(cmd[0], ci_commands[cmd[0]](cmd[1:]))] + res += ['CI COMMAND {}:\n{}'.format(cmd[0], ci_commands[cmd[0]](cmd[1:]))] return res class OutputMatch: From 10e67b207e42bf418a83023d75bbd8a0a767ddd7 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Wed, 30 Aug 2023 14:20:41 -0400 Subject: [PATCH 41/99] tests: move a couple log files into collapsed github groups where possible --- run_project_tests.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/run_project_tests.py b/run_project_tests.py index ae2696b0a730..f91af26cf443 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -553,11 +553,11 @@ def run_test_inprocess(testdir: str) -> T.Tuple[int, str, str, str]: sys.stderr = mystderr = StringIO() old_cwd = os.getcwd() os.chdir(testdir) - test_log_fname = Path('meson-logs', 'testlog.txt') + test_log_fname = os.path.join('meson-logs', 'testlog.txt') try: returncode_test = mtest.run_with_args(['--no-rebuild']) - if test_log_fname.exists(): - test_log = test_log_fname.open(encoding='utf-8', errors='ignore').read() + if os.path.exists(test_log_fname): + test_log = _run_ci_include([test_log_fname]) else: test_log = '' returncode_benchmark = mtest.run_with_args(['--no-rebuild', '--benchmark', '--logbase', 'benchmarklog']) @@ -667,11 +667,10 @@ def _run_test(test: TestDef, returncode, stdo, stde = res cmd = '(inprocess) $ ' if inprocess else '$ ' cmd += mesonlib.join_args(gen_args) - try: - logfile = Path(test_build_dir, 'meson-logs', 'meson-log.txt') - with logfile.open(errors='ignore', encoding='utf-8') as fid: - mesonlog = '\n'.join((cmd, fid.read())) - except Exception: + logfile = os.path.join(test_build_dir, 'meson-logs', 'meson-log.txt') + if os.path.exists(logfile): + mesonlog = '\n'.join((cmd, _run_ci_include([logfile]))) + else: mesonlog = no_meson_log_msg cicmds = run_ci_commands(mesonlog) testresult = TestResult(cicmds) From 74766c8c89373d568815553894e20fdf82941369 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Thu, 31 Aug 2023 17:17:55 -0400 Subject: [PATCH 42/99] tests: repeat the failure reason in the detailed logs --- run_project_tests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/run_project_tests.py b/run_project_tests.py index f91af26cf443..284210ffe2a2 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -1371,6 +1371,9 @@ def tqdm_print(*args: mlog.TV_Loggable, sep: str = ' ') -> None: right_w = max(3, right_w) failing_testcases.append(name_str) failing_logs.append(f'\n\x1b[31m{"="*left_w}\x1b[0m {name_str} \x1b[31m{"="*right_w}\x1b[0m\n') + _during = bold('Failed during:') + _reason = bold('Reason:') + failing_logs.append(f'{_during} {result.step.name}\n{_reason} {result.msg}\n') if result.step == BuildStep.configure and result.mlog != no_meson_log_msg: # For configure failures, instead of printing stdout, # print the meson log if available since it's a superset From 167f524aad2230895e7da878efb10949bb9fa2ee Mon Sep 17 00:00:00 2001 From: Charles Brunet Date: Tue, 5 Sep 2023 13:43:20 -0400 Subject: [PATCH 43/99] qt module: fix substitution for depfile in moc --- mesonbuild/modules/qt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/modules/qt.py b/mesonbuild/modules/qt.py index 85558885343a..80663358f24b 100644 --- a/mesonbuild/modules/qt.py +++ b/mesonbuild/modules/qt.py @@ -472,7 +472,7 @@ def _compile_moc_impl(self, state: 'ModuleState', kwargs: 'MocCompilerKwArgs') - if kwargs['sources']: moc_gen = build.Generator( self.tools['moc'], arguments, ['@BASENAME@.moc'], - depfile='@BASENAME.moc.d@', + depfile='@BASENAME@.moc.d', name=f'Qt{self.qt_version} moc source') output.append(moc_gen.process_files(kwargs['sources'], state)) From 5ec9162e549cb133bd898a5374a6b39265900c74 Mon Sep 17 00:00:00 2001 From: Charles Brunet Date: Tue, 5 Sep 2023 13:51:18 -0400 Subject: [PATCH 44/99] qt module: add include_directories to moc compile Fixes #12182 --- mesonbuild/modules/qt.py | 7 +++++-- test cases/frameworks/4 qt/manualinclude.cpp | 1 + test cases/frameworks/4 qt/meson.build | 13 ++++++++++--- test cases/frameworks/4 qt/mocdep/meson.build | 3 +++ test cases/frameworks/4 qt/mocdep/mocdep.h | 1 + 5 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 test cases/frameworks/4 qt/mocdep/meson.build create mode 100644 test cases/frameworks/4 qt/mocdep/mocdep.h diff --git a/mesonbuild/modules/qt.py b/mesonbuild/modules/qt.py index 80663358f24b..ad438db65e0f 100644 --- a/mesonbuild/modules/qt.py +++ b/mesonbuild/modules/qt.py @@ -23,7 +23,7 @@ from .. import build from .. import coredata from .. import mlog -from ..dependencies import find_external_dependency, Dependency, ExternalLibrary +from ..dependencies import find_external_dependency, Dependency, ExternalLibrary, InternalDependency from ..mesonlib import MesonException, File, version_compare, Popen_safe from ..interpreter import extract_required_kwarg from ..interpreter.type_checking import INSTALL_DIR_KW, INSTALL_KW, NoneType @@ -455,7 +455,10 @@ def _compile_moc_impl(self, state: 'ModuleState', kwargs: 'MocCompilerKwArgs') - inc = state.get_include_args(include_dirs=kwargs['include_directories']) compile_args: T.List[str] = [] for dep in kwargs['dependencies']: - compile_args.extend([a for a in dep.get_all_compile_args() if a.startswith(('-I', '-D'))]) + compile_args.extend(a for a in dep.get_all_compile_args() if a.startswith(('-I', '-D'))) + if isinstance(dep, InternalDependency): + for incl in dep.include_directories: + compile_args.extend(f'-I{i}' for i in incl.to_string_list(self.interpreter.source_root, self.interpreter.environment.build_dir)) output: T.List[build.GeneratedList] = [] diff --git a/test cases/frameworks/4 qt/manualinclude.cpp b/test cases/frameworks/4 qt/manualinclude.cpp index 60b94e510e12..ef151a44aad6 100644 --- a/test cases/frameworks/4 qt/manualinclude.cpp +++ b/test cases/frameworks/4 qt/manualinclude.cpp @@ -1,4 +1,5 @@ #include"manualinclude.h" +#include #include #include diff --git a/test cases/frameworks/4 qt/meson.build b/test cases/frameworks/4 qt/meson.build index 825cd5766fa6..04a5288bf1c4 100644 --- a/test cases/frameworks/4 qt/meson.build +++ b/test cases/frameworks/4 qt/meson.build @@ -2,6 +2,9 @@ project('qt4, qt5, and qt6 build test', 'cpp', # Qt6 requires C++ 17 support default_options : ['cpp_std=c++17']) +# Visit the subdir before entering the loop +subdir('mocdep') + qt5_modules = ['Widgets'] qt6_modules = ['Widgets'] foreach qt : ['qt4', 'qt5', 'qt6'] @@ -114,17 +117,21 @@ foreach qt : ['qt4', 'qt5', 'qt6'] moc_extra_arguments : ['-DMOC_EXTRA_FLAG'], # This is just a random macro to test `extra_arguments` moc_sources : 'manualinclude.cpp', moc_headers : 'manualinclude.h', - method : get_option('method')) + method : get_option('method'), + dependencies: mocdep, + ) manpreprocessed = qtmodule.compile_moc( extra_args : ['-DMOC_EXTRA_FLAG'], # This is just a random macro to test `extra_arguments` sources : 'manualinclude.cpp', headers : 'manualinclude.h', - method : get_option('method')) + method : get_option('method'), + dependencies: mocdep, + ) qtmaninclude = executable(qt + 'maninclude', sources : ['manualinclude.cpp', manpreprocessed], - dependencies : qtcore) + dependencies : [qtcore, mocdep]) test(qt + 'maninclude', qtmaninclude) diff --git a/test cases/frameworks/4 qt/mocdep/meson.build b/test cases/frameworks/4 qt/mocdep/meson.build new file mode 100644 index 000000000000..174b42679090 --- /dev/null +++ b/test cases/frameworks/4 qt/mocdep/meson.build @@ -0,0 +1,3 @@ +mocdep = declare_dependency( + include_directories: include_directories('.'), +) diff --git a/test cases/frameworks/4 qt/mocdep/mocdep.h b/test cases/frameworks/4 qt/mocdep/mocdep.h new file mode 100644 index 000000000000..357a52c3dd2b --- /dev/null +++ b/test cases/frameworks/4 qt/mocdep/mocdep.h @@ -0,0 +1 @@ +#define MOC_DEP 1 From 6048775e47279ad13872a2fc59e06c90867578b0 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 25 Jul 2022 10:11:31 -0700 Subject: [PATCH 45/99] backends/ninja: run `ranlib -c $out` when using the apple ar Apple's AR is old, and doesn't add externed symbols to the symbol table, instead relying on the user calling ranlib with -c. We need to do that for the user --- mesonbuild/backend/ninjabackend.py | 13 ++++++++++++- mesonbuild/linkers/linkers.py | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index c583c3e5cca2..94f03dd92b16 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2343,7 +2343,7 @@ def generate_static_link_rules(self): if static_linker is None: continue rule = 'STATIC_LINKER{}'.format(self.get_rule_suffix(for_machine)) - cmdlist = [] + cmdlist: T.List[T.Union[str, NinjaCommandArg]] = [] args = ['$in'] # FIXME: Must normalize file names with pathlib.Path before writing # them out to fix this properly on Windows. See: @@ -2357,6 +2357,17 @@ def generate_static_link_rules(self): cmdlist += static_linker.get_exelist() cmdlist += ['$LINK_ARGS'] cmdlist += NinjaCommandArg.list(static_linker.get_output_args('$out'), Quoting.none) + # The default ar on MacOS (at least through version 12), does not + # add extern'd variables to the symbol table by default, and + # requires that apple's ranlib be called with a special flag + # instead after linking + if static_linker.id == 'applear': + # This is a bit of a hack, but we assume that that we won't need + # an rspfile on MacOS, otherwise the arguments are passed to + # ranlib, not to ar + cmdlist.extend(args) + args = [] + cmdlist.extend(['&&', 'ranlib', '-c', '$out']) description = 'Linking static target $out' if num_pools > 0: pool = 'pool = link_pool' diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index edd408572be0..8f4d431fb554 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -146,6 +146,8 @@ class VisualStudioLinker(VisualStudioLikeLinker, StaticLinker): """Microsoft's lib static linker.""" + id = 'lib' + def __init__(self, exelist: T.List[str], machine: str): StaticLinker.__init__(self, exelist) VisualStudioLikeLinker.__init__(self, machine) @@ -155,6 +157,8 @@ class IntelVisualStudioLinker(VisualStudioLikeLinker, StaticLinker): """Intel's xilib static linker.""" + id = 'xilib' + def __init__(self, exelist: T.List[str], machine: str): StaticLinker.__init__(self, exelist) VisualStudioLikeLinker.__init__(self, machine) From 1209da69be2fcec10d325630373b2a6d131b38ae Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Mon, 25 Jul 2022 10:24:09 -0700 Subject: [PATCH 46/99] tests: Test extern'd globals on MacOS with the Apple Archiver This forces the use of the Apple archiver, since that archiver doesn't add extern'd variables to the symbol table automatically, and instead requires that ranlib be used. A native file is used to ensure that Apple's ar is used even in the presence of llvm or gcc in the path with their superior archivers. Co-authored-by: Dylan Baker --- test cases/osx/9 global variable ar/libfile.c | 9 +++++++++ test cases/osx/9 global variable ar/libfile2.c | 7 +++++++ test cases/osx/9 global variable ar/meson.build | 6 ++++++ test cases/osx/9 global variable ar/nativefile.ini | 2 ++ test cases/osx/9 global variable ar/prog.c | 7 +++++++ 5 files changed, 31 insertions(+) create mode 100644 test cases/osx/9 global variable ar/libfile.c create mode 100644 test cases/osx/9 global variable ar/libfile2.c create mode 100644 test cases/osx/9 global variable ar/meson.build create mode 100644 test cases/osx/9 global variable ar/nativefile.ini create mode 100644 test cases/osx/9 global variable ar/prog.c diff --git a/test cases/osx/9 global variable ar/libfile.c b/test cases/osx/9 global variable ar/libfile.c new file mode 100644 index 000000000000..b258d7b8250f --- /dev/null +++ b/test cases/osx/9 global variable ar/libfile.c @@ -0,0 +1,9 @@ +// Source: https://lists.gnu.org/archive/html/libtool/2002-07/msg00025.html + +#include + +extern int l2; +void l1(void) +{ + printf("l1 %d\n", l2); +} diff --git a/test cases/osx/9 global variable ar/libfile2.c b/test cases/osx/9 global variable ar/libfile2.c new file mode 100644 index 000000000000..1499c4dc7f8a --- /dev/null +++ b/test cases/osx/9 global variable ar/libfile2.c @@ -0,0 +1,7 @@ +// Source: https://lists.gnu.org/archive/html/libtool/2002-07/msg00025.html + +int l2; +void l2_func(void) +{ + l2 = 77; +} diff --git a/test cases/osx/9 global variable ar/meson.build b/test cases/osx/9 global variable ar/meson.build new file mode 100644 index 000000000000..313dd1b37653 --- /dev/null +++ b/test cases/osx/9 global variable ar/meson.build @@ -0,0 +1,6 @@ +# Source: https://lists.gnu.org/archive/html/libtool/2002-07/msg00025.html + +project('global variable test', 'c') + +lib = static_library('mylib', 'libfile.c', 'libfile2.c') +test('global variable', executable('prog', 'prog.c', link_with: lib)) diff --git a/test cases/osx/9 global variable ar/nativefile.ini b/test cases/osx/9 global variable ar/nativefile.ini new file mode 100644 index 000000000000..4fb5e7f7db1b --- /dev/null +++ b/test cases/osx/9 global variable ar/nativefile.ini @@ -0,0 +1,2 @@ +[binaries] +ar = 'ar' diff --git a/test cases/osx/9 global variable ar/prog.c b/test cases/osx/9 global variable ar/prog.c new file mode 100644 index 000000000000..4665016f6149 --- /dev/null +++ b/test cases/osx/9 global variable ar/prog.c @@ -0,0 +1,7 @@ +// Source: https://lists.gnu.org/archive/html/libtool/2002-07/msg00025.html + +extern void l1(void); +int main(void) +{ + l1(); +} From 197bf084644301221e6e1abb4e34e2863e5f39e3 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 5 Sep 2023 07:49:18 -0400 Subject: [PATCH 47/99] Fix crash when installing a vala library and python sources Installing python sources causes the python module to call create_install_data() before Ninja backends adds extra outputs to Vala targets. Target objects are supposed to be immutable, adding outputs that late is totally wrong. Add extra vala outputs immediately, but be careful because the main output is only added later in post_init(). Luckily the base class already puts a placeholder item in self.outputs for the main filename so we can just replace self.outputs[0] instead of replacing the whole list which would contain vala outputs at that stage. This is surprisingly what SharedLibrary was already doing. --- data/test.schema.json | 1 + mesonbuild/backend/ninjabackend.py | 4 ---- mesonbuild/build.py | 10 ++++++++-- run_project_tests.py | 5 ++++- test cases/vala/7 shared library/lib/meson.build | 5 +++++ test cases/vala/7 shared library/lib/source.py | 0 test cases/vala/7 shared library/test.json | 4 +++- 7 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 test cases/vala/7 shared library/lib/source.py diff --git a/data/test.schema.json b/data/test.schema.json index a809388b4798..fa5a53e5f77d 100644 --- a/data/test.schema.json +++ b/data/test.schema.json @@ -26,6 +26,7 @@ "exe", "shared_lib", "python_lib", + "python_bytecode", "pdb", "implib", "py_implib", diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 94f03dd92b16..e14ca353f268 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1687,8 +1687,6 @@ def generate_vala_compile(self, target: build.BuildTarget) -> \ # Without this, it will write it inside c_out_dir args += ['--vapi', os.path.join('..', target.vala_vapi)] valac_outputs.append(vapiname) - target.outputs += [target.vala_header, target.vala_vapi] - target.install_tag += ['devel', 'devel'] # Install header and vapi to default locations if user requests this if len(target.install_dir) > 1 and target.install_dir[1] is True: target.install_dir[1] = self.environment.get_includedir() @@ -1699,8 +1697,6 @@ def generate_vala_compile(self, target: build.BuildTarget) -> \ girname = os.path.join(self.get_target_dir(target), target.vala_gir) args += ['--gir', os.path.join('..', target.vala_gir)] valac_outputs.append(girname) - target.outputs.append(target.vala_gir) - target.install_tag.append('devel') # Install GIR to default location if requested by user if len(target.install_dir) > 3 and target.install_dir[3] is True: target.install_dir[3] = os.path.join(self.environment.get_datadir(), 'gir-1.0') diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 2b537e0b0db5..3c62fe8b9ee3 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -788,6 +788,12 @@ def post_init(self) -> None: # relocation-model=pic is rustc's default and Meson does not # currently have a way to disable PIC. self.pic = True + if 'vala' in self.compilers and self.is_linkable_target(): + self.outputs += [self.vala_header, self.vala_vapi] + self.install_tag += ['devel', 'devel'] + if self.vala_gir: + self.outputs.append(self.vala_gir) + self.install_tag.append('devel') def __repr__(self): repr_str = "<{0} {1}: {2}>" @@ -1962,7 +1968,7 @@ def post_init(self) -> None: self.filename = self.name if self.suffix: self.filename += '.' + self.suffix - self.outputs = [self.filename] + self.outputs[0] = self.filename # The import library this target will generate self.import_filename = None @@ -2111,7 +2117,7 @@ def post_init(self) -> None: else: self.suffix = 'a' self.filename = self.prefix + self.name + '.' + self.suffix - self.outputs = [self.filename] + self.outputs[0] = self.filename def get_link_deps_mapping(self, prefix: str) -> T.Mapping[str, str]: return {} diff --git a/run_project_tests.py b/run_project_tests.py index 284210ffe2a2..33ee5caaac9d 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -40,6 +40,7 @@ import typing as T import xml.etree.ElementTree as ET import collections +import importlib.util from mesonbuild import build from mesonbuild import environment @@ -167,7 +168,7 @@ def get_path(self, compiler: str, env: environment.Environment) -> T.Optional[Pa return None # Handle the different types - if self.typ in {'py_implib', 'python_lib', 'python_file'}: + if self.typ in {'py_implib', 'python_lib', 'python_file', 'python_bytecode'}: val = p.as_posix() val = val.replace('@PYTHON_PLATLIB@', python.platlib) val = val.replace('@PYTHON_PURELIB@', python.purelib) @@ -184,6 +185,8 @@ def get_path(self, compiler: str, env: environment.Environment) -> T.Optional[Pa return p.with_suffix('.dll.a') else: return None + if self.typ == 'python_bytecode': + return p.parent / importlib.util.cache_from_source(p.name) elif self.typ in {'file', 'dir'}: return p elif self.typ == 'shared_lib': diff --git a/test cases/vala/7 shared library/lib/meson.build b/test cases/vala/7 shared library/lib/meson.build index edeeb96d19bb..bbd3862f1611 100644 --- a/test cases/vala/7 shared library/lib/meson.build +++ b/test cases/vala/7 shared library/lib/meson.build @@ -33,3 +33,8 @@ shared_library('installed_vala_onlyvapi', 'mylib.vala', dependencies : valadeps, install : true, install_dir : [false, false, join_paths(get_option('datadir'), 'vala', 'vapi')]) + +# Regression test: Vala libraries were broken when also installing python modules. +# https://gitlab.gnome.org/GNOME/gitg/-/issues/412 +python = import('python').find_installation() +python.install_sources('source.py') diff --git a/test cases/vala/7 shared library/lib/source.py b/test cases/vala/7 shared library/lib/source.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test cases/vala/7 shared library/test.json b/test cases/vala/7 shared library/test.json index eee3c3dca845..08bd707347c3 100644 --- a/test cases/vala/7 shared library/test.json +++ b/test cases/vala/7 shared library/test.json @@ -9,6 +9,8 @@ {"type": "file", "file": "usr/include/installed_vala_onlyh.h"}, {"type": "file", "file": "usr/share/vala/vapi/installed_vala_all.vapi"}, {"type": "file", "file": "usr/share/vala-1.0/vapi/installed_vala_all_nolib.vapi"}, - {"type": "file", "file": "usr/share/vala/vapi/installed_vala_onlyvapi.vapi"} + {"type": "file", "file": "usr/share/vala/vapi/installed_vala_onlyvapi.vapi"}, + {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/source.py"}, + {"type": "python_bytecode", "file": "usr/@PYTHON_PURELIB@/source.py"} ] } From f0b2ab8bb02f282499c6d0e5b9f6e5d55bb1419c Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Thu, 3 Nov 2022 09:08:18 -0400 Subject: [PATCH 48/99] gnome: Fix glib tool lookup consistency It was not always using the pkg-config file. --- mesonbuild/modules/gnome.py | 42 ++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index d9b6bf1a54d6..2ce039f099b4 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -203,6 +203,8 @@ class MkEnums(_MkEnumsCommon): vtail: T.Optional[str] depends: T.List[T.Union[BuildTarget, CustomTarget, CustomTargetIndex]] + ToolType = T.Union[Executable, ExternalProgram, OverrideProgram] + # Differs from the CustomTarget version in that it straight defaults to True _BUILD_BY_DEFAULT: KwargInfo[bool] = KwargInfo( @@ -317,6 +319,22 @@ def _print_gdbus_warning() -> None: mlog.bold('https://github.com/mesonbuild/meson/issues/1387'), once=True, fatal=False) + @staticmethod + def _find_tool(state: 'ModuleState', tool: str) -> 'ToolType': + tool_map = { + 'gio-querymodules': 'gio-2.0', + 'glib-compile-schemas': 'gio-2.0', + 'glib-compile-resources': 'gio-2.0', + 'gdbus-codegen': 'gio-2.0', + 'glib-genmarshal': 'glib-2.0', + 'glib-mkenums': 'glib-2.0', + 'g-ir-scanner': 'gobject-introspection-1.0', + 'g-ir-compiler': 'gobject-introspection-1.0', + } + depname = tool_map[tool] + varname = tool.replace('-', '_') + return state.find_tool(tool, depname, varname) + @typed_kwargs( 'gnome.post_install', KwargInfo('glib_compile_schemas', bool, default=False), @@ -332,7 +350,7 @@ def post_install(self, state: 'ModuleState', args: T.List['TYPE_var'], kwargs: ' datadir_abs = os.path.join(state.environment.get_prefix(), state.environment.get_datadir()) if kwargs['glib_compile_schemas'] and not self.install_glib_compile_schemas: self.install_glib_compile_schemas = True - prog = state.find_tool('glib-compile-schemas', 'gio-2.0', 'glib_compile_schemas') + prog = self._find_tool(state, 'glib-compile-schemas') schemasdir = os.path.join(datadir_abs, 'glib-2.0', 'schemas') script = state.backend.get_executable_serialisation([prog, schemasdir]) script.skip_if_destdir = True @@ -340,7 +358,7 @@ def post_install(self, state: 'ModuleState', args: T.List['TYPE_var'], kwargs: ' for d in kwargs['gio_querymodules']: if d not in self.install_gio_querymodules: self.install_gio_querymodules.append(d) - prog = state.find_tool('gio-querymodules', 'gio-2.0', 'gio_querymodules') + prog = self._find_tool(state, 'gio-querymodules') moduledir = os.path.join(state.environment.get_prefix(), d) script = state.backend.get_executable_serialisation([prog, moduledir]) script.skip_if_destdir = True @@ -390,8 +408,8 @@ def compile_resources(self, state: 'ModuleState', args: T.Tuple[str, 'FileOrStri self.__print_gresources_warning(state) glib_version = self._get_native_glib_version(state) - glib_compile_resources = state.find_program('glib-compile-resources') - cmd: T.List[T.Union[ExternalProgram, Executable, OverrideProgram, str]] = [glib_compile_resources, '@INPUT@'] + glib_compile_resources = self._find_tool(state, 'glib-compile-resources') + cmd: T.List[T.Union['ToolType', str]] = [glib_compile_resources, '@INPUT@'] source_dirs = kwargs['source_dir'] dependencies = kwargs['dependencies'] @@ -481,7 +499,7 @@ def compile_resources(self, state: 'ModuleState', args: T.Tuple[str, 'FileOrStri raise MesonException('GResource header is installed yet export is not enabled') depfile: T.Optional[str] = None - target_cmd: T.List[T.Union[ExternalProgram, Executable, OverrideProgram, str]] + target_cmd: T.List[T.Union['ToolType', str]] if not mesonlib.version_compare(glib_version, gresource_dep_needed_version): # This will eventually go out of sync if dependencies are added target_cmd = cmd @@ -780,8 +798,8 @@ def _get_gir_dep(self, state: 'ModuleState') -> T.Tuple[Dependency, T.Union[buil T.Union[build.Executable, 'ExternalProgram', 'OverrideProgram']]: if not self.gir_dep: self.gir_dep = state.dependency('gobject-introspection-1.0') - self.giscanner = state.find_tool('g-ir-scanner', 'gobject-introspection-1.0', 'g_ir_scanner') - self.gicompiler = state.find_tool('g-ir-compiler', 'gobject-introspection-1.0', 'g_ir_compiler') + self.giscanner = self._find_tool(state, 'g-ir-scanner') + self.gicompiler = self._find_tool(state, 'g-ir-compiler') return self.gir_dep, self.giscanner, self.gicompiler @functools.lru_cache(maxsize=None) @@ -1230,7 +1248,7 @@ def compile_schemas(self, state: 'ModuleState', args: T.List['TYPE_var'], kwargs srcdir = os.path.join(state.build_to_src, state.subdir) outdir = state.subdir - cmd: T.List[T.Union[ExternalProgram, Executable, OverrideProgram, str]] = [state.find_program('glib-compile-schemas'), '--targetdir', outdir, srcdir] + cmd: T.List[T.Union['ToolType', str]] = [self._find_tool(state, 'glib-compile-schemas'), '--targetdir', outdir, srcdir] if state.subdir == '': targetname = 'gsettings-compile' else: @@ -1598,7 +1616,7 @@ def gdbus_codegen(self, state: 'ModuleState', args: T.Tuple[str, T.Optional[T.Un kwargs: 'GdbusCodegen') -> ModuleReturnValue: namebase = args[0] xml_files: T.List[T.Union['FileOrString', build.GeneratedTypes]] = [args[1]] if args[1] else [] - cmd: T.List[T.Union[ExternalProgram, Executable, OverrideProgram, str]] = [state.find_program('gdbus-codegen')] + cmd: T.List[T.Union['ToolType', str]] = [self._find_tool(state, 'gdbus-codegen')] cmd.extend(kwargs['extra_args']) # Autocleanup supported? @@ -1905,8 +1923,8 @@ def mkenums_simple(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'MkEn return ModuleReturnValue([c_file, h_file], [c_file, h_file]) - @staticmethod def _make_mkenum_impl( + self, state: 'ModuleState', sources: T.Sequence[T.Union[str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]], output: str, @@ -1916,7 +1934,7 @@ def _make_mkenum_impl( install_dir: T.Optional[T.Sequence[T.Union[str, bool]]] = None, depends: T.Optional[T.Sequence[T.Union[CustomTarget, CustomTargetIndex, BuildTarget]]] = None ) -> build.CustomTarget: - real_cmd: T.List[T.Union[ExternalProgram, Executable, OverrideProgram, str]] = [state.find_program(['glib-mkenums', 'mkenums'])] + real_cmd: T.List[T.Union[str, 'ToolType']] = [self._find_tool(state, 'glib-mkenums')] real_cmd.extend(cmd) _install_dir = install_dir or state.environment.coredata.get_option(mesonlib.OptionKey('includedir')) assert isinstance(_install_dir, str), 'for mypy' @@ -1960,7 +1978,7 @@ def genmarshal(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'GenMarsh new_genmarshal = mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.53.3') - cmd: T.List[T.Union[ExternalProgram, Executable, OverrideProgram, str]] = [state.find_program('glib-genmarshal')] + cmd: T.List[T.Union['ToolType', str]] = [self._find_tool(state, 'glib-genmarshal')] if kwargs['prefix']: cmd.extend(['--prefix', kwargs['prefix']]) if kwargs['extra_args']: From 5ac498e19ed35c158f8b3a40140770d2b80247df Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Mon, 4 Sep 2023 19:35:04 -0400 Subject: [PATCH 49/99] dependencies: fix crash in Qt if private_headers dir not found You cannot listdir() a directory that doesn't exist. This header directory may not exist if suitable devel packages in distros with split devel packages, aren't installed. In theory we could raise a suitable error here. But it would be inconsistent -- we don't otherwise validate that the Qt include directories exist, usually just assuming they do because the dependency was found. And this is niche code inside a non-default special kwarg. At least for pkg-config, it's probably a bug in the distro if pkg-config files exist but the headers don't. The qmake status is less clear. Avoiding a crash means that at the very least, if those headers are in fact directly used by the project, an obvious compiler error occurs instead of a noisy meson traceback. Fixes #12214 --- mesonbuild/dependencies/qt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/dependencies/qt.py b/mesonbuild/dependencies/qt.py index 1a86bd28a8ea..ba9b42032e48 100644 --- a/mesonbuild/dependencies/qt.py +++ b/mesonbuild/dependencies/qt.py @@ -53,7 +53,7 @@ def _qt_get_private_includes(mod_inc_dir: str, module: str, mod_version: str) -> private_dir = os.path.join(mod_inc_dir, mod_version) # fallback, let's try to find a directory with the latest version - if not os.path.exists(private_dir): + if os.path.isdir(mod_inc_dir) and not os.path.exists(private_dir): dirs = [filename for filename in os.listdir(mod_inc_dir) if os.path.isdir(os.path.join(mod_inc_dir, filename))] From de1ba4eb8c4b8d440dd672647dab7db56a5dad4b Mon Sep 17 00:00:00 2001 From: Charles Brunet Date: Wed, 6 Sep 2023 15:51:20 -0400 Subject: [PATCH 50/99] fix bug with openssl when cmake is missing Fixes #12098 DependencyFactory was returning a lambda, but it has no log_tried() function --- mesonbuild/dependencies/cmake.py | 16 ++++++++++++++++ mesonbuild/dependencies/misc.py | 8 ++++---- .../unit/117 openssl cmake bug/meson.build | 5 +++++ .../unit/117 openssl cmake bug/nativefile.ini | 7 +++++++ unittests/platformagnostictests.py | 7 +++++++ 5 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 test cases/unit/117 openssl cmake bug/meson.build create mode 100644 test cases/unit/117 openssl cmake bug/nativefile.ini diff --git a/mesonbuild/dependencies/cmake.py b/mesonbuild/dependencies/cmake.py index 8827c9abdcd8..0c6e7739cb71 100644 --- a/mesonbuild/dependencies/cmake.py +++ b/mesonbuild/dependencies/cmake.py @@ -652,3 +652,19 @@ def get_variable(self, *, cmake: T.Optional[str] = None, pkgconfig: T.Optional[s if default_value is not None: return default_value raise DependencyException(f'Could not get cmake variable and no default provided for {self!r}') + + +class CMakeDependencyFactory: + + def __init__(self, name: T.Optional[str] = None, modules: T.Optional[T.List[str]] = None): + self.name = name + self.modules = modules + + def __call__(self, name: str, env: Environment, kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None, force_use_global_compilers: bool = False) -> CMakeDependency: + if self.modules: + kwargs['modules'] = self.modules + return CMakeDependency(self.name or name, env, kwargs, language, force_use_global_compilers) + + @staticmethod + def log_tried() -> str: + return CMakeDependency.log_tried() diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index d77566961a3c..d7c4a40a84a9 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -23,7 +23,7 @@ from .. import mlog from .base import DependencyException, DependencyMethods from .base import BuiltinDependency, SystemDependency -from .cmake import CMakeDependency +from .cmake import CMakeDependency, CMakeDependencyFactory from .configtool import ConfigToolDependency from .detect import packages from .factory import DependencyFactory, factory_methods @@ -599,19 +599,19 @@ def shaderc_factory(env: 'Environment', 'openssl', [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM, DependencyMethods.CMAKE], system_class=OpensslSystemDependency, - cmake_class=lambda name, env, kwargs: CMakeDependency('OpenSSL', env, dict(kwargs, modules=['OpenSSL::Crypto', 'OpenSSL::SSL'])), + cmake_class=CMakeDependencyFactory('OpenSSL', modules=['OpenSSL::Crypto', 'OpenSSL::SSL']), ) packages['libcrypto'] = libcrypto_factory = DependencyFactory( 'libcrypto', [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM, DependencyMethods.CMAKE], system_class=OpensslSystemDependency, - cmake_class=lambda name, env, kwargs: CMakeDependency('OpenSSL', env, dict(kwargs, modules=['OpenSSL::Crypto'])), + cmake_class=CMakeDependencyFactory('OpenSSL', modules=['OpenSSL::Crypto']), ) packages['libssl'] = libssl_factory = DependencyFactory( 'libssl', [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM, DependencyMethods.CMAKE], system_class=OpensslSystemDependency, - cmake_class=lambda name, env, kwargs: CMakeDependency('OpenSSL', env, dict(kwargs, modules=['OpenSSL::SSL'])), + cmake_class=CMakeDependencyFactory('OpenSSL', modules=['OpenSSL::SSL']), ) diff --git a/test cases/unit/117 openssl cmake bug/meson.build b/test cases/unit/117 openssl cmake bug/meson.build new file mode 100644 index 000000000000..d08a8ef429a2 --- /dev/null +++ b/test cases/unit/117 openssl cmake bug/meson.build @@ -0,0 +1,5 @@ +project('bug', 'cpp') + +# When cmake is not available, +# this triggers the bug described in #12098 +openssl_dep = dependency('openssl') diff --git a/test cases/unit/117 openssl cmake bug/nativefile.ini b/test cases/unit/117 openssl cmake bug/nativefile.ini new file mode 100644 index 000000000000..dd6b0ff299c9 --- /dev/null +++ b/test cases/unit/117 openssl cmake bug/nativefile.ini @@ -0,0 +1,7 @@ +[binaries] + +cmake = '/path/to/nothing' + +[built-in options] + +pkg_config_path = '' \ No newline at end of file diff --git a/unittests/platformagnostictests.py b/unittests/platformagnostictests.py index fd012939c408..cd2d31993eb5 100644 --- a/unittests/platformagnostictests.py +++ b/unittests/platformagnostictests.py @@ -254,3 +254,10 @@ def test_setup_loaded_modules(self): self.assertEqual(data['modules'], expected) self.assertEqual(data['count'], 68) + + def test_cmake_openssl_not_found_bug(self): + """Issue #12098""" + testdir = os.path.join(self.unit_test_dir, '117 openssl cmake bug') + self.meson_native_files.append(os.path.join(testdir, 'nativefile.ini')) + out = self.init(testdir, allow_fail=True) + self.assertNotIn('Unhandled python exception', out) From ca42c7029f0a1e4c99bd6f173521662eed3b91f9 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Thu, 31 Aug 2023 15:25:31 -0400 Subject: [PATCH 51/99] msubprojects: Speedup subproject_dir extraction The interpreter takes significant amount of time to initialize everything in project() function. We only need to extract a string from AST, just like we do in handle_meson_version_from_ast(). --- mesonbuild/ast/introspection.py | 19 +++++++++++++++++++ mesonbuild/msubprojects.py | 8 +++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py index d66e73f3e320..d5203822ea33 100644 --- a/mesonbuild/ast/introspection.py +++ b/mesonbuild/ast/introspection.py @@ -362,3 +362,22 @@ def analyze(self) -> None: self.sanity_check_ast() self.parse_project() self.run() + + def extract_subproject_dir(self) -> T.Optional[str]: + '''Fast path to extract subproject_dir kwarg. + This is faster than self.parse_project() which also initialize options + and also calls parse_project() on every subproject. + ''' + if not self.ast.lines: + return + project = self.ast.lines[0] + # first line is always project() + if not isinstance(project, FunctionNode): + return + for kw, val in project.args.kwargs.items(): + assert isinstance(kw, IdNode), 'for mypy' + if kw.value == 'subproject_dir': + # mypy does not understand "and isinstance" + if isinstance(val, StringNode): + return val.value + return None diff --git a/mesonbuild/msubprojects.py b/mesonbuild/msubprojects.py index 3ecfba18fe6b..8f3231c1163a 100755 --- a/mesonbuild/msubprojects.py +++ b/mesonbuild/msubprojects.py @@ -14,7 +14,7 @@ import zipfile from . import mlog -from .ast import IntrospectionInterpreter, AstIDGenerator +from .ast import IntrospectionInterpreter from .mesonlib import quiet_git, GitException, Popen_safe, MesonException, windows_proof_rmtree from .wrap.wrap import (Resolver, WrapException, ALL_TYPES, PackageDefinition, parse_patch_url, update_wrap_file, get_releases) @@ -691,11 +691,9 @@ def run(options: 'Arguments') -> int: mlog.error('Directory', mlog.bold(source_dir), 'does not seem to be a Meson source directory.') return 1 with mlog.no_logging(): - intr = IntrospectionInterpreter(source_dir, '', 'none', visitors = [AstIDGenerator()]) + intr = IntrospectionInterpreter(source_dir, '', 'none') intr.load_root_meson_file() - intr.sanity_check_ast() - intr.parse_project() - subproject_dir = intr.subproject_dir + subproject_dir = intr.extract_subproject_dir() or 'subprojects' if not os.path.isdir(os.path.join(source_dir, subproject_dir)): mlog.log('Directory', mlog.bold(source_dir), 'does not seem to have subprojects.') return 0 From c30df902e18f43c2d343808e32f171e3909a4682 Mon Sep 17 00:00:00 2001 From: Charles Brunet Date: Fri, 8 Sep 2023 08:47:27 -0400 Subject: [PATCH 52/99] Allow unit test to parse testcase blocks When a unittest introspect a meson.build file from a test case, the file may contain a testcase block. We should ignore this block. --- mesonbuild/ast/interpreter.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py index 68e2b6e5254f..c963b273f324 100644 --- a/mesonbuild/ast/interpreter.py +++ b/mesonbuild/ast/interpreter.py @@ -29,6 +29,7 @@ InvalidArguments, BreakRequest, ContinueRequest, + Disabler, default_resolve_key, ) @@ -53,6 +54,7 @@ NotNode, PlusAssignmentNode, TernaryNode, + TestCaseClauseNode, ) if T.TYPE_CHECKING: @@ -445,3 +447,6 @@ def flatten_kwargs(self, kwargs: T.Dict[str, TYPE_nvar], include_unknown_args: b elif isinstance(val, (str, bool, int, float)) or include_unknown_args: flattened_kwargs[key] = val return flattened_kwargs + + def evaluate_testcase(self, node: TestCaseClauseNode) -> Disabler | None: + return Disabler(subproject=self.subproject) From dd1535f6a02c47e452bbab611b68f6750eb90986 Mon Sep 17 00:00:00 2001 From: Charles Brunet Date: Thu, 7 Sep 2023 15:06:23 -0400 Subject: [PATCH 53/99] Fix assertion raised with invalid option name When option name contains more that one dot, it should be detected earlier to prevent an assert to be raised. Fixes #11904. --- mesonbuild/interpreter/interpreter.py | 5 +++++ test cases/common/40 options/meson.build | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index b18421d2505a..19b60d099a88 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -37,6 +37,7 @@ from ..interpreterbase import ObjectHolder, ContextManagerObject from ..modules import ExtensionModule, ModuleObject, MutableModuleObject, NewExtensionModule, NotFoundExtensionModule from ..backend.backends import ExecutableSerialisation +from ..optinterpreter import optname_regex from . import interpreterobjects as OBJ from . import compiler as compilerOBJ @@ -1101,6 +1102,10 @@ def func_get_option(self, nodes: mparser.BaseNode, args: T.Tuple[str], raise InterpreterException('Having a colon in option name is forbidden, ' 'projects are not allowed to directly access ' 'options of other subprojects.') + + if optname_regex.search(optname.split('.', maxsplit=1)[-1]) is not None: + raise InterpreterException(f'Invalid option name {optname!r}') + opt = self.get_option_internal(optname) if isinstance(opt, coredata.UserFeatureOption): opt.name = optname diff --git a/test cases/common/40 options/meson.build b/test cases/common/40 options/meson.build index a10ff28f0c6e..de4a7d50db14 100644 --- a/test cases/common/40 options/meson.build +++ b/test cases/common/40 options/meson.build @@ -46,3 +46,11 @@ assert(get_option('wrap_mode') == 'default', 'Wrap mode option is broken.') assert(get_option('boolean_string') == false) assert(get_option('boolean_string2') == true) assert(get_option('integer_string') == 42) + +testcase expect_error('Invalid option name \'..invalid\'') + get_option('..invalid') +endtestcase + +testcase expect_error('Invalid option name \'this.is.also.invalid\'') + get_option('this.is.also.invalid') +endtestcase From d6d210cef7d6dd9df8841bd4637dfbd5c83c6247 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 21 Sep 2023 20:45:22 -0700 Subject: [PATCH 54/99] rust: properly rematerialize static dependencies as well as dynamic ones Rustc expects to be provided both a search path `-L`, and a link arg `-l kind=libname`, but we don't handle that correctly. Because we combine -L and -l arguments from pkg-config the backend must rematerialize the -L and -l split. We currently don't do this for static archives. --- mesonbuild/backend/ninjabackend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index e14ca353f268..3560d1ed24ad 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2093,13 +2093,14 @@ def generate_rust_target(self, target: build.BuildTarget) -> None: if a in rustc.native_static_libs: # Exclude link args that rustc already add by default continue - if a.endswith(('.dll', '.so', '.dylib')): + if a.endswith(('.dll', '.so', '.dylib', '.a', '.lib')): dir_, lib = os.path.split(a) linkdirs.add(dir_) lib, ext = os.path.splitext(lib) if lib.startswith('lib'): lib = lib[3:] - args.extend(['-l', f'dylib={lib}']) + _type = 'static' if a.endswith(('.a', '.lib')) else 'dylib' + args.extend(['-l', f'{_type}={lib}']) elif a.startswith('-L'): args.append(a) elif a.startswith('-l'): From c10e31d57b7f74b9bda6eee99226e3e1229f5389 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Wed, 22 Mar 2023 15:51:48 -0700 Subject: [PATCH 55/99] ZlibSystemDependency: pass libtype to clib_compiler.find_library Makes it stop reporting that it found a static zlib on Solaris which does not ship a static library file for libz, and thus allows "test cases/rust/13 external c dependencies" to pass. Fixes #10906 --- mesonbuild/dependencies/dev.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py index ec7015103b7a..09f55b705d42 100644 --- a/mesonbuild/dependencies/dev.py +++ b/mesonbuild/dependencies/dev.py @@ -536,7 +536,7 @@ def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T. else: libs = ['z'] for lib in libs: - l = self.clib_compiler.find_library(lib, environment, []) + l = self.clib_compiler.find_library(lib, environment, [], self.libtype) h = self.clib_compiler.has_header('zlib.h', '', environment, dependencies=[self]) if l and h[0]: self.is_found = True From 4ce3e63389dc4a482b55ff1017b1ff6939ac9c94 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sat, 23 Sep 2023 17:21:43 +0200 Subject: [PATCH 56/99] get_llvm_tool_names: add llvm 17 this fixes the "frameworks: 15 llvm" tests with llvm 17 --- mesonbuild/environment.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index e24cff054431..5050d3ed1b7e 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -157,6 +157,7 @@ def get_llvm_tool_names(tool: str) -> T.List[str]: # unless it becomes a stable release. suffixes = [ '', # base (no suffix) + '-17', '17', '-16', '16', '-15', '15', '-14', '14', From faa3d900e51ffb313440c6b27f076e9f33f9f650 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sat, 23 Sep 2023 14:10:29 +0200 Subject: [PATCH 57/99] openmp: add 5.1/5.2, fixes openmp with llvm v17 llvm v17 defaults to 5.1 and without this meson fails to find openmp: 'ERROR: Dependency "openmp" not found, tried system' Add 5.2 as well while at it. --- mesonbuild/dependencies/misc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index d7c4a40a84a9..b2df20886566 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -85,6 +85,8 @@ def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]): class OpenMPDependency(SystemDependency): # Map date of specification release (which is the macro value) to a version. VERSIONS = { + '202111': '5.2', + '202011': '5.1', '201811': '5.0', '201611': '5.0-revision1', # This is supported by ICC 19.x '201511': '4.5', From 58be8bcea6fcc205ecc27e7e8d449292e6262cd2 Mon Sep 17 00:00:00 2001 From: Alan Brooks Date: Fri, 15 Sep 2023 22:27:05 -0500 Subject: [PATCH 58/99] fix bug where all java builds & tests fail to run SanityCheck on JDK11 Needed a classpath set in the current working directory. This was on a Zulu build of OpenJDK 11.0.17 on a macOS ARM machine. The errors folks might encounter: Error: Could not find or load main class SanityCheck Caused by: java.lang.ClassNotFoundException: SanityCheck --- mesonbuild/compilers/java.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/compilers/java.py b/mesonbuild/compilers/java.py index 42cf0a159ce0..9f508d637313 100644 --- a/mesonbuild/compilers/java.py +++ b/mesonbuild/compilers/java.py @@ -100,7 +100,7 @@ def sanity_check(self, work_dir: str, environment: 'Environment') -> None: raise EnvironmentException(f'Java compiler {self.name_string()} cannot compile programs.') runner = shutil.which(self.javarunner) if runner: - cmdlist = [runner, obj] + cmdlist = [runner, '-cp', '.', obj] pe = subprocess.Popen(cmdlist, cwd=work_dir) pe.wait() if pe.returncode != 0: From 36210f64f22dc10d324db76bb1a7988c9cd5b14e Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 22 Sep 2023 13:40:35 -0700 Subject: [PATCH 59/99] rust: apply global, project, and environment C args to bindgen This means that arguments set via `add_global_arguments`, `add_project_arguments` and by either the `-Dc_args` or `CFLAGS` are applied to bindgen as well. This can be important when, among other things, #defines are set via these mechanisms. Fixes: #12065 --- mesonbuild/modules/rust.py | 6 ++++++ test cases/rust/12 bindgen/meson.build | 18 ++++++++++++++++++ .../rust/12 bindgen/src/global-project.h | 10 ++++++++++ test cases/rust/12 bindgen/src/global.c | 5 +++++ test cases/rust/12 bindgen/src/global.rs | 14 ++++++++++++++ test cases/rust/12 bindgen/test.json | 5 ++++- 6 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 test cases/rust/12 bindgen/src/global-project.h create mode 100644 test cases/rust/12 bindgen/src/global.c create mode 100644 test cases/rust/12 bindgen/src/global.rs diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py index 3514412e65df..e6e5c633ff11 100644 --- a/mesonbuild/modules/rust.py +++ b/mesonbuild/modules/rust.py @@ -232,6 +232,12 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu elif isinstance(s, CustomTarget): depends.append(s) + clang_args.extend(state.global_args.get('c', [])) + clang_args.extend(state.project_args.get('c', [])) + cargs = state.get_option('args', state.subproject, lang='c') + assert isinstance(cargs, list), 'for mypy' + clang_args.extend(cargs) + if self._bindgen_bin is None: self._bindgen_bin = state.find_program('bindgen') diff --git a/test cases/rust/12 bindgen/meson.build b/test cases/rust/12 bindgen/meson.build index c05cc063136c..e7cb5f3db2c0 100644 --- a/test cases/rust/12 bindgen/meson.build +++ b/test cases/rust/12 bindgen/meson.build @@ -8,6 +8,9 @@ if not prog_bindgen.found() error('MESON_SKIP_TEST bindgen not found') endif +add_project_arguments('-DPROJECT_ARG', language : 'c') +add_global_arguments('-DGLOBAL_ARG', language : 'c') + # This seems to happen on windows when libclang.dll is not in path or is not # valid. We must try to process a header file for this to work. # @@ -81,3 +84,18 @@ test('generated header', rust_bin2) subdir('sub') subdir('dependencies') + +gp = rust.bindgen( + input : 'src/global-project.h', + output : 'global-project.rs', +) + +gp_lib = static_library('gp_lib', 'src/global.c') + +gp_exe = executable( + 'gp_exe', + structured_sources(['src/global.rs', gp]), + link_with : gp_lib, +) + +test('global and project arguments', gp_exe) diff --git a/test cases/rust/12 bindgen/src/global-project.h b/test cases/rust/12 bindgen/src/global-project.h new file mode 100644 index 000000000000..6084e8ed6b0b --- /dev/null +++ b/test cases/rust/12 bindgen/src/global-project.h @@ -0,0 +1,10 @@ +#ifndef GLOBAL_ARG +char * success(void); +#endif +#ifndef PROJECT_ARG +char * success(void); +#endif +#ifndef CMD_ARG +char * success(void); +#endif +int success(void); diff --git a/test cases/rust/12 bindgen/src/global.c b/test cases/rust/12 bindgen/src/global.c new file mode 100644 index 000000000000..10f6676f7a1b --- /dev/null +++ b/test cases/rust/12 bindgen/src/global.c @@ -0,0 +1,5 @@ +#include "src/global-project.h" + +int success(void) { + return 0; +} diff --git a/test cases/rust/12 bindgen/src/global.rs b/test cases/rust/12 bindgen/src/global.rs new file mode 100644 index 000000000000..4b70b1ecc728 --- /dev/null +++ b/test cases/rust/12 bindgen/src/global.rs @@ -0,0 +1,14 @@ +// SPDX-license-identifer: Apache-2.0 +// Copyright © 2023 Intel Corporation + +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +include!("global-project.rs"); + +fn main() { + unsafe { + std::process::exit(success()); + }; +} diff --git a/test cases/rust/12 bindgen/test.json b/test cases/rust/12 bindgen/test.json index f94ee85f9740..b3a758562969 100644 --- a/test cases/rust/12 bindgen/test.json +++ b/test cases/rust/12 bindgen/test.json @@ -1,7 +1,10 @@ { + "env": { + "CFLAGS": "-DCMD_ARG" + }, "stdout": [ { - "line": "test cases/rust/12 bindgen/meson.build:27: WARNING: Project targets '>= 0.63' but uses feature introduced in '1.0.0': \"rust.bindgen\" keyword argument \"include_directories\" of type array[str]." + "line": "test cases/rust/12 bindgen/meson.build:30: WARNING: Project targets '>= 0.63' but uses feature introduced in '1.0.0': \"rust.bindgen\" keyword argument \"include_directories\" of type array[str]." } ] } From f12a43a0bc22f4355883223e7c0c0d9b546e8af2 Mon Sep 17 00:00:00 2001 From: CorrodedCoder <38778644+CorrodedCoder@users.noreply.github.com> Date: Mon, 18 Sep 2023 18:03:57 +0100 Subject: [PATCH 60/99] Adjust kernel detection to support Solaris 5.10 or earlier The logic previously added to distinguish between illumos and Solaris made use of a uname invocation with a -o switch which is not supported on Solaris 5.10 or earlier. illumos started with version 5.11 so the logic has been shortcut to report 'solaris' in such cases where the version is 5.10 or below. --- mesonbuild/environment.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 5050d3ed1b7e..cd9d487085a7 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -410,6 +410,11 @@ def detect_cpu(compilers: CompilersDict) -> str: def detect_kernel(system: str) -> T.Optional[str]: if system == 'sunos': + # Solaris 5.10 uname doesn't support the -o switch, and illumos started + # with version 5.11 so shortcut the logic to report 'solaris' in such + # cases where the version is 5.10 or below. + if mesonlib.version_compare(platform.uname().release, '<=5.10'): + return 'solaris' # This needs to be /usr/bin/uname because gnu-uname could be installed and # won't provide the necessary information p, out, _ = Popen_safe(['/usr/bin/uname', '-o']) From 3f874d5e08ab37541dca1e06bbe3949975089b31 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Fri, 1 Sep 2023 17:23:29 -0400 Subject: [PATCH 61/99] compilers: use correct version comparison for openbsd libraries It should *be* a version comparison. We are guaranteed to get a two-element version number, which also parses as a float but a float doesn't correctly handle version sorting when the second component differs in number of digits. The standard way to handle this is by comparing tuples such that each component is an integer. Do so here. Fixes #12195 Co-authored-by: George Koehler (for unittests) --- mesonbuild/compilers/mixins/clike.py | 9 ++++++--- unittests/internaltests.py | 5 ++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index cec6b758f546..db13e8493666 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -1066,6 +1066,10 @@ def get_library_naming(self, env: 'Environment', libtype: LibType, strict: bool @staticmethod def _sort_shlibs_openbsd(libs: T.List[str]) -> T.List[str]: + def tuple_key(x: str) -> T.Tuple[int, ...]: + ver = x.rsplit('.so.', maxsplit=1)[1] + return tuple(int(i) for i in ver.split('.')) + filtered = [] # type: T.List[str] for lib in libs: # Validate file as a shared library of type libfoo.so.X.Y @@ -1073,12 +1077,11 @@ def _sort_shlibs_openbsd(libs: T.List[str]) -> T.List[str]: if len(ret) != 2: continue try: - float(ret[1]) + tuple(int(i) for i in ret[1].split('.')) except ValueError: continue filtered.append(lib) - float_cmp = lambda x: float(x.rsplit('.so.', maxsplit=1)[1]) - return sorted(filtered, key=float_cmp, reverse=True) + return sorted(filtered, key=tuple_key, reverse=True) @classmethod def _get_trials_from_pattern(cls, pattern: str, directory: str, libname: str) -> T.List[Path]: diff --git a/unittests/internaltests.py b/unittests/internaltests.py index b4d090dd29c3..e57dd6d83549 100644 --- a/unittests/internaltests.py +++ b/unittests/internaltests.py @@ -549,11 +549,14 @@ def _test_all_naming(self, cc, env, patterns, platform): if platform != 'openbsd': return with tempfile.TemporaryDirectory() as tmpdir: - for i in ['libfoo.so.6.0', 'libfoo.so.5.0', 'libfoo.so.54.0', 'libfoo.so.66a.0b', 'libfoo.so.70.0.so.1']: + for i in ['libfoo.so.6.0', 'libfoo.so.5.0', 'libfoo.so.54.0', 'libfoo.so.66a.0b', 'libfoo.so.70.0.so.1', + 'libbar.so.7.10', 'libbar.so.7.9', 'libbar.so.7.9.3']: libpath = Path(tmpdir) / i libpath.write_text('', encoding='utf-8') found = cc._find_library_real('foo', env, [tmpdir], '', LibType.PREFER_SHARED, lib_prefix_warning=True) self.assertEqual(os.path.basename(found[0]), 'libfoo.so.54.0') + found = cc._find_library_real('bar', env, [tmpdir], '', LibType.PREFER_SHARED, lib_prefix_warning=True) + self.assertEqual(os.path.basename(found[0]), 'libbar.so.7.10') def test_find_library_patterns(self): ''' From 48c03f9ad50ed8171e1fae4c71550c57b9592275 Mon Sep 17 00:00:00 2001 From: "Kunwu.Chan" Date: Wed, 20 Sep 2023 10:57:53 +0800 Subject: [PATCH 62/99] CPU family support 'sw_64' --- mesonbuild/envconfig.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index 7e0c56703121..cd464fda1208 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -68,6 +68,7 @@ 'sh4', 'sparc', 'sparc64', + 'sw_64', 'wasm32', 'wasm64', 'x86', @@ -86,6 +87,7 @@ 'riscv64', 's390x', 'sparc64', + 'sw_64', 'wasm64', 'x86_64', ] From 4c8cd24d04e89e3a6145cd6727833d7d6f87f459 Mon Sep 17 00:00:00 2001 From: "Kunwu.Chan" Date: Wed, 20 Sep 2023 11:41:00 +0800 Subject: [PATCH 63/99] Update Reference-tables.md add sw_64 --- docs/markdown/Reference-tables.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md index 377b36286523..09225df874e8 100644 --- a/docs/markdown/Reference-tables.md +++ b/docs/markdown/Reference-tables.md @@ -131,6 +131,7 @@ set in the cross file. | wasm64 | 64 bit Webassembly | | x86 | 32 bit x86 processor | | x86_64 | 64 bit x86 processor | +| sw_64 | 64 bit sunway processor | Any cpu family not listed in the above list is not guaranteed to remain stable in future releases. From fd1f36afc88522c2427b8803cac5b4012421acd2 Mon Sep 17 00:00:00 2001 From: "Kunwu.Chan" Date: Fri, 22 Sep 2023 15:04:18 +0800 Subject: [PATCH 64/99] docs/markdown: update Reference-tables.md to keep 'CPU families' in alphabetical order --- docs/markdown/Reference-tables.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md index 09225df874e8..26cbdf037aa1 100644 --- a/docs/markdown/Reference-tables.md +++ b/docs/markdown/Reference-tables.md @@ -127,11 +127,12 @@ set in the cross file. | sh4 | SuperH SH-4 | | sparc | 32 bit SPARC | | sparc64 | SPARC v9 processor | +| sw_64 | 64 bit sunway processor | | wasm32 | 32 bit Webassembly | | wasm64 | 64 bit Webassembly | | x86 | 32 bit x86 processor | | x86_64 | 64 bit x86 processor | -| sw_64 | 64 bit sunway processor | + Any cpu family not listed in the above list is not guaranteed to remain stable in future releases. From e77edf4edc03de4026359c311146e9e358a7137c Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Tue, 8 Aug 2023 08:41:01 +0200 Subject: [PATCH 65/99] tests: fix test_vsenv_option with Python 3.11+ on Windows meson tests enable PYTHONWARNDEFAULTENCODING by default and make EncodingWarning fatal too. Starting with Python 3.11 CPython not only warns if no encoding is passed to open() but also to things like subprocess.check_output(). This made the call in vsenv.py fail and in turn made test_vsenv_option fail. check_output() here calls a .bat file which in turn calls vcvars. I don't know what the encoding is supposed to be used there, so just be explicit with the locale encoding to silence the warning. --- mesonbuild/utils/vsenv.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mesonbuild/utils/vsenv.py b/mesonbuild/utils/vsenv.py index 3c2687884de2..e9a5c1072e02 100644 --- a/mesonbuild/utils/vsenv.py +++ b/mesonbuild/utils/vsenv.py @@ -6,6 +6,7 @@ import pathlib import shutil import tempfile +import locale from .. import mlog from .universal import MesonException, is_windows, windows_detect_native_arch @@ -92,7 +93,8 @@ def _setup_vsenv(force: bool) -> bool: bat_file.write(bat_contents) bat_file.flush() bat_file.close() - bat_output = subprocess.check_output(bat_file.name, universal_newlines=True) + bat_output = subprocess.check_output(bat_file.name, universal_newlines=True, + encoding=locale.getpreferredencoding(False)) os.unlink(bat_file.name) bat_lines = bat_output.split('\n') bat_separator_seen = False From 8b09ab23eb73a662554ae4d7b79fc9d355d6f2eb Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Tue, 8 Aug 2023 09:26:33 +0200 Subject: [PATCH 66/99] tests: fix "4 custom target depends extmodule" with Python 3.8+ on Windows Since CPython 3.8 .pyd files no longer look in PATH for loading libraries, but require the DLL directory to be explicitely added via os.add_dll_directory(). This resulted in those tests failing with 3.8+ on Windows. Add the DLL build directory with os.add_dll_directory() to fix them. This was never noticed in CI because it only uses Python 3.7 and the MSYS2 CPython still used the old behaviour until now. --- test cases/python/4 custom target depends extmodule/blaster.py | 3 +++ .../python3/4 custom target depends extmodule/blaster.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/test cases/python/4 custom target depends extmodule/blaster.py b/test cases/python/4 custom target depends extmodule/blaster.py index 61b11f922977..65b6493df890 100644 --- a/test cases/python/4 custom target depends extmodule/blaster.py +++ b/test cases/python/4 custom target depends extmodule/blaster.py @@ -10,6 +10,9 @@ if list(filedir.glob('ext/*tachyon*')): sys.path.insert(0, (filedir / 'ext').as_posix()) +if hasattr(os, 'add_dll_directory'): + os.add_dll_directory(filedir / 'ext' / 'lib') + import tachyon parser = argparse.ArgumentParser() diff --git a/test cases/python3/4 custom target depends extmodule/blaster.py b/test cases/python3/4 custom target depends extmodule/blaster.py index d2c93ad038fa..9cce64505e5d 100644 --- a/test cases/python3/4 custom target depends extmodule/blaster.py +++ b/test cases/python3/4 custom target depends extmodule/blaster.py @@ -10,6 +10,9 @@ if list(filedir.glob('ext/*tachyon.*')): sys.path.insert(0, (filedir / 'ext').as_posix()) +if hasattr(os, 'add_dll_directory'): + os.add_dll_directory(filedir / 'ext' / 'lib') + import tachyon parser = argparse.ArgumentParser() From 5aeacb76a05de5707f8e9dccde0133dc5522bf11 Mon Sep 17 00:00:00 2001 From: Albert Tang Date: Mon, 21 Aug 2023 10:13:05 -0500 Subject: [PATCH 67/99] tests: Skip "withIncludeFile" for PCH on Xcode backend Xcode always fails here because this makes the PCH not be the first included header, causing Xcode to ignore it completely. There is no way around this. --- test cases/common/13 pch/meson.build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test cases/common/13 pch/meson.build b/test cases/common/13 pch/meson.build index 4bb3e1f275ba..d83291963284 100644 --- a/test cases/common/13 pch/meson.build +++ b/test cases/common/13 pch/meson.build @@ -13,7 +13,11 @@ subdir('cpp') subdir('generated') subdir('userDefined') subdir('withIncludeDirectories') -subdir('withIncludeFile') +if meson.backend() == 'xcode' + warning('Xcode backend does not support forced includes. Skipping "withIncludeFile" which requires this.') +else + subdir('withIncludeFile') +endif if meson.backend() == 'xcode' warning('Xcode backend only supports one precompiled header per target. Skipping "mixed" which has various precompiled headers.') From 3328f38192c7515f5b9c327b5c9fe813d1ebad5c Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Mon, 25 Sep 2023 23:29:48 -0400 Subject: [PATCH 68/99] tests: fix broken promises with linker scripts This has never, ever, ever worked. You can get away with it a tiny, tiny bit, iff you magically assume several things about both internal implementations, as well as the project source layout and builddir location. This can be witnessed by the way using files() was mercilessly tortured through joining the undefined stringified format value of the file to the current source dir... because it didn't actually *work*, the stringified value isn't an absolute path or a builddir-relative one, but it works as long as you do it from the root meson.build file. Furthermore, this triggers a deprecation warning if you do it. And using it for files() is frivolous, the "static map file" case was correct all along. Fix the configure_file case to demonstrate the same painful hoops we must jump through to get custom_target outputs to work correctly. Fixes #12259 --- test cases/linuxlike/3 linker script/meson.build | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/test cases/linuxlike/3 linker script/meson.build b/test cases/linuxlike/3 linker script/meson.build index 5901bf7cf716..660858792cb2 100644 --- a/test cases/linuxlike/3 linker script/meson.build +++ b/test cases/linuxlike/3 linker script/meson.build @@ -22,7 +22,7 @@ m = configure_file( output : 'bob-conf.map', configuration : conf, ) -vflag = '-Wl,--version-script,@0@'.format(m) +vflag = '-Wl,--version-script,@0@'.format(meson.current_build_dir() / 'bob-conf.map') l = shared_library('bob-conf', 'bob.c', link_args : vflag, link_depends : m) e = executable('prog-conf', 'prog.c', link_with : l) @@ -43,14 +43,6 @@ l = shared_library('bob-ct', ['bob.c', m], link_args : vflag, link_depends : m) e = executable('prog-ct', 'prog.c', link_with : l) test('core', e) -# File -mapfile = files('bob.map') -vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile[0]) - -l = shared_library('bob-files', 'bob.c', link_args : vflag, link_depends : mapfile) -e = executable('prog-files', 'prog.c', link_with : l) -test('core', e) - subdir('sub') # With map file in subdir From a37a20a738d2cfdb8e9c4c6c93a6bdbf43bf65a0 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 12 Sep 2023 10:03:07 -0400 Subject: [PATCH 69/99] Wrap: Use git instead of patch by default This solves problems with Strawberry Perl providing patch.exe on Windows with an unconsistent line ending support. Fixes: #12092 --- mesonbuild/wrap/wrap.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index 2b0a0ba9eb84..1b8dd37d04d5 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -797,15 +797,17 @@ def apply_diff_files(self) -> None: if not path.exists(): raise WrapException(f'Diff file "{path}" does not exist') relpath = os.path.relpath(str(path), self.dirname) - if PATCH: - # Always pass a POSIX path to patch, because on Windows it's MSYS - cmd = [PATCH, '-f', '-p1', '-i', str(Path(relpath).as_posix())] - elif GIT: - # If the `patch` command is not available, fall back to `git - # apply`. The `--work-tree` is necessary in case we're inside a + if GIT: + # Git is more likely to be available on Windows and more likely + # to apply correctly assuming patches are often generated by git. + # See https://github.com/mesonbuild/meson/issues/12092. + # The `--work-tree` is necessary in case we're inside a # Git repository: by default, Git will try to apply the patch to # the repository root. cmd = [GIT, '--work-tree', '.', 'apply', '-p1', relpath] + elif PATCH: + # Always pass a POSIX path to patch, because on Windows it's MSYS + cmd = [PATCH, '-f', '-p1', '-i', str(Path(relpath).as_posix())] else: raise WrapException('Missing "patch" or "git" commands to apply diff files') From 47d456afea54b7d7c6c99d352fd121fac7301ddc Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Wed, 30 Aug 2023 13:41:53 -0400 Subject: [PATCH 70/99] ci: Skip gir test on cygwin --- test cases/frameworks/37 gir cpp/meson.build | 6 ++++++ test cases/frameworks/37 gir cpp/test.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/test cases/frameworks/37 gir cpp/meson.build b/test cases/frameworks/37 gir cpp/meson.build index c8bf4281250c..0d228b0fe610 100644 --- a/test cases/frameworks/37 gir cpp/meson.build +++ b/test cases/frameworks/37 gir cpp/meson.build @@ -5,6 +5,12 @@ if not gi.found() error('MESON_SKIP_TEST gobject-introspection not found.') endif +if host_machine.system() == 'cygwin' + # FIXME: g-ir-scanner seems broken on cygwin: + # ERROR: can't resolve libraries to shared libraries: foo++ + error('MESON_SKIP_TEST g-ir-scanner is broken on cygwin.') +endif + gnome = import('gnome') lib = library('foo++', 'foo.cpp') diff --git a/test cases/frameworks/37 gir cpp/test.json b/test cases/frameworks/37 gir cpp/test.json index a9d74fb8a9b0..3641d75ca9e8 100644 --- a/test cases/frameworks/37 gir cpp/test.json +++ b/test cases/frameworks/37 gir cpp/test.json @@ -1,3 +1,3 @@ { - "skip_on_jobname": ["azure", "macos", "msys2"] + "skip_on_jobname": ["azure", "macos", "msys2", "cygwin"] } From b9cbf3aa6f4a8c1c5332ce7947d8040755f186b8 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Wed, 27 Sep 2023 22:09:05 +0530 Subject: [PATCH 71/99] Bump versions to 1.2.2 for release --- man/meson.1 | 2 +- mesonbuild/coredata.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/meson.1 b/man/meson.1 index f59a22714fc0..5fcc96c45f69 100644 --- a/man/meson.1 +++ b/man/meson.1 @@ -1,4 +1,4 @@ -.TH MESON "1" "August 2023" "meson 1.2.1" "User Commands" +.TH MESON "1" "September 2023" "meson 1.2.2" "User Commands" .SH NAME meson - a high productivity build system .SH DESCRIPTION diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index ddce45c02ff5..17ad7013fdc8 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -59,7 +59,7 @@ # # Pip requires that RCs are named like this: '0.1.0.rc1' # But the corresponding Git tag needs to be '0.1.0rc1' -version = '1.2.1' +version = '1.2.2' # The next stable version when we are in dev. This is used to allow projects to # require meson version >=1.2.0 when using 1.1.99. FeatureNew won't warn when From 65cb017c2b2f27f38cdfe541c5d18bd4b5846922 Mon Sep 17 00:00:00 2001 From: Xiang Gao Date: Wed, 27 Sep 2023 15:57:46 -0700 Subject: [PATCH 72/99] Allow share/cmake/ as cmake_prefix_path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is to allow passing the path share/cmake/ as cmake_prefix_path. This is a case supported by cmake and is relied on by PyTorch. The cmake prefix of PyTorch can be found by running: python -c 'import torch.utils; print(torch.utils.cmake_prefix_path)' you will see something like below from the above command: /home/gaoxiang/.virtualenvs/nvfuser/lib/python3.11/site-packages/torch/share/cmake Inspecting this directory: ❯ tree /home/gaoxiang/.virtualenvs/nvfuser/lib/python3.11/site-packages/torch/share/cmake /home/gaoxiang/.virtualenvs/nvfuser/lib/python3.11/site-packages/torch/share/cmake ├── ATen │   └── ATenConfig.cmake ├── Caffe2 │   ├── Caffe2Config.cmake │   ├── Caffe2Targets.cmake │   ├── Caffe2Targets-release.cmake │   ├── FindCUDAToolkit.cmake │   ├── FindCUSPARSELT.cmake │   ├── Modules_CUDA_fix │   │   ├── FindCUDA.cmake │   │   ├── FindCUDNN.cmake │   │   └── upstream │   │   ├── CMakeInitializeConfigs.cmake │   │   ├── FindCUDA │   │   │   ├── make2cmake.cmake │   │   │   ├── parse_cubin.cmake │   │   │   ├── run_nvcc.cmake │   │   │   └── select_compute_arch.cmake │   │   ├── FindCUDA.cmake │   │   ├── FindPackageHandleStandardArgs.cmake │   │   └── FindPackageMessage.cmake │   └── public │   ├── cuda.cmake │   ├── gflags.cmake │   ├── glog.cmake │   ├── LoadHIP.cmake │   ├── mkl.cmake │   ├── mkldnn.cmake │   ├── protobuf.cmake │   └── utils.cmake ├── Tensorpipe │   ├── TensorpipeTargets.cmake │   └── TensorpipeTargets-release.cmake └── Torch ├── TorchConfig.cmake └── TorchConfigVersion.cmake 9 directories, 28 files However, meson currently filters this directory out by `_preliminary_find_check`. As a result, doing torch_dep = dependency('Torch') will fail, even if you set `cmake_prefix_path` with the value returned by PyTorch. Possibly related issues: https://stackoverflow.com/questions/68884434/libtorch-c-meson-dependency https://github.com/mesonbuild/meson/issues/9740 https://discuss.pytorch.org/t/libtorch-meson-build/139648 --- mesonbuild/dependencies/cmake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/dependencies/cmake.py b/mesonbuild/dependencies/cmake.py index 0c6e7739cb71..0e42ad3a70e2 100644 --- a/mesonbuild/dependencies/cmake.py +++ b/mesonbuild/dependencies/cmake.py @@ -225,7 +225,7 @@ def process_paths(l: T.List[str]) -> T.Set[str]: module_paths = [x for x in module_paths if os.path.isdir(x)] archs = temp_parser.get_cmake_var('MESON_ARCH_LIST') - common_paths = ['lib', 'lib32', 'lib64', 'libx32', 'share'] + common_paths = ['lib', 'lib32', 'lib64', 'libx32', 'share', ''] for i in archs: common_paths += [os.path.join('lib', i)] From ab3d02066c91974922948f8b8b0fc944875d1a90 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sat, 30 Sep 2023 15:03:36 +0200 Subject: [PATCH 73/99] find_tool: don't assume the pkgconfig variable is a valid command ExternalProgram currently assumes that if a command is passed it exists and can be used as is. In case we extract the path from pkgconfig the path might not exist, on Windows it might be missing the ".exe" suffix. By passing the variables as a name ExternalProgram will validate that the command exists at configure time and will fail if not, and it will try to fixup the command by appending .exe etc. Fixes #12271 --- mesonbuild/modules/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index 7ef87b23a130..697f4f3e52b1 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -112,7 +112,7 @@ def find_tool(self, name: str, depname: str, varname: str, required: bool = True if dep.found() and dep.type_name == 'pkgconfig': value = dep.get_variable(pkgconfig=varname) if value: - return ExternalProgram(name, [value]) + return ExternalProgram(value) # Normal program lookup return self.find_program(name, required=required, wanted=wanted) From 5498f56e1f8fbaa6025e984a3fb02e0d0bf5ee44 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 29 Sep 2023 14:02:52 +0300 Subject: [PATCH 74/99] Mangle dashes as needed by WiX. --- packaging/createmsi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/createmsi.py b/packaging/createmsi.py index 6f198f3088b6..fef2b38759d0 100755 --- a/packaging/createmsi.py +++ b/packaging/createmsi.py @@ -291,7 +291,7 @@ def create_xml(self, nodes, current_dir, parent_xml_node, staging_dir): }) for dirname in cur_node.dirs: - dir_id = os.path.join(current_dir, dirname).replace('\\', '_').replace('/', '_') + dir_id = os.path.join(current_dir, dirname).replace('\\', '_').replace('/', '_').replace('-', '_') dir_node = ET.SubElement(parent_xml_node, 'Directory', { 'Id': dir_id, 'Name': dirname, From 030d0fc2648582136e68b667fad1150fbdc88f1f Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Mon, 2 Oct 2023 13:46:39 -0700 Subject: [PATCH 75/99] nasm tests: skip asm language test on Solaris & illumos The code in this test to make Linux system calls is not compatible with the SunOS kernel system call conventions. --- test cases/nasm/2 asm language/meson.build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test cases/nasm/2 asm language/meson.build b/test cases/nasm/2 asm language/meson.build index 0eecd99a648b..d025d43ea9b7 100644 --- a/test cases/nasm/2 asm language/meson.build +++ b/test cases/nasm/2 asm language/meson.build @@ -7,6 +7,8 @@ endif if host_machine.system() == 'windows' error('MESON_SKIP_TEST: this test asm is not made for Windows') +elif host_machine.system() == 'sunos' + error('MESON_SKIP_TEST: this test asm is not made for Solaris or illumos') endif if meson.backend().startswith('vs') From f8b2ee1010f95751cea0f8667870ed0b7e37acf7 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Fri, 8 Sep 2023 16:54:48 -0400 Subject: [PATCH 76/99] python dependency: ensure that setuptools doesn't inject itself into distutils We do not use setuptools for anything, and only lightly use distutils. Unpredictable issues can occur due to setuptools monkey-patching, which interferes with our intended use. Tell setuptools to simply never get involved. Note: while it's otherwise possible to check if the probe is run using sys.executable and avoid forking, setuptools unconditionally injects itself at startup in a way that requires subprocess isolation to disable. --- mesonbuild/dependencies/python.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py index 1607728883df..f04494674726 100644 --- a/mesonbuild/dependencies/python.py +++ b/mesonbuild/dependencies/python.py @@ -113,7 +113,9 @@ def sanity(self) -> bool: with importlib.resources.path('mesonbuild.scripts', 'python_info.py') as f: cmd = self.get_command() + [str(f)] - p, stdout, stderr = mesonlib.Popen_safe(cmd) + env = os.environ.copy() + env['SETUPTOOLS_USE_DISTUTILS'] = 'stdlib' + p, stdout, stderr = mesonlib.Popen_safe(cmd, env=env) try: info = json.loads(stdout) From d573c8f105948a30d7485eb5049c3649cf676acd Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Mon, 21 Nov 2022 20:47:14 -0500 Subject: [PATCH 77/99] python module: stop using distutils schemes on sufficiently new Debian Since 3.10.3, Debian finally started patching sysconfig with custom paths, instead of just distutils. This means we can now go use that instead. It reduces our reliance on the deprecated distutils module. Partial fix for #7702 --- mesonbuild/scripts/python_info.py | 32 +++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/mesonbuild/scripts/python_info.py b/mesonbuild/scripts/python_info.py index 9c3a0791ac90..65597b12167d 100755 --- a/mesonbuild/scripts/python_info.py +++ b/mesonbuild/scripts/python_info.py @@ -13,7 +13,6 @@ del sys.path[0] import json, os, sysconfig -import distutils.command.install def get_distutils_paths(scheme=None, prefix=None): import distutils.dist @@ -37,15 +36,32 @@ def get_distutils_paths(scheme=None, prefix=None): # default scheme to a custom one pointing to /usr/local and replacing # site-packages with dist-packages. # See https://github.com/mesonbuild/meson/issues/8739. -# XXX: We should be using sysconfig, but Debian only patches distutils. +# +# We should be using sysconfig, but before 3.10.3, Debian only patches distutils. +# So we may end up falling back. -if 'deb_system' in distutils.command.install.INSTALL_SCHEMES: - paths = get_distutils_paths(scheme='deb_system') - install_paths = get_distutils_paths(scheme='deb_system', prefix='') -else: - paths = sysconfig.get_paths() +def get_install_paths(): + if sys.version_info >= (3, 10): + scheme = sysconfig.get_default_scheme() + else: + scheme = sysconfig._get_default_scheme() + + if sys.version_info >= (3, 10, 3): + if 'deb_system' in sysconfig.get_scheme_names(): + scheme = 'deb_system' + else: + import distutils.command.install + if 'deb_system' in distutils.command.install.INSTALL_SCHEMES: + paths = get_distutils_paths(scheme='deb_system') + install_paths = get_distutils_paths(scheme='deb_system', prefix='') + return paths, install_paths + + paths = sysconfig.get_paths(scheme=scheme) empty_vars = {'base': '', 'platbase': '', 'installed_base': ''} - install_paths = sysconfig.get_paths(vars=empty_vars) + install_paths = sysconfig.get_paths(scheme=scheme, vars=empty_vars) + return paths, install_paths + +paths, install_paths = get_install_paths() def links_against_libpython(): from distutils.core import Distribution, Extension From 3c3caf5163e2efdb2bc6a7089a7f4e0c5d058efb Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 22 Nov 2022 22:56:10 -0500 Subject: [PATCH 78/99] python module: stop using distutils "link to libpython" probe on recent python On python >=3.8, this information is expected to be encoded in the sysconfig vars. In distutils, it is always necessary to link to libpython on Windows; for posix platforms, it depends on the value of LIBPYTHON (which is the library to link to, possibly the empty string) as generated by configure.ac and embedded into python.pc and python-config.sh, and then coded a second time in the distutils python sources. There are a couple of caveats which have ramifications for Cygwin and Android: - python.pc and python-config.sh disagree with distutils when python is not built shared. In that case, the former act the same as a shared build, while the latter *never* links to libpython - python.pc disagrees with python-config.sh and distutils when python is built shared. The former never links to libpython, while the latter do The disagreement is resolved in favor of distutils' behavior in all cases, and python.pc is correct for our purposes on python 3.12; see: https://github.com/python/cpython/pull/100356 https://github.com/python/cpython/pull/100967 Although it was not backported to older releases, Cygwin at least has always patched in a fix for python.pc, which behavior is now declared canonical. We can reliably assume it is always correct. This is the other half of the fix for #7702 --- mesonbuild/scripts/python_info.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/mesonbuild/scripts/python_info.py b/mesonbuild/scripts/python_info.py index 65597b12167d..e9a78f84141a 100755 --- a/mesonbuild/scripts/python_info.py +++ b/mesonbuild/scripts/python_info.py @@ -64,13 +64,23 @@ def get_install_paths(): paths, install_paths = get_install_paths() def links_against_libpython(): - from distutils.core import Distribution, Extension - cmd = Distribution().get_command_obj('build_ext') - cmd.ensure_finalized() - return bool(cmd.get_libraries(Extension('dummy', []))) + # on versions supporting python-embed.pc, this is the non-embed lib + # + # PyPy is not yet up to 3.12 and work is still pending to export the + # relevant information (it doesn't automatically provide arbitrary + # Makefile vars) + if sys.version_info >= (3, 8) and not is_pypy: + variables = sysconfig.get_config_vars() + return bool(variables.get('LIBPYTHON', 'yes')) + else: + from distutils.core import Distribution, Extension + cmd = Distribution().get_command_obj('build_ext') + cmd.ensure_finalized() + return bool(cmd.get_libraries(Extension('dummy', []))) variables = sysconfig.get_config_vars() variables.update({'base_prefix': getattr(sys, 'base_prefix', sys.prefix)}) +is_pypy = '__pypy__' in sys.builtin_module_names if sys.version_info < (3, 0): suffix = variables.get('SO') @@ -88,7 +98,7 @@ def links_against_libpython(): 'install_paths': install_paths, 'version': sysconfig.get_python_version(), 'platform': sysconfig.get_platform(), - 'is_pypy': '__pypy__' in sys.builtin_module_names, + 'is_pypy': is_pypy, 'is_venv': sys.prefix != variables['base_prefix'], 'link_libpython': links_against_libpython(), 'suffix': suffix, From 618c6ccbb530af33c32defbf87934eecd8f8e7af Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Mon, 2 Oct 2023 23:51:57 -0400 Subject: [PATCH 79/99] tests: fix test case to not import distutils on python 3.12 Testing the correctness of the `modules: ` kwarg can be done with other guaranteed stdlib modules that are even more guaranteed since they didn't get deprecated for removal. --- test cases/python/5 modules kwarg/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test cases/python/5 modules kwarg/meson.build b/test cases/python/5 modules kwarg/meson.build index 9751adaaba2b..41a9a4faee9a 100644 --- a/test cases/python/5 modules kwarg/meson.build +++ b/test cases/python/5 modules kwarg/meson.build @@ -1,7 +1,7 @@ project('python kwarg') py = import('python') -prog_python = py.find_installation('python3', modules : ['distutils']) +prog_python = py.find_installation('python3', modules : ['os', 'sys', 're']) assert(prog_python.found() == true, 'python not found when should be') prog_python = py.find_installation('python3', modules : ['thisbetternotexistmod'], required : false) assert(prog_python.found() == false, 'python not found but reported as found') From 195ba1c2594de5a6b240eec5a166f899bb2f33dc Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 3 Oct 2023 00:22:25 -0400 Subject: [PATCH 80/99] mark the PyPI metadata as supporting python 3.12 meson itself runs okay on 3.12, and the last issue for *probing* against 3.12 is solved. Tests pass here locally. --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index dfaba76dd194..2f2962eedcba 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,6 +30,7 @@ classifiers = Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 Topic :: Software Development :: Build Tools long_description = Meson is a cross-platform build system designed to be both as fast and as user friendly as possible. It supports many languages and compilers, including GCC, Clang, PGI, Intel, and Visual Studio. Its build definitions are written in a simple non-Turing complete DSL. From 707f284db37640a099b5c2192e3902d228594316 Mon Sep 17 00:00:00 2001 From: Charles Brunet Date: Tue, 3 Oct 2023 11:48:46 -0400 Subject: [PATCH 81/99] temp disable pylint falsepositive on dub.py This was introduced by pylint 3.0.0. See https://github.com/pylint-dev/pylint/issues/9095. --- mesonbuild/dependencies/dub.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/dependencies/dub.py b/mesonbuild/dependencies/dub.py index 37a9ea11e5eb..c206ce9e73bf 100644 --- a/mesonbuild/dependencies/dub.py +++ b/mesonbuild/dependencies/dub.py @@ -53,7 +53,7 @@ def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T. self.is_found = False return - (self.dubbin, dubver) = DubDependency.class_dubbin + (self.dubbin, dubver) = DubDependency.class_dubbin # pylint: disable=unpacking-non-sequence assert isinstance(self.dubbin, ExternalProgram) From 404ed7b006aeeeda20ffbfad5104871c56fb01d6 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 3 Oct 2023 01:19:13 -0400 Subject: [PATCH 82/99] CI: install an older java on opensuse They do not appear to have 20 in their repos anymore, and no traces can be found of it in the history, as usual. They do have 11, 17, and 21. Last time we chose one randomly and hoped it doesn't keep changing value. This dismally failed: 20 was upgraded to 21. It looks like 17 may have some staying power. --- ci/ciimage/opensuse/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/ciimage/opensuse/install.sh b/ci/ciimage/opensuse/install.sh index 41cb96192e8f..b0097172a8a9 100755 --- a/ci/ciimage/opensuse/install.sh +++ b/ci/ciimage/opensuse/install.sh @@ -9,7 +9,7 @@ pkgs=( ninja make git autoconf automake patch libjpeg-devel elfutils gcc gcc-c++ gcc-fortran gcc-objc gcc-obj-c++ vala rust bison flex curl lcov mono-core gtkmm3-devel gtest gmock protobuf-devel wxGTK3-3_2-devel gobject-introspection-devel - itstool gtk3-devel java-15-openjdk-devel gtk-doc llvm-devel clang-devel libSDL2-devel graphviz-devel zlib-devel zlib-devel-static + itstool gtk3-devel java-17-openjdk-devel gtk-doc llvm-devel clang-devel libSDL2-devel graphviz-devel zlib-devel zlib-devel-static #hdf5-devel netcdf-devel libscalapack2-openmpi3-devel libscalapack2-gnu-openmpi3-hpc-devel openmpi3-devel doxygen vulkan-devel vulkan-validationlayers openssh mercurial gtk-sharp3-complete gtk-sharp2-complete libpcap-devel libgpgme-devel libqt5-qtbase-devel libqt5-qttools-devel libqt5-linguist libqt5-qtbase-private-headers-devel From e03bcf7d68f25775cd086ca92edc7d76915ae10a Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 3 Oct 2023 11:20:50 -0400 Subject: [PATCH 83/99] CI: fix broken ciimage builder script failing to correctly copy meson Regression in commit 0af126fec798d6dbb0d1ad52168cc1f3f1758acd. We added support for some "test cases/" stuff that actually relies on test files being a symlink, but when testing the image builder, we copied the meson repository contents into the docker container without telling python that it is in fact super important to copy symlinks as symlinks. As a result, the tests themselves ran fine when merging, but caused the image builder to thereafter fail. --- ci/ciimage/build.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/ciimage/build.py b/ci/ciimage/build.py index 01979556dcfb..f9c0ad6a78a1 100755 --- a/ci/ciimage/build.py +++ b/ci/ciimage/build.py @@ -137,13 +137,14 @@ def copy_meson(self) -> None: shutil.copytree( self.meson_root, self.temp_dir / 'meson', + symlinks=True, ignore=shutil.ignore_patterns( '.git', '*_cache', '__pycache__', # 'work area', self.temp_dir.name, - ) + ), ) def do_test(self, tty: bool = False) -> None: From 2d01821b9f9ce6f031b7558b6ce6b417dc5b833f Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 3 Oct 2023 11:43:28 -0400 Subject: [PATCH 84/99] CI: fix the fix for python actually being mildly useful In commit 5c479d7a13a518c18ccb4dc3b6bdd7bfc2a9bdb5, we deleted bad stuff that makes python not work. But we missed the case where it is installed to lib64. --- ci/ciimage/common.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/ciimage/common.sh b/ci/ciimage/common.sh index 6209ef9a1c08..67d59978f5a7 100644 --- a/ci/ciimage/common.sh +++ b/ci/ciimage/common.sh @@ -39,11 +39,11 @@ dub_fetch() { } install_minimal_python_packages() { - rm -f /usr/lib/python3.*/EXTERNALLY-MANAGED + rm -f /usr/lib*/python3.*/EXTERNALLY-MANAGED python3 -m pip install "${base_python_pkgs[@]}" $* } install_python_packages() { - rm -f /usr/lib/python3.*/EXTERNALLY-MANAGED + rm -f /usr/lib*/python3.*/EXTERNALLY-MANAGED python3 -m pip install "${base_python_pkgs[@]}" "${python_pkgs[@]}" $* } From 361812c4a6d429cbc3cda7e0739ef65eb7e82df0 Mon Sep 17 00:00:00 2001 From: Nigel Kukard Date: Mon, 9 Oct 2023 00:00:39 +0000 Subject: [PATCH 85/99] Add support for lcov 2.0 lcov 2.0 deprecates `--rc lcov_branch_coverage=1` for `--rc branch_coverage=1` and gives an error when an exclude is used on a non existing directory. I added a version check for lcov and removed the subprojects directory from the exclusion list if it does not exist. Fixes #11995 --- mesonbuild/backend/ninjabackend.py | 2 +- mesonbuild/environment.py | 22 +++++++++++++++++----- mesonbuild/scripts/coverage.py | 20 ++++++++++++++------ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 3560d1ed24ad..320c30220ae2 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -636,7 +636,7 @@ def generate(self, capture: bool = False, vslite_ctx: dict = None) -> T.Optional key = OptionKey('b_coverage') if (key in self.environment.coredata.options and self.environment.coredata.options[key].value): - gcovr_exe, gcovr_version, lcov_exe, genhtml_exe, _ = environment.find_coverage_tools() + gcovr_exe, gcovr_version, lcov_exe, lcov_version, genhtml_exe, _ = environment.find_coverage_tools() if gcovr_exe or (lcov_exe and genhtml_exe): self.add_build_comment(NinjaComment('Coverage rules')) self.generate_coverage_rules(gcovr_exe, gcovr_version) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index cd9d487085a7..3d25b92f14f7 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -96,6 +96,20 @@ def detect_gcovr(min_version='3.3', log=False): return gcovr_exe, found return None, None +def detect_lcov(log: bool = False): + lcov_exe = 'lcov' + try: + p, found = Popen_safe([lcov_exe, '--version'])[0:2] + except (FileNotFoundError, PermissionError): + # Doesn't exist in PATH or isn't executable + return None, None + found = search_version(found) + if p.returncode == 0 and found: + if log: + mlog.log('Found lcov-{} at {}'.format(found, quote_arg(shutil.which(lcov_exe)))) + return lcov_exe, found + return None, None + def detect_llvm_cov(): tools = get_llvm_tool_names('llvm-cov') for tool in tools: @@ -103,20 +117,18 @@ def detect_llvm_cov(): return tool return None -def find_coverage_tools() -> T.Tuple[T.Optional[str], T.Optional[str], T.Optional[str], T.Optional[str], T.Optional[str]]: +def find_coverage_tools() -> T.Tuple[T.Optional[str], T.Optional[str], T.Optional[str], T.Optional[str], T.Optional[str], T.Optional[str]]: gcovr_exe, gcovr_version = detect_gcovr() llvm_cov_exe = detect_llvm_cov() - lcov_exe = 'lcov' + lcov_exe, lcov_version = detect_lcov() genhtml_exe = 'genhtml' - if not mesonlib.exe_exists([lcov_exe, '--version']): - lcov_exe = None if not mesonlib.exe_exists([genhtml_exe, '--version']): genhtml_exe = None - return gcovr_exe, gcovr_version, lcov_exe, genhtml_exe, llvm_cov_exe + return gcovr_exe, gcovr_version, lcov_exe, lcov_version, genhtml_exe, llvm_cov_exe def detect_ninja(version: str = '1.8.2', log: bool = False) -> T.List[str]: r = detect_ninja_command_and_version(version, log) diff --git a/mesonbuild/scripts/coverage.py b/mesonbuild/scripts/coverage.py index cb865d08d258..4c0f81e8a026 100644 --- a/mesonbuild/scripts/coverage.py +++ b/mesonbuild/scripts/coverage.py @@ -22,7 +22,7 @@ def coverage(outputs: T.List[str], source_root: str, subproject_root: str, build outfiles = [] exitcode = 0 - (gcovr_exe, gcovr_version, lcov_exe, genhtml_exe, llvm_cov_exe) = environment.find_coverage_tools() + (gcovr_exe, gcovr_version, lcov_exe, lcov_version, genhtml_exe, llvm_cov_exe) = environment.find_coverage_tools() # load config files for tools if available in the source tree # - lcov requires manually specifying a per-project config @@ -35,6 +35,11 @@ def coverage(outputs: T.List[str], source_root: str, subproject_root: str, build else: lcov_config = [] + if lcov_exe and mesonlib.version_compare(lcov_version, '>=2.0'): + lcov_exe_rc_branch_coverage = ['--rc', 'branch_coverage=1'] + else: + lcov_exe_rc_branch_coverage = ['--rc', 'lcov_branch_coverage=1'] + gcovr_config = ['-e', re.escape(subproject_root)] # gcovr >= 4.2 requires a different syntax for out of source builds @@ -90,6 +95,9 @@ def coverage(outputs: T.List[str], source_root: str, subproject_root: str, build initial_tracefile = covinfo + '.initial' run_tracefile = covinfo + '.run' raw_tracefile = covinfo + '.raw' + lcov_subpoject_exclude = [] + if os.path.exists(subproject_root): + lcov_subpoject_exclude.append(os.path.join(subproject_root, '*')) if use_llvm_cov: # Create a shim to allow using llvm-cov as a gcov tool. if mesonlib.is_windows(): @@ -117,26 +125,26 @@ def coverage(outputs: T.List[str], source_root: str, subproject_root: str, build '--capture', '--output-file', run_tracefile, '--no-checksum', - '--rc', 'lcov_branch_coverage=1'] + + *lcov_exe_rc_branch_coverage] + lcov_config + gcov_tool_args) # Join initial and test results. subprocess.check_call([lcov_exe, '-a', initial_tracefile, '-a', run_tracefile, - '--rc', 'lcov_branch_coverage=1', + *lcov_exe_rc_branch_coverage, '-o', raw_tracefile] + lcov_config) # Remove all directories outside the source_root from the covinfo subprocess.check_call([lcov_exe, '--extract', raw_tracefile, os.path.join(source_root, '*'), - '--rc', 'lcov_branch_coverage=1', + *lcov_exe_rc_branch_coverage, '--output-file', covinfo] + lcov_config) # Remove all directories inside subproject dir subprocess.check_call([lcov_exe, '--remove', covinfo, - os.path.join(subproject_root, '*'), - '--rc', 'lcov_branch_coverage=1', + *lcov_subpoject_exclude, + *lcov_exe_rc_branch_coverage, '--output-file', covinfo] + lcov_config) subprocess.check_call([genhtml_exe, '--prefix', build_root, From 15fd6ec6db389e9890f85fa0502673bac739b1ca Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Sun, 8 Oct 2023 22:51:06 -0400 Subject: [PATCH 86/99] wrap: catch failure to extract tarball and raise WrapException This most likely happens when the source archive has files which take advantage of case sensitivity, and someone is unfortunate enough to have to work with broken operating systems that do not have the capacity to use modern technology, like the 1970s invention of case sensitive filesystems. For example, Windows and macOS both have retrocomputing environments, where case sensitive abilities were carefully removed from modern filesystems in order to share the delights of classical computing with the masses. On such systems, innocent tarballs fail to extract with: ``` OSError: [Errno 22] Invalid argument: 'C:\path\to\file' ``` thereby demonstrating Microsoft's unbounded and enthusiastic love for users (who are, universally, retrocomputing fans). n.b. there is, begrudgingly, a secret option for crazy people who hate retrocomputing to enable modern 1970s computing on Windows systems. Naturally, no one with any sense would ever use this, and it is rightly left in its sensible default in for example Github Actions. Fixes #12344 --- mesonbuild/wrap/wrap.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index 1b8dd37d04d5..faa167e64033 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -547,7 +547,10 @@ def get_file(self) -> None: if 'lead_directory_missing' in self.wrap.values: os.mkdir(self.dirname) extract_dir = self.dirname - shutil.unpack_archive(path, extract_dir) + try: + shutil.unpack_archive(path, extract_dir) + except OSError as e: + raise WrapException(f'failed to unpack archive with error: {str(e)}') from e def get_git(self) -> None: if not GIT: From 64543603d1e8ba35278404c1a7b92b8c940a371c Mon Sep 17 00:00:00 2001 From: Steven Noonan Date: Tue, 20 Jun 2023 14:33:50 -0700 Subject: [PATCH 87/99] c++: add fallback mappings for C++23 The c++23 mappings apply to current production compilers (GCC, Clang). Signed-off-by: Steven Noonan Signed-off-by: Patrick Williams Backported-by: Nirbheek Chauhan --- mesonbuild/compilers/cpp.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 0c6892374f7f..0aa72f8305ec 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -154,6 +154,8 @@ def _find_best_cpp_std(self, cpp_std: str) -> str: 'gnu++17': 'gnu++1z', 'c++20': 'c++2a', 'gnu++20': 'gnu++2a', + 'c++23': 'c++2b', + 'gnu++23': 'gnu++2b', } # Currently, remapping is only supported for Clang, Elbrus and GCC From 5c1b0ef18425b30a9df5f8443b68d71d276a2bbf Mon Sep 17 00:00:00 2001 From: Steven Noonan Date: Tue, 20 Jun 2023 15:45:18 -0700 Subject: [PATCH 88/99] tests: add support for c++23 detection Signed-off-by: Steven Noonan Signed-off-by: Patrick Williams Backported-by: Nirbheek Chauhan --- unittests/linuxliketests.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/unittests/linuxliketests.py b/unittests/linuxliketests.py index b5c9b4ee3146..9445d59d0887 100644 --- a/unittests/linuxliketests.py +++ b/unittests/linuxliketests.py @@ -517,6 +517,12 @@ def _test_stds_impl(self, testdir: str, compiler: 'Compiler') -> None: has_cpp20 = (compiler.get_id() not in {'clang', 'gcc'} or compiler.get_id() == 'clang' and _clang_at_least(compiler, '>=10.0.0', None) or compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=10.0.0')) + has_cpp2b = (compiler.get_id() not in {'clang', 'gcc'} or + compiler.get_id() == 'clang' and _clang_at_least(compiler, '>=12.0.0', None) or + compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=12.2.0')) + has_cpp23 = (compiler.get_id() not in {'clang', 'gcc'} or + compiler.get_id() == 'clang' and _clang_at_least(compiler, '>=17.0.0', None) or + compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=12.2.0')) has_c18 = (compiler.get_id() not in {'clang', 'gcc'} or compiler.get_id() == 'clang' and _clang_at_least(compiler, '>=8.0.0', '>=11.0') or compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=8.0.0')) @@ -533,6 +539,10 @@ def _test_stds_impl(self, testdir: str, compiler: 'Compiler') -> None: continue elif '++20' in v and not has_cpp20: continue + elif '++2b' in v and not has_cpp2b: + continue + elif '++23' in v and not has_cpp23: + continue # now C elif '17' in v and not has_cpp2a_c17: continue From 002982be4faf8935d33693da2a37661be2875e24 Mon Sep 17 00:00:00 2001 From: Steven Noonan Date: Tue, 20 Jun 2023 14:34:47 -0700 Subject: [PATCH 89/99] c++: add support for c++23 standard and aliases GCC 12.3 and Clang 16 support -std flags for c++23/c++2b. Signed-off-by: Steven Noonan Signed-off-by: Patrick Williams Backported-by: Nirbheek Chauhan --- mesonbuild/compilers/cpp.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 0aa72f8305ec..399ef0977502 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -224,6 +224,9 @@ def language_stdlib_only_link_flags(self, env: Environment) -> T.List[str]: class ClangCPPCompiler(_StdCPPLibMixin, ClangCompiler, CPPCompiler): + + _CPP23_VERSION = '>=12.0.0' + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, linker: T.Optional['DynamicLinker'] = None, @@ -250,11 +253,15 @@ def get_options(self) -> 'MutableKeyedOptionDictType': ), key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True), }) - opts[key.evolve('std')].choices = [ + cppstd_choices = [ 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a', 'c++20', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a', 'gnu++20', ] + if version_compare(self.version, self._CPP23_VERSION): + cppstd_choices.append('c++23') + cppstd_choices.append('gnu++23') + opts[key.evolve('std')].choices = cppstd_choices if self.info.is_windows() or self.info.is_cygwin(): opts.update({ key.evolve('winlibs'): coredata.UserArrayOption( @@ -296,7 +303,8 @@ class ArmLtdClangCPPCompiler(ClangCPPCompiler): class AppleClangCPPCompiler(ClangCPPCompiler): - pass + + _CPP23_VERSION = '>=13.0.0' class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler): From 33f0df48341f4cb4dbf8579e47c26148736c1dc9 Mon Sep 17 00:00:00 2001 From: Benjamin Redelings Date: Sat, 7 Oct 2023 10:37:49 -0400 Subject: [PATCH 90/99] Allow c++23 in gcc-11. --- mesonbuild/compilers/cpp.py | 2 +- unittests/linuxliketests.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 399ef0977502..c7a0a928b988 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -421,7 +421,7 @@ def get_options(self) -> 'MutableKeyedOptionDictType': 'c++2a', 'c++20', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a', 'gnu++20', ] - if version_compare(self.version, '>=12.2.0'): + if version_compare(self.version, '>=11.0.0'): cppstd_choices.append('c++23') cppstd_choices.append('gnu++23') opts[key].choices = cppstd_choices diff --git a/unittests/linuxliketests.py b/unittests/linuxliketests.py index 9445d59d0887..1899cb48ccc6 100644 --- a/unittests/linuxliketests.py +++ b/unittests/linuxliketests.py @@ -519,10 +519,10 @@ def _test_stds_impl(self, testdir: str, compiler: 'Compiler') -> None: compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=10.0.0')) has_cpp2b = (compiler.get_id() not in {'clang', 'gcc'} or compiler.get_id() == 'clang' and _clang_at_least(compiler, '>=12.0.0', None) or - compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=12.2.0')) + compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=11.0.0')) has_cpp23 = (compiler.get_id() not in {'clang', 'gcc'} or compiler.get_id() == 'clang' and _clang_at_least(compiler, '>=17.0.0', None) or - compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=12.2.0')) + compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=11.0.0')) has_c18 = (compiler.get_id() not in {'clang', 'gcc'} or compiler.get_id() == 'clang' and _clang_at_least(compiler, '>=8.0.0', '>=11.0') or compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=8.0.0')) From 11e5cac8ef869565eae7d0b14249ad5611c1a550 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Sat, 7 Oct 2023 03:09:44 +0530 Subject: [PATCH 91/99] msubprojects: Abort the rebase if there's conflicts Don't leave the subproject tree in a broken / conflicting state. The user is most likely not a git expert who will know what magic command to run to fix their source tree. --- mesonbuild/msubprojects.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mesonbuild/msubprojects.py b/mesonbuild/msubprojects.py index 8f3231c1163a..74b8286f7783 100755 --- a/mesonbuild/msubprojects.py +++ b/mesonbuild/msubprojects.py @@ -229,7 +229,9 @@ def git_rebase(self, revision: str) -> bool: try: self.git_output(['-c', 'rebase.autoStash=true', 'rebase', 'FETCH_HEAD']) except GitException as e: - self.log(' -> Could not rebase', mlog.bold(self.repo_dir), 'onto', mlog.bold(revision)) + self.git_output(['-c', 'rebase.autoStash=true', 'rebase', '--abort']) + self.log(' -> Could not rebase', mlog.bold(self.repo_dir), 'onto', mlog.bold(revision), + '-- aborted') self.log(mlog.red(e.output)) self.log(mlog.red(str(e))) return False From 428c89a38005e22feb2571a54389e4079d6ba5a7 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Sat, 7 Oct 2023 03:10:41 +0530 Subject: [PATCH 92/99] msubprojects: Checkout if the branch is tracking upstream A rebase of the current branch is the wrong thing to do if the revision (branch) specified in the wrap changed, which is the case in the majority of cases, such as when switching from one release branch to another. --- mesonbuild/msubprojects.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/mesonbuild/msubprojects.py b/mesonbuild/msubprojects.py index 74b8286f7783..3e00b4e37e5b 100755 --- a/mesonbuild/msubprojects.py +++ b/mesonbuild/msubprojects.py @@ -285,6 +285,19 @@ def git_checkout_and_rebase(self, revision: str) -> bool: success = self.git_rebase(revision) return success + def git_branch_has_upstream(self, urls: set) -> bool: + cmd = ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'] + ret, upstream = quiet_git(cmd, self.repo_dir) + if not ret: + return False + try: + remote = upstream.split('/', maxsplit=1)[0] + except IndexError: + return False + cmd = ['remote', 'get-url', remote] + ret, remote_url = quiet_git(cmd, self.repo_dir) + return remote_url.strip() in urls + def update_git(self) -> bool: options = T.cast('UpdateArguments', self.options) if not os.path.exists(os.path.join(self.repo_dir, '.git')): @@ -376,12 +389,16 @@ def update_git(self) -> bool: success = self.git_rebase(revision) else: # We are in another branch, either the user created their own branch and - # we should rebase it, or revision changed in the wrap file and we need - # to checkout the new branch. + # we should rebase it, or revision changed in the wrap file (we + # know this when the current branch has an upstream) and we need to + # checkout the new branch. if options.reset: success = self.git_checkout_and_reset(revision) else: - success = self.git_rebase(revision) + if self.git_branch_has_upstream({url, push_url}): + success = self.git_checkout_and_rebase(revision) + else: + success = self.git_rebase(revision) if success: self.update_git_done() return success From 5f86d62e9109392223d0325cc7310f19d71859ec Mon Sep 17 00:00:00 2001 From: Ada Date: Tue, 10 Oct 2023 14:59:32 +0100 Subject: [PATCH 93/99] Fix MSVC linker error LNK1170 with long rspfiles The MSVC linker errors out if a line in the rspfile is too long. The resolution is to use the built-in ninja keyword $in_newline instead of $in, which splits each input into separate lines. --- mesonbuild/backend/ninjabackend.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 320c30220ae2..796fa039d106 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -237,8 +237,10 @@ def _quoter(x, qf = quote_func): return ninja_quote(qf(str(x))) def write(self, outfile: T.TextIO) -> None: + rspfile_args = self.args if self.rspfile_quote_style is RSPFileSyntax.MSVC: rspfile_quote_func = cmd_quote + rspfile_args = [NinjaCommandArg('$in_newline', arg.quoting) if arg.s == '$in' else arg for arg in rspfile_args] else: rspfile_quote_func = gcc_rsp_quote @@ -253,7 +255,7 @@ def rule_iter(): if rsp == '_RSP': outfile.write(' command = {} @$out.rsp\n'.format(' '.join([self._quoter(x) for x in self.command]))) outfile.write(' rspfile = $out.rsp\n') - outfile.write(' rspfile_content = {}\n'.format(' '.join([self._quoter(x, rspfile_quote_func) for x in self.args]))) + outfile.write(' rspfile_content = {}\n'.format(' '.join([self._quoter(x, rspfile_quote_func) for x in rspfile_args]))) else: outfile.write(' command = {}\n'.format(' '.join([self._quoter(x) for x in self.command + self.args]))) if self.deps: From 639ed002fc4ceca3f172e7e2ff8acc0b457583e8 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 12 Oct 2023 05:40:07 +0530 Subject: [PATCH 94/99] ninjabackend: Use the right ranlib for static linker rules Fixes https://github.com/mesonbuild/meson/issues/12349 --- mesonbuild/backend/ninjabackend.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 796fa039d106..ef9a322a2906 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2366,7 +2366,12 @@ def generate_static_link_rules(self): # ranlib, not to ar cmdlist.extend(args) args = [] - cmdlist.extend(['&&', 'ranlib', '-c', '$out']) + # Ensure that we use the user-specified ranlib if any, and + # fallback to just picking up some ranlib otherwise + ranlib = self.environment.lookup_binary_entry(for_machine, 'ranlib') + if ranlib is None: + ranlib = ['ranlib'] + cmdlist.extend(['&&'] + ranlib + ['-c', '$out']) description = 'Linking static target $out' if num_pools > 0: pool = 'pool = link_pool' From 6496038fa52783e62994f6695c0dcaaee121f711 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Mon, 16 Oct 2023 17:34:59 -0400 Subject: [PATCH 95/99] msubprojects: Fix crash if wrapdb_version is in bad format Fixes: #12378 --- mesonbuild/msubprojects.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mesonbuild/msubprojects.py b/mesonbuild/msubprojects.py index 3e00b4e37e5b..330e16b9a0c1 100755 --- a/mesonbuild/msubprojects.py +++ b/mesonbuild/msubprojects.py @@ -153,6 +153,11 @@ def update_wrapdb(self) -> bool: try: wrapdb_version = self.wrap.get('wrapdb_version') branch, revision = wrapdb_version.split('-', 1) + except ValueError: + if not options.force: + self.log(' ->', mlog.red('Malformed wrapdb_version field, use --force to update any way')) + return False + branch = revision = None except WrapException: # Fallback to parsing the patch URL to determine current version. # This won't work for projects that have upstream Meson support. From 0958291f67ac1b21697456f95e46100020a29672 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Tue, 17 Oct 2023 13:01:23 +0530 Subject: [PATCH 96/99] msubprojects: Fix typo 'any way' -> 'anyway' --- mesonbuild/msubprojects.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mesonbuild/msubprojects.py b/mesonbuild/msubprojects.py index 330e16b9a0c1..f20290debf27 100755 --- a/mesonbuild/msubprojects.py +++ b/mesonbuild/msubprojects.py @@ -155,7 +155,7 @@ def update_wrapdb(self) -> bool: branch, revision = wrapdb_version.split('-', 1) except ValueError: if not options.force: - self.log(' ->', mlog.red('Malformed wrapdb_version field, use --force to update any way')) + self.log(' ->', mlog.red('Malformed wrapdb_version field, use --force to update anyway')) return False branch = revision = None except WrapException: @@ -166,7 +166,7 @@ def update_wrapdb(self) -> bool: branch, revision = parse_patch_url(patch_url) except WrapException: if not options.force: - self.log(' ->', mlog.red('Could not determine current version, use --force to update any way')) + self.log(' ->', mlog.red('Could not determine current version, use --force to update anyway')) return False branch = revision = None From 63b5a02353e267430cc2f66f2d0317b6d2062800 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Wed, 18 Oct 2023 08:04:57 +0530 Subject: [PATCH 97/99] Revert "rust: apply global, project, and environment C args to bindgen" This reverts commit 36210f64f22dc10d324db76bb1a7988c9cd5b14e. Fixes https://github.com/mesonbuild/meson/issues/12326 --- mesonbuild/modules/rust.py | 6 ------ test cases/rust/12 bindgen/meson.build | 18 ------------------ .../rust/12 bindgen/src/global-project.h | 10 ---------- test cases/rust/12 bindgen/src/global.c | 5 ----- test cases/rust/12 bindgen/src/global.rs | 14 -------------- test cases/rust/12 bindgen/test.json | 5 +---- 6 files changed, 1 insertion(+), 57 deletions(-) delete mode 100644 test cases/rust/12 bindgen/src/global-project.h delete mode 100644 test cases/rust/12 bindgen/src/global.c delete mode 100644 test cases/rust/12 bindgen/src/global.rs diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py index e6e5c633ff11..3514412e65df 100644 --- a/mesonbuild/modules/rust.py +++ b/mesonbuild/modules/rust.py @@ -232,12 +232,6 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu elif isinstance(s, CustomTarget): depends.append(s) - clang_args.extend(state.global_args.get('c', [])) - clang_args.extend(state.project_args.get('c', [])) - cargs = state.get_option('args', state.subproject, lang='c') - assert isinstance(cargs, list), 'for mypy' - clang_args.extend(cargs) - if self._bindgen_bin is None: self._bindgen_bin = state.find_program('bindgen') diff --git a/test cases/rust/12 bindgen/meson.build b/test cases/rust/12 bindgen/meson.build index e7cb5f3db2c0..c05cc063136c 100644 --- a/test cases/rust/12 bindgen/meson.build +++ b/test cases/rust/12 bindgen/meson.build @@ -8,9 +8,6 @@ if not prog_bindgen.found() error('MESON_SKIP_TEST bindgen not found') endif -add_project_arguments('-DPROJECT_ARG', language : 'c') -add_global_arguments('-DGLOBAL_ARG', language : 'c') - # This seems to happen on windows when libclang.dll is not in path or is not # valid. We must try to process a header file for this to work. # @@ -84,18 +81,3 @@ test('generated header', rust_bin2) subdir('sub') subdir('dependencies') - -gp = rust.bindgen( - input : 'src/global-project.h', - output : 'global-project.rs', -) - -gp_lib = static_library('gp_lib', 'src/global.c') - -gp_exe = executable( - 'gp_exe', - structured_sources(['src/global.rs', gp]), - link_with : gp_lib, -) - -test('global and project arguments', gp_exe) diff --git a/test cases/rust/12 bindgen/src/global-project.h b/test cases/rust/12 bindgen/src/global-project.h deleted file mode 100644 index 6084e8ed6b0b..000000000000 --- a/test cases/rust/12 bindgen/src/global-project.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef GLOBAL_ARG -char * success(void); -#endif -#ifndef PROJECT_ARG -char * success(void); -#endif -#ifndef CMD_ARG -char * success(void); -#endif -int success(void); diff --git a/test cases/rust/12 bindgen/src/global.c b/test cases/rust/12 bindgen/src/global.c deleted file mode 100644 index 10f6676f7a1b..000000000000 --- a/test cases/rust/12 bindgen/src/global.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "src/global-project.h" - -int success(void) { - return 0; -} diff --git a/test cases/rust/12 bindgen/src/global.rs b/test cases/rust/12 bindgen/src/global.rs deleted file mode 100644 index 4b70b1ecc728..000000000000 --- a/test cases/rust/12 bindgen/src/global.rs +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-license-identifer: Apache-2.0 -// Copyright © 2023 Intel Corporation - -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] - -include!("global-project.rs"); - -fn main() { - unsafe { - std::process::exit(success()); - }; -} diff --git a/test cases/rust/12 bindgen/test.json b/test cases/rust/12 bindgen/test.json index b3a758562969..f94ee85f9740 100644 --- a/test cases/rust/12 bindgen/test.json +++ b/test cases/rust/12 bindgen/test.json @@ -1,10 +1,7 @@ { - "env": { - "CFLAGS": "-DCMD_ARG" - }, "stdout": [ { - "line": "test cases/rust/12 bindgen/meson.build:30: WARNING: Project targets '>= 0.63' but uses feature introduced in '1.0.0': \"rust.bindgen\" keyword argument \"include_directories\" of type array[str]." + "line": "test cases/rust/12 bindgen/meson.build:27: WARNING: Project targets '>= 0.63' but uses feature introduced in '1.0.0': \"rust.bindgen\" keyword argument \"include_directories\" of type array[str]." } ] } From 49d98cf487fa1e48e4aafaea3edb2952ed3df036 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Wed, 18 Oct 2023 10:08:16 +0530 Subject: [PATCH 98/99] test cases/15 llvm: Skip cmake when llvm == 17.0 There's a bug in the zstd find_package module: https://github.com/llvm/llvm-project/commit/e7fc7540daa9333f0be4f380fc9c619236d17f57#r130257253 --- test cases/frameworks/15 llvm/meson.build | 5 +++++ test cases/frameworks/15 llvm/test.json | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/test cases/frameworks/15 llvm/meson.build b/test cases/frameworks/15 llvm/meson.build index aac037fe6cd7..9c39e45b6a43 100644 --- a/test cases/frameworks/15 llvm/meson.build +++ b/test cases/frameworks/15 llvm/meson.build @@ -8,6 +8,11 @@ if not d.found() error('MESON_SKIP_TEST llvm not found.') endif +if method != 'config-tool' and d.version().startswith('17.0') and host_machine.system() == 'windows' + # https://github.com/llvm/llvm-project/commit/e7fc7540daa9333f0be4f380fc9c619236d17f57#r130257253 + error('MESON_SKIP_TEST broken llvm cmake files on MSYS2') +endif + modules_to_find = [ 'bitwriter', 'asmprinter', 'executionengine', 'mcjit', 'target', 'nativecodegen', 'amdgpu', 'engine' diff --git a/test cases/frameworks/15 llvm/test.json b/test cases/frameworks/15 llvm/test.json index 66ecd43552f6..f9d730514220 100644 --- a/test cases/frameworks/15 llvm/test.json +++ b/test cases/frameworks/15 llvm/test.json @@ -2,9 +2,9 @@ "matrix": { "options": { "method": [ - { "val": "config-tool", "skip_on_jobname": ["msys2-gcc"]}, - { "val": "cmake", "skip_on_jobname": ["msys2-gcc"] }, - { "val": "combination", "skip_on_jobname": ["msys2-gcc"]} + { "val": "config-tool", "skip_on_jobname": ["msys2-gcc"] }, + { "val": "cmake", "skip_on_jobname": ["msys2"] }, + { "val": "combination", "skip_on_jobname": ["msys2"] } ], "link-static": [ { "val": true, "skip_on_jobname": ["opensuse"] }, From 84e437179da05db10aa2457322c54f4ec8be61f1 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Tue, 17 Oct 2023 15:48:52 +0530 Subject: [PATCH 99/99] Bump versions to 1.2.3 for release --- man/meson.1 | 2 +- mesonbuild/coredata.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/meson.1 b/man/meson.1 index 5fcc96c45f69..f3b6de733cef 100644 --- a/man/meson.1 +++ b/man/meson.1 @@ -1,4 +1,4 @@ -.TH MESON "1" "September 2023" "meson 1.2.2" "User Commands" +.TH MESON "1" "October 2023" "meson 1.2.3" "User Commands" .SH NAME meson - a high productivity build system .SH DESCRIPTION diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 17ad7013fdc8..81c9080e9f2a 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -59,7 +59,7 @@ # # Pip requires that RCs are named like this: '0.1.0.rc1' # But the corresponding Git tag needs to be '0.1.0rc1' -version = '1.2.2' +version = '1.2.3' # The next stable version when we are in dev. This is used to allow projects to # require meson version >=1.2.0 when using 1.1.99. FeatureNew won't warn when