diff --git a/test/CPPDEFINES/pkg-config.py b/test/CPPDEFINES/pkg-config.py index cd8c9dc7b5..efd4e9c403 100644 --- a/test/CPPDEFINES/pkg-config.py +++ b/test/CPPDEFINES/pkg-config.py @@ -25,8 +25,27 @@ """ Verify merging with MergeFlags to CPPPDEFINES with various data types. + +Uses system pkg-config with a stub pc file to generate the data. +Not entirely sure the motivation for this - it would be more "isolated" +to just paste in the data and not depend on pkg-config, but presumably +this test exists because of observed bugs, so leaving alone for now. + +Ran into an interesting problem when we spun up a GitHub Windows Action: +it finds pre-installed Strawberry Perl's pkg-config over the mingw one, +which is also pre-installed. The Strawberry one is written in pure +Perl (after getting past the initial batch file), so requires perl.exe, +which won't be in the SCons env['ENV']['PATH']. We try to detect it, +by somewhat hokey means: if pkg-config's path had "strawberry' in it, +assume we need to add the directory path to our execution env. + +It ended up being more portable to use pkg-config's --with-path than +to set PKG_CONFIG_PATH, because the Windows cmd.exe can't accept +the standard calling style. """ +import pathlib + import TestSCons import TestCmd @@ -34,9 +53,17 @@ pkg_config_path = test.where_is('pkg-config') if not pkg_config_path: - test.skip_test("Could not find 'pkg-config' in system PATH, skipping test.\n") + test.skip_test("Could not find 'pkg-config' in PATH, skipping test.\n") pkg_config_path = pkg_config_path.replace("\\", "/") +# Try to guess if this was Strawberry Perl's pkg-config +if 'strawberry' in pkg_config_path.lower(): + # as_posix() or the pasted paths in SConstruct will have escape problems + # (or need to be raw strings) + strawberry_perl_path = pathlib.PurePath(pkg_config_path).parent.as_posix() +else: + strawberry_perl_path = "" + test.write('bug.pc', """\ prefix=/usr exec_prefix=${prefix} @@ -57,72 +84,74 @@ """) if TestCmd.IS_WINDOWS: - pkg_config_file = 'bug.pc' + pkg_config_file = 'bug' pkg_config_tools = 'mingw' - pkg_config_cl_path = "" else: - pkg_config_file = 'bug' + pkg_config_file = 'bug.pc' pkg_config_tools = 'default' - pkg_config_cl_path = "PKG_CONFIG_PATH=." +pkg_config_cl_path = '--with-path=.' -test.write('SConstruct', """\ +test.write('SConstruct', f"""\ import os import sys -# Python3 dicts dont preserve order. Hence we supply subclass of OrderedDict -# whose __str__ and __repr__ act like a normal dict. -from collections import OrderedDict - -class OrderedPrintingDict(OrderedDict): - def __repr__(self): - return '{' + ', '.join(['%r: %r' % (k, v) for (k, v) in self.items()]) + '}' - - __str__ = __repr__ - - # Because dict-like objects (except dict and UserDict) are not deep copied - # directly when constructing Environment(CPPDEFINES = OrderedPrintingDict(...)) - def __semi_deepcopy__(self): - return self.copy() -""" + """ +DefaultEnvironment(tools=[]) # https://github.com/SCons/scons/issues/2671 # Passing test cases -env_1 = Environment(CPPDEFINES=[('DEBUG', '1'), 'TEST'], tools=['%(pkg_config_tools)s']) +env_1 = Environment( + CPPDEFINES=[('DEBUG', '1'), 'TEST'], + tools=['{pkg_config_tools}'] +) +if '{strawberry_perl_path}': + env_1.AppendENVPath('PATH', '{strawberry_perl_path}') if sys.platform == 'win32': os.environ['PKG_CONFIG_PATH'] = env_1.Dir('.').abspath.replace("\\\\", "/") -env_1.ParseConfig( - '%(pkg_config_cl_path)s "%(pkg_config_path)s" --cflags %(pkg_config_file)s' -) +env_1.ParseConfig('"{pkg_config_path}" {pkg_config_cl_path} --cflags {pkg_config_file}') print(env_1.subst('$_CPPDEFFLAGS')) -env_2 = Environment(CPPDEFINES=[('DEBUG', '1'), 'TEST'], tools=['%(pkg_config_tools)s']) +env_2 = Environment( + CPPDEFINES=[('DEBUG', '1'), 'TEST'], + tools=['{pkg_config_tools}'] +) +if '{strawberry_perl_path}': + env_2.AppendENVPath('PATH', '{strawberry_perl_path}') env_2.MergeFlags('-DSOMETHING -DVARIABLE=2') print(env_2.subst('$_CPPDEFFLAGS')) # Failing test cases env_3 = Environment( - CPPDEFINES=OrderedPrintingDict([('DEBUG', 1), ('TEST', None)]), - tools=['%(pkg_config_tools)s'], -) -env_3.ParseConfig( - '%(pkg_config_cl_path)s "%(pkg_config_path)s" --cflags %(pkg_config_file)s' + CPPDEFINES=dict([('DEBUG', 1), ('TEST', None)]), + tools=['{pkg_config_tools}'], ) +if '{strawberry_perl_path}': + env_3.AppendENVPath('PATH', '{strawberry_perl_path}') +env_3.ParseConfig('"{pkg_config_path}" {pkg_config_cl_path} --cflags {pkg_config_file}') print(env_3.subst('$_CPPDEFFLAGS')) env_4 = Environment( - CPPDEFINES=OrderedPrintingDict([('DEBUG', 1), ('TEST', None)]), - tools=['%(pkg_config_tools)s'], + CPPDEFINES=dict([('DEBUG', 1), ('TEST', None)]), + tools=['{pkg_config_tools}'], ) +if '{strawberry_perl_path}': + env_4.AppendENVPath('PATH', '{strawberry_perl_path}') env_4.MergeFlags('-DSOMETHING -DVARIABLE=2') print(env_4.subst('$_CPPDEFFLAGS')) # https://github.com/SCons/scons/issues/1738 -env_1738_1 = Environment(tools=['%(pkg_config_tools)s']) +# TODO: the Perl pkg-config doesn't work right with both --cflags --libs +# e.g.: pkg-config --with-path=. --libs --cflags bug +# Exepct: -DSOMETHING -DVARIABLE=2 +# Strawberry: (blank) +# We don't have any libs in the stub pc file, so just drop that for now. +env_1738_1 = Environment(tools=['{pkg_config_tools}']) +if '{strawberry_perl_path}': + env_1738_1.AppendENVPath('PATH', '{strawberry_perl_path}') env_1738_1.ParseConfig( - '%(pkg_config_cl_path)s "%(pkg_config_path)s" --cflags --libs %(pkg_config_file)s' + '"{pkg_config_path}" {pkg_config_cl_path} --cflags {pkg_config_file}' ) -env_1738_1.Append(CPPDEFINES={'value': '1'}) +env_1738_1.Append(CPPDEFINES={{'value': '1'}}) print(env_1738_1.subst('$_CPPDEFFLAGS')) -"""%locals() ) +""") expect_print_output="""\ -DDEBUG=1 -DTEST -DSOMETHING -DVARIABLE=2 diff --git a/testing/ci/windows_ci_skip.txt b/testing/ci/windows_ci_skip.txt index 1bd073f5ff..f3e925c203 100644 --- a/testing/ci/windows_ci_skip.txt +++ b/testing/ci/windows_ci_skip.txt @@ -1,5 +1,4 @@ # temporarily skip this in GitHub Windows runner -test/CPPDEFINES/pkg-config.py test/packaging/msi/explicit-target.py test/packaging/msi/file-placement.py test/packaging/msi/package.py