Hello community, here is the log from the commit of package meson for openSUSE:Factory checked in at 2019-02-13 10:16:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/meson (Old) and /work/SRC/openSUSE:Factory/.meson.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "meson" Wed Feb 13 10:16:24 2019 rev:40 rq:669785 version:0.49.1 Changes: -------- --- /work/SRC/openSUSE:Factory/meson/meson.changes 2019-01-28 20:46:20.994037451 +0100 +++ /work/SRC/openSUSE:Factory/.meson.new.28833/meson.changes 2019-02-13 10:16:28.309378508 +0100 @@ -1,0 +2,8 @@ +Mon Jan 28 14:41:28 UTC 2019 - Dominique Leuenberger <dims...@opensuse.org> + +- Update to version 0.49.1: + + dependencies/ui: Don't require lrelease for qt. + + Better Python exe detector (gh#mesonbuild/meson#4614). +- Drop meson-no-lrelease.patch: fixed upstream. + +------------------------------------------------------------------- Old: ---- meson-0.49.0.tar.gz meson-0.49.0.tar.gz.asc meson-no-lrelease.patch New: ---- meson-0.49.1.tar.gz meson-0.49.1.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ meson.spec ++++++ --- /var/tmp/diff_new_pack.18ERdY/_old 2019-02-13 10:16:29.049378226 +0100 +++ /var/tmp/diff_new_pack.18ERdY/_new 2019-02-13 10:16:29.053378224 +0100 @@ -28,7 +28,7 @@ %{!?vim_data_dir:%global vim_data_dir %{_datadir}/vim} %bcond_with setuptools Name: meson%{name_ext} -Version: 0.49.0 +Version: 0.49.1 Release: 0 Summary: Python-based build system License: Apache-2.0 @@ -49,8 +49,6 @@ Patch4: meson-fix-gcc48.patch # PATCH-FEATURE-OPENSUSE meson-distutils.patch tchva...@suse.com -- build and install using distutils instead of full setuptools Patch5: meson-distutils.patch -# PATCH-FIX-UPSTREAM meson-no-lrelease.patch dims...@opensuse.org -- Don't require lrelease for qt -Patch6: meson-no-lrelease.patch BuildRequires: fdupes BuildRequires: python-rpm-macros BuildRequires: python3-base @@ -162,7 +160,6 @@ %if !%{with setuptools} %patch5 -p1 %endif -%patch6 -p1 # Remove static boost tests from "test cases/frameworks/1 boost/". sed -i "/static/d" test\ cases/frameworks/1\ boost/meson.build ++++++ meson-0.49.0.tar.gz -> meson-0.49.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/PKG-INFO new/meson-0.49.1/PKG-INFO --- old/meson-0.49.0/PKG-INFO 2018-12-09 21:02:29.000000000 +0100 +++ new/meson-0.49.1/PKG-INFO 2019-01-23 17:49:49.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: meson -Version: 0.49.0 +Version: 0.49.1 Summary: A high performance build system Home-page: http://mesonbuild.com Author: Jussi Pakkanen diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/man/meson.1 new/meson-0.49.1/man/meson.1 --- old/meson-0.49.0/man/meson.1 2018-12-09 20:42:19.000000000 +0100 +++ new/meson-0.49.1/man/meson.1 2019-01-23 17:46:38.000000000 +0100 @@ -1,4 +1,4 @@ -.TH MESON "1" "December 2018" "meson 0.49.0" "User Commands" +.TH MESON "1" "January 2019" "meson 0.49.1" "User Commands" .SH NAME meson - a high productivity build system .SH DESCRIPTION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/meson.egg-info/PKG-INFO new/meson-0.49.1/meson.egg-info/PKG-INFO --- old/meson-0.49.0/meson.egg-info/PKG-INFO 2018-12-09 21:02:22.000000000 +0100 +++ new/meson-0.49.1/meson.egg-info/PKG-INFO 2019-01-23 17:49:43.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: meson -Version: 0.49.0 +Version: 0.49.1 Summary: A high performance build system Home-page: http://mesonbuild.com Author: Jussi Pakkanen diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/meson.egg-info/SOURCES.txt new/meson-0.49.1/meson.egg-info/SOURCES.txt --- old/meson-0.49.0/meson.egg-info/SOURCES.txt 2018-12-09 21:02:23.000000000 +0100 +++ new/meson-0.49.1/meson.egg-info/SOURCES.txt 2019-01-23 17:49:44.000000000 +0100 @@ -2075,6 +2075,7 @@ test cases/unit/5 compiler detection/trivial.cc test cases/unit/5 compiler detection/trivial.m test cases/unit/5 compiler detection/trivial.mm +test cases/unit/50 pkgconfig static link order/meson.build test cases/unit/6 std override/meson.build test cases/unit/6 std override/prog11.cpp test cases/unit/6 std override/prog98.cpp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/mesonbuild/coredata.py new/meson-0.49.1/mesonbuild/coredata.py --- old/meson-0.49.0/mesonbuild/coredata.py 2018-12-09 20:42:19.000000000 +0100 +++ new/meson-0.49.1/mesonbuild/coredata.py 2019-01-23 17:46:09.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright 2012-2018 The Meson development team +# Copyright 2012-2019 The Meson development team # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ import argparse import configparser -version = '0.49.0' +version = '0.49.1' backendlist = ['ninja', 'vs', 'vs2010', 'vs2015', 'vs2017', 'xcode'] default_yielding = False @@ -560,6 +560,10 @@ properties = config['properties'] if options.cross_file is None: options.cross_file = properties.get('cross_file', None) + if not options.native_file: + # This will be a string in the form: "['first', 'second', ...]", use + # literal_eval to get it into the list of strings. + options.native_file = ast.literal_eval(properties.get('native_file', '[]')) def write_cmd_line_file(build_dir, options): filename = get_cmd_line_file(build_dir) @@ -568,6 +572,8 @@ properties = {} if options.cross_file is not None: properties['cross_file'] = options.cross_file + if options.native_file: + properties['native_file'] = options.native_file config['options'] = options.cmd_line_options config['properties'] = properties @@ -582,17 +588,25 @@ with open(filename, 'w') as f: config.write(f) +def major_versions_differ(v1, v2): + return v1.split('.')[0:2] != v2.split('.')[0:2] + def load(build_dir): filename = os.path.join(build_dir, 'meson-private', 'coredata.dat') load_fail_msg = 'Coredata file {!r} is corrupted. Try with a fresh build tree.'.format(filename) try: with open(filename, 'rb') as f: obj = pickle.load(f) - except pickle.UnpicklingError: + except (pickle.UnpicklingError, EOFError): raise MesonException(load_fail_msg) + except AttributeError: + raise MesonException( + "Coredata file {!r} references functions or classes that don't " + "exist. This probably means that it was generated with an old " + "version of meson.".format(filename)) if not isinstance(obj, CoreData): raise MesonException(load_fail_msg) - if obj.version != version: + if major_versions_differ(obj.version, version): raise MesonException('Build directory has been generated with Meson version %s, ' 'which is incompatible with current version %s.\n' % (obj.version, version)) @@ -602,7 +616,7 @@ filename = os.path.join(build_dir, 'meson-private', 'coredata.dat') prev_filename = filename + '.prev' tempfilename = filename + '~' - if obj.version != version: + if major_versions_differ(obj.version, version): raise MesonException('Fatal version mismatch corruption.') if os.path.exists(filename): import shutil diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/mesonbuild/dependencies/ui.py new/meson-0.49.1/mesonbuild/dependencies/ui.py --- old/meson-0.49.0/mesonbuild/dependencies/ui.py 2018-12-09 15:27:23.000000000 +0100 +++ new/meson-0.49.1/mesonbuild/dependencies/ui.py 2019-01-23 17:46:09.000000000 +0100 @@ -14,7 +14,6 @@ # This file contains the detection logic for external dependencies that # are UI-related. - import functools import os import re @@ -243,7 +242,7 @@ if self.bindir: yield os.path.join(self.bindir, b), b, False yield '{}-{}'.format(b, self.name), b, False - yield b, b, self.required + yield b, b, self.required if b != 'lrelease' else False for b, name, required in gen_bins(): if found[name].found(): @@ -288,7 +287,15 @@ self.compile_args += m.get_compile_args() if self.private_headers: qt_inc_dir = m.get_pkgconfig_variable('includedir', dict()) - mod_private_inc = _qt_get_private_includes(os.path.join(qt_inc_dir, 'Qt' + m_name), m_name, m.version) + mod_private_dir = os.path.join(qt_inc_dir, 'Qt' + m_name) + if not os.path.isdir(mod_private_dir): + # At least some versions of homebrew don't seem to set this + # up correctly. /usr/local/opt/qt/include/Qt + m_name is a + # symlink to /usr/local/opt/qt/include, but the pkg-config + # file points to /usr/local/Cellar/qt/x.y.z/Headers/, and + # the Qt + m_name there is not a symlink, it's a file + mod_private_dir = qt_inc_dir + mod_private_inc = _qt_get_private_includes(mod_private_dir, m_name, m.version) for dir in mod_private_inc: self.compile_args.append('-I' + dir) self.link_args += m.get_link_args() @@ -334,10 +341,9 @@ return ExternalProgram.from_bin_list(self.env.cross_info.config['binaries'], 'qmake') elif self.env.config_info: # Prefer suffixed to unsuffixed version - p = ExternalProgram.from_bin_list(self.env.config_info.binaries, 'qmake-' + self.name) + p = ExternalProgram.from_bin_list(self.env.config_info.binaries, 'qmake') if p.found(): return p - return ExternalProgram.from_bin_list(self.env.config_info.binaries, 'qmake') return ExternalProgram(qmake, silent=True) def _qmake_detect(self, mods, kwargs): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/mesonbuild/environment.py new/meson-0.49.1/mesonbuild/environment.py --- old/meson-0.49.0/mesonbuild/environment.py 2018-12-09 17:37:53.000000000 +0100 +++ new/meson-0.49.1/mesonbuild/environment.py 2019-01-23 17:46:09.000000000 +0100 @@ -237,6 +237,8 @@ trial = 'arm' elif trial.startswith('ppc64'): trial = 'ppc64' + elif trial == 'macppc': + trial = 'ppc' elif trial == 'powerpc': trial = 'ppc' # FreeBSD calls both ppc and ppc64 "powerpc". diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/mesonbuild/interpreter.py new/meson-0.49.1/mesonbuild/interpreter.py --- old/meson-0.49.0/mesonbuild/interpreter.py 2018-12-09 15:27:23.000000000 +0100 +++ new/meson-0.49.1/mesonbuild/interpreter.py 2019-01-23 17:46:09.000000000 +0100 @@ -2359,11 +2359,11 @@ if pv == 'undefined' or not mesonlib.version_compare_many(pv, wanted)[0]: raise InterpreterException('Subproject %s version is %s but %s required.' % (dirname, pv, wanted)) self.active_projectname = current_active - self.build.subprojects[dirname] = subi.project_version self.subprojects.update(subi.subprojects) self.subprojects[dirname] = SubprojectHolder(subi, self.subproject_dir, dirname) self.build_def_files += subi.build_def_files self.build.merge(subi.build) + self.build.subprojects[dirname] = subi.project_version return self.subprojects[dirname] def get_option_internal(self, optname): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/mesonbuild/mesonlib.py new/meson-0.49.1/mesonbuild/mesonlib.py --- old/meson-0.49.0/mesonbuild/mesonlib.py 2018-12-09 15:27:16.000000000 +0100 +++ new/meson-0.49.1/mesonbuild/mesonlib.py 2018-12-27 21:58:21.000000000 +0100 @@ -1116,6 +1116,22 @@ shutil.rmtree(f) +def windows_proof_rm(fpath): + """Like windows_proof_rmtree, but for a single file.""" + if os.path.isfile(fpath): + os.chmod(fpath, os.stat(fpath).st_mode | stat.S_IWRITE | stat.S_IREAD) + delays = [0.1, 0.1, 0.2, 0.2, 0.2, 0.5, 0.5, 1, 1, 1, 1, 2] + for d in delays: + try: + os.unlink(fpath) + return + except FileNotFoundError: + return + except (OSError, PermissionError): + time.sleep(d) + os.unlink(fpath) + + def detect_subprojects(spdir_name, current_dir='', result=None): if result is None: result = {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/mesonbuild/mesonmain.py new/meson-0.49.1/mesonbuild/mesonmain.py --- old/meson-0.49.0/mesonbuild/mesonmain.py 2018-12-09 15:27:23.000000000 +0100 +++ new/meson-0.49.1/mesonbuild/mesonmain.py 2019-01-23 17:46:09.000000000 +0100 @@ -17,6 +17,7 @@ import importlib import traceback import argparse +import codecs from . import mesonlib from . import mlog @@ -148,6 +149,17 @@ mlog.exception(e) return 1 +def ensure_stdout_accepts_unicode(): + if sys.stdout.encoding and not sys.stdout.encoding.upper().startswith('UTF-'): + if sys.version_info >= (3, 7): + sys.stdout.reconfigure(errors='surrogateescape') + else: + sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach(), + errors='surrogateescape') + sys.stdout.encoding = 'UTF-8' + if not hasattr(sys.stdout, 'buffer'): + sys.stdout.buffer = sys.stdout.raw if hasattr(sys.stdout, 'raw') else sys.stdout + def run(original_args, mainfile): if sys.version_info < (3, 5): print('Meson works correctly only with python 3.5+.') @@ -155,6 +167,11 @@ print('Please update your environment') return 1 + # Meson gets confused if stdout can't output Unicode, if the + # locale isn't Unicode, just force stdout to accept it. This tries + # to emulate enough of PEP 540 to work elsewhere. + ensure_stdout_accepts_unicode() + # https://github.com/mesonbuild/meson/issues/3653 if sys.platform.lower() == 'msys': mlog.error('This python3 seems to be msys/python on MSYS2 Windows, which is known to have path semantics incompatible with Meson') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/mesonbuild/modules/pkgconfig.py new/meson-0.49.1/mesonbuild/modules/pkgconfig.py --- old/meson-0.49.0/mesonbuild/modules/pkgconfig.py 2018-12-09 15:27:23.000000000 +0100 +++ new/meson-0.49.1/mesonbuild/modules/pkgconfig.py 2019-01-06 22:41:19.000000000 +0100 @@ -35,13 +35,13 @@ def add_pub_libs(self, libs): libs, reqs, cflags = self._process_libs(libs, True) - self.pub_libs += libs + self.pub_libs = libs + self.pub_libs # prepend to preserve dependencies self.pub_reqs += reqs self.cflags += cflags def add_priv_libs(self, libs): libs, reqs, _ = self._process_libs(libs, False) - self.priv_libs += libs + self.priv_libs = libs + self.priv_libs self.priv_reqs += reqs def add_pub_reqs(self, reqs): @@ -192,7 +192,11 @@ for x in xs: # Don't de-dup unknown strings to avoid messing up arguments like: # ['-framework', 'CoreAudio', '-framework', 'CoreMedia'] - if x not in result or (libs and (isinstance(x, str) and not x.endswith(('-l', '-L')))): + known_flags = ['-pthread'] + cannot_dedup = libs and isinstance(x, str) and \ + not x.startswith(('-l', '-L')) and \ + x not in known_flags + if x not in result or cannot_dedup: result.append(x) return result self.pub_libs = _fn(self.pub_libs, True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/mesonbuild/msetup.py new/meson-0.49.1/mesonbuild/msetup.py --- old/meson-0.49.0/mesonbuild/msetup.py 2018-12-09 15:27:23.000000000 +0100 +++ new/meson-0.49.1/mesonbuild/msetup.py 2019-01-23 17:46:09.000000000 +0100 @@ -62,13 +62,26 @@ # restore that file if anything bad happens. For example if # configuration fails we need to be able to wipe again. filename = coredata.get_cmd_line_file(self.build_dir) - with open(filename, 'r') as f: - content = f.read() + try: + with open(filename, 'r') as f: + content = f.read() + except FileNotFoundError: + raise MesonException( + 'Cannot find cmd_line.txt. This is probably because this ' + 'build directory was configured with a meson version < 0.49.0.') coredata.read_cmd_line_file(self.build_dir, options) try: - mesonlib.windows_proof_rmtree(self.build_dir) + # Don't delete the whole tree, just all of the files and + # folders in the tree. Otherwise calling wipe form the builddir + # will cause a crash + for l in os.listdir(self.build_dir): + l = os.path.join(self.build_dir, l) + if os.path.isdir(l): + mesonlib.windows_proof_rmtree(l) + else: + mesonlib.windows_proof_rm(l) finally: # Restore the file path = os.path.dirname(filename) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/mesonbuild/mtest.py new/meson-0.49.1/mesonbuild/mtest.py --- old/meson-0.49.0/mesonbuild/mtest.py 2018-12-09 15:27:23.000000000 +0100 +++ new/meson-0.49.1/mesonbuild/mtest.py 2019-01-23 17:45:59.000000000 +0100 @@ -647,8 +647,8 @@ self.logfilename = logfile_base + '.txt' self.jsonlogfilename = logfile_base + '.json' - self.jsonlogfile = open(self.jsonlogfilename, 'w', encoding='utf-8') - self.logfile = open(self.logfilename, 'w', encoding='utf-8') + self.jsonlogfile = open(self.jsonlogfilename, 'w', encoding='utf-8', errors='replace') + self.logfile = open(self.logfilename, 'w', encoding='utf-8', errors='surrogateescape') self.logfile.write('Log of Meson test suite run on %s\n\n' % datetime.datetime.now().isoformat()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/mesonbuild/scripts/commandrunner.py new/meson-0.49.1/mesonbuild/scripts/commandrunner.py --- old/meson-0.49.0/mesonbuild/scripts/commandrunner.py 2018-08-25 10:05:43.000000000 +0200 +++ new/meson-0.49.1/mesonbuild/scripts/commandrunner.py 2018-12-19 00:26:26.000000000 +0100 @@ -16,6 +16,7 @@ what to run, sets up the environment and executes the command.""" import sys, os, subprocess, shutil, shlex +import re def run_command(source_dir, build_dir, subdir, meson_command, command, arguments): env = {'MESON_SOURCE_ROOT': source_dir, @@ -49,6 +50,9 @@ print('Could not execute command "{}": {}'.format(command, err)) sys.exit(1) +def is_python_command(cmdname): + end_py_regex = r'python(3|3\.\d+)?(\.exe)?$' + return re.search(end_py_regex, cmdname) is not None def run(args): if len(args) < 4: @@ -58,7 +62,7 @@ build_dir = args[1] subdir = args[2] meson_command = args[3] - if 'python' in meson_command: # Hack. + if is_python_command(meson_command): meson_command = [meson_command, args[4]] command = args[5] arguments = args[6:] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/meson-0.49.0/run_unittests.py new/meson-0.49.1/run_unittests.py --- old/meson-0.49.0/run_unittests.py 2018-12-09 18:55:42.000000000 +0100 +++ new/meson-0.49.1/run_unittests.py 2019-01-23 17:46:09.000000000 +0100 @@ -2922,19 +2922,26 @@ self.wipe() self.init(testdir, extra_args=['-Dstart_native=true']) - def test_reconfigure(self): - testdir = os.path.join(self.unit_test_dir, '46 reconfigure') - self.init(testdir, extra_args=['-Dopt1=val1']) - self.setconf('-Dopt2=val2') - + def __reconfigure(self, change_minor=False): # Set an older version to force a reconfigure from scratch filename = os.path.join(self.privatedir, 'coredata.dat') with open(filename, 'rb') as f: obj = pickle.load(f) - obj.version = '0.47.0' + if change_minor: + v = mesonbuild.coredata.version.split('.') + obj.version = '.'.join(v[0:2] + [str(int(v[2]) + 1)]) + else: + obj.version = '0.47.0' with open(filename, 'wb') as f: pickle.dump(obj, f) + def test_reconfigure(self): + testdir = os.path.join(self.unit_test_dir, '46 reconfigure') + self.init(testdir, extra_args=['-Dopt1=val1']) + self.setconf('-Dopt2=val2') + + self.__reconfigure() + out = self.init(testdir, extra_args=['--reconfigure', '-Dopt3=val3']) self.assertRegex(out, 'WARNING:.*Regenerating configuration from scratch') self.assertRegex(out, 'opt1 val1') @@ -2957,6 +2964,30 @@ self.build() self.run_tests() + def test_wipe_from_builddir(self): + testdir = os.path.join(self.common_test_dir, '162 custom target subdir depend files') + self.init(testdir) + self.__reconfigure() + + with Path(self.builddir): + self.init(testdir, extra_args=['--wipe']) + + def test_minor_version_does_not_reconfigure_wipe(self): + testdir = os.path.join(self.unit_test_dir, '46 reconfigure') + self.init(testdir, extra_args=['-Dopt1=val1']) + self.setconf('-Dopt2=val2') + + self.__reconfigure(change_minor=True) + + out = self.init(testdir, extra_args=['--reconfigure', '-Dopt3=val3']) + self.assertNotRegex(out, 'WARNING:.*Regenerating configuration from scratch') + self.assertRegex(out, 'opt1 val1') + self.assertRegex(out, 'opt2 val2') + self.assertRegex(out, 'opt3 val3') + self.assertRegex(out, 'opt4 default4') + self.build() + self.run_tests() + def test_target_construct_id_from_path(self): # This id is stable but not guessable. # The test is supposed to prevent unintentional @@ -2995,6 +3026,23 @@ self.assertEqual(res['subprojects'][0]['version'], 'undefined') self.assertEqual(res['subprojects'][0]['descriptive_name'], 'subproject') + def test_introspect_projectinfo_subprojects(self): + testdir = os.path.join(self.common_test_dir, '103 subproject subdir') + self.init(testdir) + res = self.introspect('--projectinfo') + expected = { + 'descriptive_name': 'proj', + 'version': 'undefined', + 'subprojects': [ + { + 'descriptive_name': 'sub', + 'name': 'sub', + 'version': 'undefined' + } + ] + } + self.assertDictEqual(res, expected) + class FailureTests(BasePlatformTests): ''' @@ -3542,26 +3590,30 @@ privatedir2 = self.privatedir os.environ['PKG_CONFIG_LIBDIR'] = os.pathsep.join([privatedir1, privatedir2]) - cmd = ['pkg-config', 'dependency-test'] - - out = self._run(cmd + ['--print-requires']).strip().split('\n') - self.assertEqual(sorted(out), sorted(['libexposed'])) - - out = self._run(cmd + ['--print-requires-private']).strip().split('\n') - self.assertEqual(sorted(out), sorted(['libfoo >= 1.0'])) - - out = self._run(cmd + ['--cflags-only-other']).strip().split() - self.check_pkg_flags_are_same(out, ['-pthread', '-DCUSTOM']) + self._run(['pkg-config', 'dependency-test', '--validate']) - out = self._run(cmd + ['--libs-only-l', '--libs-only-other']).strip().split() - self.check_pkg_flags_are_same(out, ['-pthread', '-lcustom', - '-llibmain', '-llibexposed']) - - out = self._run(cmd + ['--libs-only-l', '--libs-only-other', '--static']).strip().split() - self.check_pkg_flags_are_same(out, ['-pthread', '-lcustom', - '-llibmain', '-llibexposed', - '-llibinternal', '-lcustom2', - '-lfoo']) + # pkg-config strips some duplicated flags so we have to parse the + # generated file ourself. + expected = { + 'Requires': 'libexposed', + 'Requires.private': 'libfoo >= 1.0', + 'Libs': '-L${libdir} -llibmain -pthread -lcustom', + 'Libs.private': '-lcustom2 -L${libdir} -llibinternal', + 'Cflags': '-I${includedir} -pthread -DCUSTOM', + } + if is_osx() or is_haiku(): + expected['Cflags'] = expected['Cflags'].replace('-pthread ', '') + with open(os.path.join(privatedir2, 'dependency-test.pc')) as f: + matched_lines = 0 + for line in f: + parts = line.split(':', 1) + if parts[0] in expected: + key = parts[0] + val = parts[1].strip() + expected_val = expected[key] + self.assertEqual(expected_val, val) + matched_lines += 1 + self.assertEqual(len(expected), matched_lines) cmd = ['pkg-config', 'requires-test'] out = self._run(cmd + ['--print-requires']).strip().split('\n') @@ -3571,11 +3623,6 @@ out = self._run(cmd + ['--print-requires-private']).strip().split('\n') self.assertEqual(sorted(out), sorted(['libexposed', 'libfoo >= 1.0', 'libhello'])) - def check_pkg_flags_are_same(self, output, expected): - if is_osx() or is_haiku(): - expected = [x for x in expected if x != '-pthread'] - self.assertEqual(sorted(output), sorted(expected)) - def test_pkg_unfound(self): testdir = os.path.join(self.unit_test_dir, '23 unfound pkgconfig') self.init(testdir) @@ -4274,6 +4321,19 @@ self.assertEqual("-r/usr/lib/libsomething.dll", str(stdo.decode('ascii')).strip()) + @skipIfNoPkgconfig + def test_pkgconfig_link_order(self): + ''' + Test that libraries are listed before their dependencies. + ''' + testdir = os.path.join(self.unit_test_dir, '50 pkgconfig static link order') + self.init(testdir) + myenv = os.environ.copy() + myenv['PKG_CONFIG_PATH'] = self.privatedir + stdo = subprocess.check_output(['pkg-config', '--libs', 'libsomething'], env=myenv) + deps = stdo.split() + self.assertTrue(deps.index(b'-lsomething') < deps.index(b'-ldependency')) + def test_deterministic_dep_order(self): ''' Test that the dependencies are always listed in a deterministic order. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' "old/meson-0.49.0/test cases/common/48 pkgconfig-gen/dependencies/meson.build" "new/meson-0.49.1/test cases/common/48 pkgconfig-gen/dependencies/meson.build" --- "old/meson-0.49.0/test cases/common/48 pkgconfig-gen/dependencies/meson.build" 2018-12-09 15:27:23.000000000 +0100 +++ "new/meson-0.49.1/test cases/common/48 pkgconfig-gen/dependencies/meson.build" 2019-01-06 22:41:19.000000000 +0100 @@ -28,8 +28,8 @@ # - Having pc_dep in libraries_private should add it in Requires.private # - pc_dep_dup is the same library and same version, should be ignored # - notfound_dep is not required so it shouldn't appear in the pc file. -pkgg.generate(libraries : [main_lib, exposed_lib, threads_dep , custom_dep], - libraries_private : [custom_dep, custom2_dep, pc_dep, pc_dep_dup, notfound_dep], +pkgg.generate(libraries : [main_lib, exposed_lib, threads_dep, threads_dep, custom_dep, custom_dep, '-pthread'], + libraries_private : [custom_dep, custom2_dep, custom2_dep, pc_dep, pc_dep_dup, notfound_dep], version : '1.0', name : 'dependency-test', filebase : 'dependency-test', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' "old/meson-0.49.0/test cases/unit/50 pkgconfig static link order/meson.build" "new/meson-0.49.1/test cases/unit/50 pkgconfig static link order/meson.build" --- "old/meson-0.49.0/test cases/unit/50 pkgconfig static link order/meson.build" 1970-01-01 01:00:00.000000000 +0100 +++ "new/meson-0.49.1/test cases/unit/50 pkgconfig static link order/meson.build" 2018-12-19 00:26:26.000000000 +0100 @@ -0,0 +1,11 @@ +project('link order test', 'c') + +dep = library('dependency', []) +lib = static_library('something', [], link_with: dep) + +import('pkgconfig').generate( + name: 'libsomething', + description: 'test library', + libraries: lib, + version: '1' +)