unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
@ 2019-07-07 10:48 Christopher Baines
  2019-07-08  7:46 ` bug#36535: " Christopher Baines
  0 siblings, 1 reply; 12+ messages in thread
From: Christopher Baines @ 2019-07-07 10:48 UTC (permalink / raw)
  To: 36535

Incorporate some changes from nixpkgs to the gobject-introspection package
patches.  This is motivated by looking at issues with libsoup and lollypop.
This changes means that the share/gir-1.0/Soup-2.4.gir file within libsoup
references libsoup-2.4.so.1 with an absolute filename, whereas previously, the
filename wasn't absolute.

* gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch:
Incorporate changes from nixpkgs.
---
 ...ct-introspection-absolute-shlib-path.patch | 141 +++++++++++++++++-
 1 file changed, 137 insertions(+), 4 deletions(-)

diff --git a/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch b/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
index d00cc5a420..3c0bb1c6cf 100644
--- a/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
+++ b/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
@@ -2,10 +2,131 @@
 # add the full path.
 #
 # This patch was provided by Luca Bruno <lucabru@src.gnome.org>  for 
-# 'gobject-introspection' 1.40.0 in Nix. 
---- ./giscanner/utils.py.orig	2014-08-14 22:05:05.055334080 +0200
-+++ ./giscanner/utils.py	2014-08-14 22:05:24.687497334 +0200
-@@ -110,17 +110,11 @@
+# 'gobject-introspection' 1.40.0 in Nix.
+#
+# It has since been updated to work with newer versions of
+# gobject-introspection.
+--- a/giscanner/scannermain.py
++++ b/giscanner/scannermain.py
+@@ -95,6 +95,39 @@ def get_windows_option_group(parser):
+     return group
+ 
+ 
++def _get_default_fallback_libpath():
++    # Newer multiple-output-optimized stdenv has an environment variable
++    # $outputLib which in turn specifies another variable which then is used as
++    # the destination for the library contents (${!outputLib}/lib).
++    store_path = os.environ.get(os.environ.get("outputLib")) if "outputLib" in os.environ else None
++    if store_path is None:
++        outputs = os.environ.get("outputs", "out").split()
++        if "lib" in outputs:
++            # For multiple output derivations let's try whether there is a $lib
++            # environment variable and use that as the base store path.
++            store_path = os.environ.get("lib")
++        elif "out" in outputs:
++            # Otherwise we have a single output derivation, so the libraries
++            # most certainly will end up in "$out/lib".
++            store_path = os.environ.get("out")
++
++    if store_path is not None:
++        # Even if we have a $lib as output, there still should be a $lib/lib
++        # directory.
++        return os.path.join(store_path, 'lib')
++    else:
++        # If we haven't found a possible scenario, let's return an empty string
++        # so that the shared library won't be prepended with a path.
++        #
++        # Note that this doesn't mean that all hope is lost, because after all
++        # we can still use --fallback-library-path to set one.
++        #
++        # Also, we're not returning None, because that would make it very
++        # difficult to disable adding fallback paths altogether using something
++        # like: --fallback-library-path=""
++        return ""
++
++
+ def _get_option_parser():
+     parser = optparse.OptionParser('%prog [options] sources',
+                                    version='%prog ' + giscanner.__version__)
+@@ -205,6 +238,10 @@ match the namespace prefix.""")
+     parser.add_option("", "--filelist",
+                       action="store", dest="filelist", default=[],
+                       help="file containing headers and sources to be scanned")
++    parser.add_option("", "--fallback-library-path",
++                      action="store", dest="fallback_libpath",
++                      default=_get_default_fallback_libpath(),
++                      help="Path to prepend to unknown shared libraries")
+ 
+     group = get_preprocessor_option_group(parser)
+     parser.add_option_group(group)
+--- a/giscanner/shlibs.py
++++ b/giscanner/shlibs.py
+@@ -57,6 +57,12 @@ def _ldd_library_pattern(library_name):
+     $""" % re.escape(library_name), re.VERBOSE)
+ 
+ 
++def _ldd_library_guix_pattern(library_name):
++    store_dir = re.escape('/gnu/store')
++    pattern = r'(%s(?:/[^/]*)+lib%s[^A-Za-z0-9_-][^\s\(\)]*)'
++    return re.compile(pattern % (store_dir, re.escape(library_name)))
++
++
+ # This is a what we do for non-la files. We assume that we are on an
+ # ELF-like system where ldd exists and the soname extracted with ldd is
+ # a filename that can be opened with dlopen().
+@@ -106,7 +112,8 @@ def _resolve_non_libtool(options, binary, libraries):
+             output = output.decode("utf-8", "replace")
+ 
+         shlibs = resolve_from_ldd_output(libraries, output)
+-        return list(map(sanitize_shlib_path, shlibs))
++        fallback_libpath = options.fallback_libpath or "";
++        return list(map(lambda p: os.path.join(fallback_libpath, p), map(sanitize_shlib_path, shlibs)))
+ 
+ 
+ def sanitize_shlib_path(lib):
+@@ -115,19 +122,18 @@ def sanitize_shlib_path(lib):
+     # In case we get relative paths on macOS (like @rpath) then we fall
+     # back to the basename as well:
+     # https://gitlab.gnome.org/GNOME/gobject-introspection/issues/222
+-    if sys.platform == "darwin":
+-        if not os.path.isabs(lib):
+-            return os.path.basename(lib)
+-        return lib
+-    else:
++
++    # Always use absolute paths if available
++    if not os.path.isabs(lib):
+         return os.path.basename(lib)
++    return lib
+ 
+ 
+ def resolve_from_ldd_output(libraries, output):
+     patterns = {}
+     for library in libraries:
+         if not os.path.isfile(library):
+-            patterns[library] = _ldd_library_pattern(library)
++            patterns[library] = (_ldd_library_pattern(library), _ldd_library_guix_pattern(library))
+     if len(patterns) == 0:
+         return []
+ 
+@@ -139,8 +145,11 @@ def resolve_from_ldd_output(libraries, output):
+         if line.endswith(':'):
+             continue
+         for word in line.split():
+-            for library, pattern in patterns.items():
+-                m = pattern.match(word)
++            for library, (pattern, guix_pattern) in patterns.items():
++                if line.find('/gnu/store') != -1:
++                    m = guix_pattern.match(word)
++                else:
++                    m = pattern.match(word)
+                 if m:
+                     del patterns[library]
+                     shlibs.append(m.group())
+
+--- a/giscanner/utils.py
++++ b/giscanner/utils.py
+@@ -111,17 +111,11 @@ def extract_libtool_shlib(la_file):
      if dlname is None:
          return None
  
@@ -28,3 +149,15 @@
  
  
  def extract_libtool(la_file):
+--- a/tests/scanner/test_shlibs.py
++++ b/tests/scanner/test_shlibs.py
+@@ -40,6 +64,7 @@ class TestLddParser(unittest.TestCase):
+ 
+         self.assertEqual(
+             sanitize_shlib_path('/foo/bar'),
+-            '/foo/bar' if sys.platform == 'darwin' else 'bar')
++            # Always use an absolute filename for Guix
++            '/foo/bar')
+ 
+     def test_unresolved_library(self):
+output = ''
-- 
2.22.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* bug#36535: [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
  2019-07-07 10:48 [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch Christopher Baines
@ 2019-07-08  7:46 ` Christopher Baines
  2019-07-08 14:21   ` [bug#36535] " Marius Bakke
  0 siblings, 1 reply; 12+ messages in thread
From: Christopher Baines @ 2019-07-08  7:46 UTC (permalink / raw)
  To: 36535-done

[-- Attachment #1: Type: text/plain, Size: 771 bytes --]


Christopher Baines <mail@cbaines.net> writes:

> Incorporate some changes from nixpkgs to the gobject-introspection package
> patches.  This is motivated by looking at issues with libsoup and lollypop.
> This changes means that the share/gir-1.0/Soup-2.4.gir file within libsoup
> references libsoup-2.4.so.1 with an absolute filename, whereas previously, the
> filename wasn't absolute.
>
> * gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch:
> Incorporate changes from nixpkgs.
> ---
>  ...ct-introspection-absolute-shlib-path.patch | 141 +++++++++++++++++-
>  1 file changed, 137 insertions(+), 4 deletions(-)
>

I've pushed this as [1] to core-updates now, as I wanted to get it in
before the freeze.

1: 8747477deb765571c300d3eb9a4012a3c36cf7f7

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 962 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
  2019-07-08  7:46 ` bug#36535: " Christopher Baines
@ 2019-07-08 14:21   ` Marius Bakke
  2019-07-08 15:59     ` Christopher Baines
  0 siblings, 1 reply; 12+ messages in thread
From: Marius Bakke @ 2019-07-08 14:21 UTC (permalink / raw)
  To: Christopher Baines, 36535-done

[-- Attachment #1: Type: text/plain, Size: 7661 bytes --]

Hi Chris,

Christopher Baines <mail@cbaines.net> writes:

> Christopher Baines <mail@cbaines.net> writes:
>
>> Incorporate some changes from nixpkgs to the gobject-introspection package
>> patches.  This is motivated by looking at issues with libsoup and lollypop.
>> This changes means that the share/gir-1.0/Soup-2.4.gir file within libsoup
>> references libsoup-2.4.so.1 with an absolute filename, whereas previously, the
>> filename wasn't absolute.
>>
>> * gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch:
>> Incorporate changes from nixpkgs.
>> ---
>>  ...ct-introspection-absolute-shlib-path.patch | 141 +++++++++++++++++-
>>  1 file changed, 137 insertions(+), 4 deletions(-)
>>
>
> I've pushed this as [1] to core-updates now, as I wanted to get it in
> before the freeze.

Thank you for addressing this.  IIUC previously lollypop failed to
retain a reference to libsoup-2.4.so.1, whereas with this patch it does?

A few comments about the patch:

> diff --git a/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch b/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
> index d00cc5a420..3c0bb1c6cf 100644
> --- a/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
> +++ b/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
> @@ -2,10 +2,131 @@
>  # add the full path.
>  #
>  # This patch was provided by Luca Bruno <lucabru@src.gnome.org>  for 
> -# 'gobject-introspection' 1.40.0 in Nix. 
> ---- ./giscanner/utils.py.orig	2014-08-14 22:05:05.055334080 +0200
> -+++ ./giscanner/utils.py	2014-08-14 22:05:24.687497334 +0200
> -@@ -110,17 +110,11 @@
> +# 'gobject-introspection' 1.40.0 in Nix.
> +#
> +# It has since been updated to work with newer versions of
> +# gobject-introspection.
> +--- a/giscanner/scannermain.py
> ++++ b/giscanner/scannermain.py
> +@@ -95,6 +95,39 @@ def get_windows_option_group(parser):
> +     return group
> + 
> + 
> ++def _get_default_fallback_libpath():
> ++    # Newer multiple-output-optimized stdenv has an environment variable
> ++    # $outputLib which in turn specifies another variable which then is used as
> ++    # the destination for the library contents (${!outputLib}/lib).
> ++    store_path = os.environ.get(os.environ.get("outputLib")) if "outputLib" in os.environ else None
> ++    if store_path is None:
> ++        outputs = os.environ.get("outputs", "out").split()

gnu-build-system does not currently export an "outputs" variable.
Perhaps it should?

> ++        if "lib" in outputs:
> ++            # For multiple output derivations let's try whether there is a $lib
> ++            # environment variable and use that as the base store path.
> ++            store_path = os.environ.get("lib")
> ++        elif "out" in outputs:
> ++            # Otherwise we have a single output derivation, so the libraries
> ++            # most certainly will end up in "$out/lib".
> ++            store_path = os.environ.get("out")

Consequently, this is the only ever matching case, and "lib" outputs are
ignored, counter to what one might expect from glancing over this patch.

That is, unless one sets an "outputs" or "outputLib" variable in a
package recipe, so maybe we don't have to do anything here.

> ++
> ++    if store_path is not None:
> ++        # Even if we have a $lib as output, there still should be a $lib/lib
> ++        # directory.
> ++        return os.path.join(store_path, 'lib')
> ++    else:
> ++        # If we haven't found a possible scenario, let's return an empty string
> ++        # so that the shared library won't be prepended with a path.
> ++        #
> ++        # Note that this doesn't mean that all hope is lost, because after all
> ++        # we can still use --fallback-library-path to set one.
> ++        #
> ++        # Also, we're not returning None, because that would make it very
> ++        # difficult to disable adding fallback paths altogether using something
> ++        # like: --fallback-library-path=""
> ++        return ""
> ++
> ++
> + def _get_option_parser():
> +     parser = optparse.OptionParser('%prog [options] sources',
> +                                    version='%prog ' + giscanner.__version__)
> +@@ -205,6 +238,10 @@ match the namespace prefix.""")
> +     parser.add_option("", "--filelist",
> +                       action="store", dest="filelist", default=[],
> +                       help="file containing headers and sources to be scanned")
> ++    parser.add_option("", "--fallback-library-path",
> ++                      action="store", dest="fallback_libpath",
> ++                      default=_get_default_fallback_libpath(),
> ++                      help="Path to prepend to unknown shared libraries")
> + 
> +     group = get_preprocessor_option_group(parser)
> +     parser.add_option_group(group)
> +--- a/giscanner/shlibs.py
> ++++ b/giscanner/shlibs.py
> +@@ -57,6 +57,12 @@ def _ldd_library_pattern(library_name):
> +     $""" % re.escape(library_name), re.VERBOSE)
> + 
> + 
> ++def _ldd_library_guix_pattern(library_name):
> ++    store_dir = re.escape('/gnu/store')

Here we should use:

 os.environ.get("NIX_STORE") if "NIX_STORE" in os.environ else "/gnu/store"

So that it works for non-default store prefixes.

> ++    pattern = r'(%s(?:/[^/]*)+lib%s[^A-Za-z0-9_-][^\s\(\)]*)'
> ++    return re.compile(pattern % (store_dir, re.escape(library_name)))
> ++
> ++
> + # This is a what we do for non-la files. We assume that we are on an
> + # ELF-like system where ldd exists and the soname extracted with ldd is
> + # a filename that can be opened with dlopen().
> +@@ -106,7 +112,8 @@ def _resolve_non_libtool(options, binary, libraries):
> +             output = output.decode("utf-8", "replace")
> + 
> +         shlibs = resolve_from_ldd_output(libraries, output)
> +-        return list(map(sanitize_shlib_path, shlibs))
> ++        fallback_libpath = options.fallback_libpath or "";
> ++        return list(map(lambda p: os.path.join(fallback_libpath, p), map(sanitize_shlib_path, shlibs)))
> + 
> + 
> + def sanitize_shlib_path(lib):
> +@@ -115,19 +122,18 @@ def sanitize_shlib_path(lib):
> +     # In case we get relative paths on macOS (like @rpath) then we fall
> +     # back to the basename as well:
> +     # https://gitlab.gnome.org/GNOME/gobject-introspection/issues/222
> +-    if sys.platform == "darwin":
> +-        if not os.path.isabs(lib):
> +-            return os.path.basename(lib)
> +-        return lib
> +-    else:
> ++
> ++    # Always use absolute paths if available
> ++    if not os.path.isabs(lib):
> +         return os.path.basename(lib)
> ++    return lib
> + 
> + 
> + def resolve_from_ldd_output(libraries, output):
> +     patterns = {}
> +     for library in libraries:
> +         if not os.path.isfile(library):
> +-            patterns[library] = _ldd_library_pattern(library)
> ++            patterns[library] = (_ldd_library_pattern(library), _ldd_library_guix_pattern(library))
> +     if len(patterns) == 0:
> +         return []
> + 
> +@@ -139,8 +145,11 @@ def resolve_from_ldd_output(libraries, output):
> +         if line.endswith(':'):
> +             continue
> +         for word in line.split():
> +-            for library, pattern in patterns.items():
> +-                m = pattern.match(word)
> ++            for library, (pattern, guix_pattern) in patterns.items():
> ++                if line.find('/gnu/store') != -1:

Use $NIX_STORE here, too.

Other than that LGTM.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
  2019-07-08 14:21   ` [bug#36535] " Marius Bakke
@ 2019-07-08 15:59     ` Christopher Baines
  2019-07-08 16:29       ` Marius Bakke
  0 siblings, 1 reply; 12+ messages in thread
From: Christopher Baines @ 2019-07-08 15:59 UTC (permalink / raw)
  To: Marius Bakke; +Cc: 36535

[-- Attachment #1: Type: text/plain, Size: 9043 bytes --]


Marius Bakke <mbakke@fastmail.com> writes:

> Hi Chris,
>
> Christopher Baines <mail@cbaines.net> writes:
>
>> Christopher Baines <mail@cbaines.net> writes:
>>
>>> Incorporate some changes from nixpkgs to the gobject-introspection package
>>> patches.  This is motivated by looking at issues with libsoup and lollypop.
>>> This changes means that the share/gir-1.0/Soup-2.4.gir file within libsoup
>>> references libsoup-2.4.so.1 with an absolute filename, whereas previously, the
>>> filename wasn't absolute.
>>>
>>> * gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch:
>>> Incorporate changes from nixpkgs.
>>> ---
>>>  ...ct-introspection-absolute-shlib-path.patch | 141 +++++++++++++++++-
>>>  1 file changed, 137 insertions(+), 4 deletions(-)
>>>
>>
>> I've pushed this as [1] to core-updates now, as I wanted to get it in
>> before the freeze.
>
> Thank you for addressing this.  IIUC previously lollypop failed to
> retain a reference to libsoup-2.4.so.1, whereas with this patch it does?

Not quite... I think lollypop was reading the typelib in libsoup, but
the shared library was just referenced by filename, not the absolute
filename, and I think this was causing issues when trying to use libsoup
from lollypop.

On master:

grep shared-library /gnu/store/bafaiiblr2vmmf1zvidkw1137ndqnqg2-libsoup-2.66.2/share/gir-1.0/Soup-2.4.gir
             shared-library="libsoup-2.4.so.1"

On core-updates:

grep shared-library /gnu/store/b1ykh6xj11v7zav4r68v8qflk31cnddm-libsoup-2.66.2/share/gir-1.0/Soup-2.4.gir
             shared-library="/gnu/store/b1ykh6xj11v7zav4r68v8qflk31cnddm-libsoup-2.66.2/lib/libsoup-2.4.so.1"

> A few comments about the patch:
>
>> diff --git a/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch b/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
>> index d00cc5a420..3c0bb1c6cf 100644
>> --- a/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
>> +++ b/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
>> @@ -2,10 +2,131 @@
>>  # add the full path.
>>  #
>>  # This patch was provided by Luca Bruno <lucabru@src.gnome.org>  for
>> -# 'gobject-introspection' 1.40.0 in Nix.
>> ---- ./giscanner/utils.py.orig	2014-08-14 22:05:05.055334080 +0200
>> -+++ ./giscanner/utils.py	2014-08-14 22:05:24.687497334 +0200
>> -@@ -110,17 +110,11 @@
>> +# 'gobject-introspection' 1.40.0 in Nix.
>> +#
>> +# It has since been updated to work with newer versions of
>> +# gobject-introspection.
>> +--- a/giscanner/scannermain.py
>> ++++ b/giscanner/scannermain.py
>> +@@ -95,6 +95,39 @@ def get_windows_option_group(parser):
>> +     return group
>> +
>> +
>> ++def _get_default_fallback_libpath():
>> ++    # Newer multiple-output-optimized stdenv has an environment variable
>> ++    # $outputLib which in turn specifies another variable which then is used as
>> ++    # the destination for the library contents (${!outputLib}/lib).
>> ++    store_path = os.environ.get(os.environ.get("outputLib")) if "outputLib" in os.environ else None
>> ++    if store_path is None:
>> ++        outputs = os.environ.get("outputs", "out").split()
>
> gnu-build-system does not currently export an "outputs" variable.
> Perhaps it should?

Ah, I didn't realise this part of the patch was as Nix specific as it
is...

At least for the change I was trying to affect, this seems to be
probably redundant, or somehow doing the job. Maybe this part of the
patch relating to the fallback_libpath should be removed.

>> ++        if "lib" in outputs:
>> ++            # For multiple output derivations let's try whether there is a $lib
>> ++            # environment variable and use that as the base store path.
>> ++            store_path = os.environ.get("lib")
>> ++        elif "out" in outputs:
>> ++            # Otherwise we have a single output derivation, so the libraries
>> ++            # most certainly will end up in "$out/lib".
>> ++            store_path = os.environ.get("out")
>
> Consequently, this is the only ever matching case, and "lib" outputs are
> ignored, counter to what one might expect from glancing over this patch.
>
> That is, unless one sets an "outputs" or "outputLib" variable in a
> package recipe, so maybe we don't have to do anything here.
>
>> ++
>> ++    if store_path is not None:
>> ++        # Even if we have a $lib as output, there still should be a $lib/lib
>> ++        # directory.
>> ++        return os.path.join(store_path, 'lib')
>> ++    else:
>> ++        # If we haven't found a possible scenario, let's return an empty string
>> ++        # so that the shared library won't be prepended with a path.
>> ++        #
>> ++        # Note that this doesn't mean that all hope is lost, because after all
>> ++        # we can still use --fallback-library-path to set one.
>> ++        #
>> ++        # Also, we're not returning None, because that would make it very
>> ++        # difficult to disable adding fallback paths altogether using something
>> ++        # like: --fallback-library-path=""
>> ++        return ""
>> ++
>> ++
>> + def _get_option_parser():
>> +     parser = optparse.OptionParser('%prog [options] sources',
>> +                                    version='%prog ' + giscanner.__version__)
>> +@@ -205,6 +238,10 @@ match the namespace prefix.""")
>> +     parser.add_option("", "--filelist",
>> +                       action="store", dest="filelist", default=[],
>> +                       help="file containing headers and sources to be scanned")
>> ++    parser.add_option("", "--fallback-library-path",
>> ++                      action="store", dest="fallback_libpath",
>> ++                      default=_get_default_fallback_libpath(),
>> ++                      help="Path to prepend to unknown shared libraries")
>> +
>> +     group = get_preprocessor_option_group(parser)
>> +     parser.add_option_group(group)
>> +--- a/giscanner/shlibs.py
>> ++++ b/giscanner/shlibs.py
>> +@@ -57,6 +57,12 @@ def _ldd_library_pattern(library_name):
>> +     $""" % re.escape(library_name), re.VERBOSE)
>> +
>> +
>> ++def _ldd_library_guix_pattern(library_name):
>> ++    store_dir = re.escape('/gnu/store')
>
> Here we should use:
>
>  os.environ.get("NIX_STORE") if "NIX_STORE" in os.environ else "/gnu/store"
>
> So that it works for non-default store prefixes.

Given NIX_STORE is set at build time, and this code is mostly used at
build time, then that would work.

Before I was thinking about how to actually put the store path in the
code at build time, but that's probably not necessary.

>> ++    pattern = r'(%s(?:/[^/]*)+lib%s[^A-Za-z0-9_-][^\s\(\)]*)'
>> ++    return re.compile(pattern % (store_dir, re.escape(library_name)))
>> ++
>> ++
>> + # This is a what we do for non-la files. We assume that we are on an
>> + # ELF-like system where ldd exists and the soname extracted with ldd is
>> + # a filename that can be opened with dlopen().
>> +@@ -106,7 +112,8 @@ def _resolve_non_libtool(options, binary, libraries):
>> +             output = output.decode("utf-8", "replace")
>> +
>> +         shlibs = resolve_from_ldd_output(libraries, output)
>> +-        return list(map(sanitize_shlib_path, shlibs))
>> ++        fallback_libpath = options.fallback_libpath or "";
>> ++        return list(map(lambda p: os.path.join(fallback_libpath, p), map(sanitize_shlib_path, shlibs)))
>> +
>> +
>> + def sanitize_shlib_path(lib):
>> +@@ -115,19 +122,18 @@ def sanitize_shlib_path(lib):
>> +     # In case we get relative paths on macOS (like @rpath) then we fall
>> +     # back to the basename as well:
>> +     # https://gitlab.gnome.org/GNOME/gobject-introspection/issues/222
>> +-    if sys.platform == "darwin":
>> +-        if not os.path.isabs(lib):
>> +-            return os.path.basename(lib)
>> +-        return lib
>> +-    else:
>> ++
>> ++    # Always use absolute paths if available
>> ++    if not os.path.isabs(lib):
>> +         return os.path.basename(lib)
>> ++    return lib
>> +
>> +
>> + def resolve_from_ldd_output(libraries, output):
>> +     patterns = {}
>> +     for library in libraries:
>> +         if not os.path.isfile(library):
>> +-            patterns[library] = _ldd_library_pattern(library)
>> ++            patterns[library] = (_ldd_library_pattern(library), _ldd_library_guix_pattern(library))
>> +     if len(patterns) == 0:
>> +         return []
>> +
>> +@@ -139,8 +145,11 @@ def resolve_from_ldd_output(libraries, output):
>> +         if line.endswith(':'):
>> +             continue
>> +         for word in line.split():
>> +-            for library, pattern in patterns.items():
>> +-                m = pattern.match(word)
>> ++            for library, (pattern, guix_pattern) in patterns.items():
>> ++                if line.find('/gnu/store') != -1:
>
> Use $NIX_STORE here, too.
>
> Other than that LGTM.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 962 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
  2019-07-08 15:59     ` Christopher Baines
@ 2019-07-08 16:29       ` Marius Bakke
  2019-07-10 17:35         ` Marius Bakke
  2019-07-12 18:44         ` Marius Bakke
  0 siblings, 2 replies; 12+ messages in thread
From: Marius Bakke @ 2019-07-08 16:29 UTC (permalink / raw)
  To: Christopher Baines; +Cc: 36535

[-- Attachment #1: Type: text/plain, Size: 4411 bytes --]

Christopher Baines <mail@cbaines.net> writes:

> Marius Bakke <mbakke@fastmail.com> writes:
>
>> Hi Chris,
>>
>> Christopher Baines <mail@cbaines.net> writes:
>>
>>> Christopher Baines <mail@cbaines.net> writes:
>>>
>>>> Incorporate some changes from nixpkgs to the gobject-introspection package
>>>> patches.  This is motivated by looking at issues with libsoup and lollypop.
>>>> This changes means that the share/gir-1.0/Soup-2.4.gir file within libsoup
>>>> references libsoup-2.4.so.1 with an absolute filename, whereas previously, the
>>>> filename wasn't absolute.
>>>>
>>>> * gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch:
>>>> Incorporate changes from nixpkgs.
>>>> ---
>>>>  ...ct-introspection-absolute-shlib-path.patch | 141 +++++++++++++++++-
>>>>  1 file changed, 137 insertions(+), 4 deletions(-)
>>>>
>>>
>>> I've pushed this as [1] to core-updates now, as I wanted to get it in
>>> before the freeze.
>>
>> Thank you for addressing this.  IIUC previously lollypop failed to
>> retain a reference to libsoup-2.4.so.1, whereas with this patch it does?
>
> Not quite... I think lollypop was reading the typelib in libsoup, but
> the shared library was just referenced by filename, not the absolute
> filename, and I think this was causing issues when trying to use libsoup
> from lollypop.

I see, thanks for explaining.  In Guix, we usually resolve these
situations by native-search-paths, do you know if gobject-introspection
supports looking up the 'share/gir-1.0' directory from an environment
variable (similar to how GI_TYPELIB_PATH works today)?  However...

>
> On master:
>
> grep shared-library /gnu/store/bafaiiblr2vmmf1zvidkw1137ndqnqg2-libsoup-2.66.2/share/gir-1.0/Soup-2.4.gir
>              shared-library="libsoup-2.4.so.1"
>
> On core-updates:
>
> grep shared-library /gnu/store/b1ykh6xj11v7zav4r68v8qflk31cnddm-libsoup-2.66.2/share/gir-1.0/Soup-2.4.gir
>              shared-library="/gnu/store/b1ykh6xj11v7zav4r68v8qflk31cnddm-libsoup-2.66.2/lib/libsoup-2.4.so.1"

...this is even better, so I am mostly just curious :-)

>> A few comments about the patch:
>>
>>> diff --git a/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch b/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
>>> index d00cc5a420..3c0bb1c6cf 100644
>>> --- a/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
>>> +++ b/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
>>> @@ -2,10 +2,131 @@
>>>  # add the full path.
>>>  #
>>>  # This patch was provided by Luca Bruno <lucabru@src.gnome.org>  for
>>> -# 'gobject-introspection' 1.40.0 in Nix.
>>> ---- ./giscanner/utils.py.orig	2014-08-14 22:05:05.055334080 +0200
>>> -+++ ./giscanner/utils.py	2014-08-14 22:05:24.687497334 +0200
>>> -@@ -110,17 +110,11 @@
>>> +# 'gobject-introspection' 1.40.0 in Nix.
>>> +#
>>> +# It has since been updated to work with newer versions of
>>> +# gobject-introspection.
>>> +--- a/giscanner/scannermain.py
>>> ++++ b/giscanner/scannermain.py
>>> +@@ -95,6 +95,39 @@ def get_windows_option_group(parser):
>>> +     return group
>>> +
>>> +
>>> ++def _get_default_fallback_libpath():
>>> ++    # Newer multiple-output-optimized stdenv has an environment variable
>>> ++    # $outputLib which in turn specifies another variable which then is used as
>>> ++    # the destination for the library contents (${!outputLib}/lib).
>>> ++    store_path = os.environ.get(os.environ.get("outputLib")) if "outputLib" in os.environ else None
>>> ++    if store_path is None:
>>> ++        outputs = os.environ.get("outputs", "out").split()
>>
>> gnu-build-system does not currently export an "outputs" variable.
>> Perhaps it should?
>
> Ah, I didn't realise this part of the patch was as Nix specific as it
> is...
>
> At least for the change I was trying to affect, this seems to be
> probably redundant, or somehow doing the job. Maybe this part of the
> patch relating to the fallback_libpath should be removed.

I'd keep the "$outputs" logic, it sounds like a useful and easy change
to do in gnu-build-system, although maybe not for this 'core-updates'
round.  We can use it in package recipes for fun and profit meanwhile.

However I doubt we'll ever use "outputLib", so it would be good to
remove that.

If you are updating the patch, could you also add a link to the upstream
patch, as well as one to this discussion?

Thank you!

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
  2019-07-08 16:29       ` Marius Bakke
@ 2019-07-10 17:35         ` Marius Bakke
  2019-07-12 18:44         ` Marius Bakke
  1 sibling, 0 replies; 12+ messages in thread
From: Marius Bakke @ 2019-07-10 17:35 UTC (permalink / raw)
  To: Christopher Baines; +Cc: 36535

[-- Attachment #1: Type: text/plain, Size: 1927 bytes --]

Marius Bakke <mbakke@fastmail.com> writes:

> Christopher Baines <mail@cbaines.net> writes:
>
>> Marius Bakke <mbakke@fastmail.com> writes:
>>
>>> Hi Chris,
>>>
>>> Christopher Baines <mail@cbaines.net> writes:
>>>
>>>> Christopher Baines <mail@cbaines.net> writes:
>>>>
>>>>> Incorporate some changes from nixpkgs to the gobject-introspection package
>>>>> patches.  This is motivated by looking at issues with libsoup and lollypop.
>>>>> This changes means that the share/gir-1.0/Soup-2.4.gir file within libsoup
>>>>> references libsoup-2.4.so.1 with an absolute filename, whereas previously, the
>>>>> filename wasn't absolute.
>>>>>
>>>>> * gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch:
>>>>> Incorporate changes from nixpkgs.
>>>>> ---
>>>>>  ...ct-introspection-absolute-shlib-path.patch | 141 +++++++++++++++++-
>>>>>  1 file changed, 137 insertions(+), 4 deletions(-)
>>>>>
>>>>
>>>> I've pushed this as [1] to core-updates now, as I wanted to get it in
>>>> before the freeze.
>>>
>>> Thank you for addressing this.  IIUC previously lollypop failed to
>>> retain a reference to libsoup-2.4.so.1, whereas with this patch it does?
>>
>> Not quite... I think lollypop was reading the typelib in libsoup, but
>> the shared library was just referenced by filename, not the absolute
>> filename, and I think this was causing issues when trying to use libsoup
>> from lollypop.
>
> I see, thanks for explaining.  In Guix, we usually resolve these
> situations by native-search-paths, do you know if gobject-introspection
> supports looking up the 'share/gir-1.0' directory from an environment
> variable (similar to how GI_TYPELIB_PATH works today)?  However...

Errh, ignore this, I need to study the GObject stuff one of these days...

Do you think you'll have time to update the patch within the coming
days?  The only important part is the NIX_STORE bits; the rest can be
dealt with later.

TIA!

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
  2019-07-08 16:29       ` Marius Bakke
  2019-07-10 17:35         ` Marius Bakke
@ 2019-07-12 18:44         ` Marius Bakke
  2019-07-12 23:22           ` Christopher Baines
  1 sibling, 1 reply; 12+ messages in thread
From: Marius Bakke @ 2019-07-12 18:44 UTC (permalink / raw)
  To: Christopher Baines; +Cc: 36535

severity 36535 important

>>>> ++def _get_default_fallback_libpath():
>>>> ++    # Newer multiple-output-optimized stdenv has an environment variable
>>>> ++    # $outputLib which in turn specifies another variable which then is used as
>>>> ++    # the destination for the library contents (${!outputLib}/lib).
>>>> ++    store_path = os.environ.get(os.environ.get("outputLib")) if "outputLib" in os.environ else None
>>>> ++    if store_path is None:
>>>> ++        outputs = os.environ.get("outputs", "out").split()
>>>
>>> gnu-build-system does not currently export an "outputs" variable.
>>> Perhaps it should?
>>
>> Ah, I didn't realise this part of the patch was as Nix specific as it
>> is...
>>
>> At least for the change I was trying to affect, this seems to be
>> probably redundant, or somehow doing the job. Maybe this part of the
>> patch relating to the fallback_libpath should be removed.
>
> I'd keep the "$outputs" logic, it sounds like a useful and easy change
> to do in gnu-build-system, although maybe not for this 'core-updates'
> round.  We can use it in package recipes for fun and profit meanwhile.

We now have a user of the $outputs variable:

https://git.savannah.gnu.org/cgit/guix.git/commit/?id=7555d539245ff3456848c02d61f9e601ee5af463

Incidentally, the package was broken because of the very same feature :-)

But we can not merge this with the hard-coded /gnu/store paths, as that
is likely to cause strange problems for users with a non-default store
prefix.

Unless someone steps up to fix it within a few days, I think we'll have
to revert it for now.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
  2019-07-12 18:44         ` Marius Bakke
@ 2019-07-12 23:22           ` Christopher Baines
  2019-07-13 11:09             ` [bug#36535] [PATCH] gnu: gobject-introspection: Remove hardcoded store from patch Christopher Baines
  2019-07-13 11:11             ` [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch Christopher Baines
  0 siblings, 2 replies; 12+ messages in thread
From: Christopher Baines @ 2019-07-12 23:22 UTC (permalink / raw)
  To: Marius Bakke; +Cc: 36535

[-- Attachment #1: Type: text/plain, Size: 3355 bytes --]


Marius Bakke <mbakke@fastmail.com> writes:

> severity 36535 important
>
>>>>> ++def _get_default_fallback_libpath():
>>>>> ++    # Newer multiple-output-optimized stdenv has an environment variable
>>>>> ++    # $outputLib which in turn specifies another variable which then is used as
>>>>> ++    # the destination for the library contents (${!outputLib}/lib).
>>>>> ++    store_path = os.environ.get(os.environ.get("outputLib")) if "outputLib" in os.environ else None
>>>>> ++    if store_path is None:
>>>>> ++        outputs = os.environ.get("outputs", "out").split()
>>>>
>>>> gnu-build-system does not currently export an "outputs" variable.
>>>> Perhaps it should?
>>>
>>> Ah, I didn't realise this part of the patch was as Nix specific as it
>>> is...
>>>
>>> At least for the change I was trying to affect, this seems to be
>>> probably redundant, or somehow doing the job. Maybe this part of the
>>> patch relating to the fallback_libpath should be removed.
>>
>> I'd keep the "$outputs" logic, it sounds like a useful and easy change
>> to do in gnu-build-system, although maybe not for this 'core-updates'
>> round.  We can use it in package recipes for fun and profit meanwhile.
>
> We now have a user of the $outputs variable:
>
> https://git.savannah.gnu.org/cgit/guix.git/commit/?id=7555d539245ff3456848c02d61f9e601ee5af463

Ooh, interesting :)

> Incidentally, then package was broken because of the very same feature :-)
>
> But we can not merge this with the hard-coded /gnu/store paths, as that
> is likely to cause strange problems for users with a non-default store
> prefix.
>
> Unless someone steps up to fix it within a few days, I think we'll have
> to revert it for now.

I have some time now to look at this, I'm currently building libsoup
with these changes to the patch.


modified   gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
@@ -61,12 +61,14 @@
      parser.add_option_group(group)
 --- a/giscanner/shlibs.py
 +++ b/giscanner/shlibs.py
-@@ -57,6 +57,12 @@ def _ldd_library_pattern(library_name):
+@@ -57,6 +57,14 @@ def _ldd_library_pattern(library_name):
      $""" % re.escape(library_name), re.VERBOSE)
  
  
 +def _ldd_library_guix_pattern(library_name):
-+    store_dir = re.escape('/gnu/store')
++    store_dir = re.escape(
++      os.environ.get("NIX_STORE", default="/gnu/store")
++    )
 +    pattern = r'(%s(?:/[^/]*)+lib%s[^A-Za-z0-9_-][^\s\(\)]*)'
 +    return re.compile(pattern % (store_dir, re.escape(library_name)))
 +
@@ -109,14 +111,15 @@
      if len(patterns) == 0:
          return []
  
-@@ -139,8 +145,11 @@ def resolve_from_ldd_output(libraries, output):
+@@ -139,8 +145,12 @@ def resolve_from_ldd_output(libraries, output):
          if line.endswith(':'):
              continue
          for word in line.split():
 -            for library, pattern in patterns.items():
 -                m = pattern.match(word)
 +            for library, (pattern, guix_pattern) in patterns.items():
-+                if line.find('/gnu/store') != -1:
++                store_dir = os.environ.get("NIX_STORE", default="/gnu/store")
++                if line.find(store_dir) != -1:
 +                    m = guix_pattern.match(word)
 +                else:
 +                    m = pattern.match(word)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 962 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [bug#36535] [PATCH] gnu: gobject-introspection: Remove hardcoded store from patch.
  2019-07-12 23:22           ` Christopher Baines
@ 2019-07-13 11:09             ` Christopher Baines
  2019-07-13 11:11             ` [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch Christopher Baines
  1 sibling, 0 replies; 12+ messages in thread
From: Christopher Baines @ 2019-07-13 11:09 UTC (permalink / raw)
  To: Marius Bakke; +Cc: 36535

* gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch: Use
the NIX_STORE environment variable, rather than hardcoding the store
directory.
---
 .../gobject-introspection-absolute-shlib-path.patch   | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch b/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
index 3c0bb1c6cf..956fa617c3 100644
--- a/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
+++ b/gnu/packages/patches/gobject-introspection-absolute-shlib-path.patch
@@ -61,12 +61,14 @@
      parser.add_option_group(group)
 --- a/giscanner/shlibs.py
 +++ b/giscanner/shlibs.py
-@@ -57,6 +57,12 @@ def _ldd_library_pattern(library_name):
+@@ -57,6 +57,14 @@ def _ldd_library_pattern(library_name):
      $""" % re.escape(library_name), re.VERBOSE)
  
  
 +def _ldd_library_guix_pattern(library_name):
-+    store_dir = re.escape('/gnu/store')
++    store_dir = re.escape(
++      os.environ.get("NIX_STORE", default="/gnu/store")
++    )
 +    pattern = r'(%s(?:/[^/]*)+lib%s[^A-Za-z0-9_-][^\s\(\)]*)'
 +    return re.compile(pattern % (store_dir, re.escape(library_name)))
 +
@@ -109,14 +111,15 @@
      if len(patterns) == 0:
          return []
  
-@@ -139,8 +145,11 @@ def resolve_from_ldd_output(libraries, output):
+@@ -139,8 +145,12 @@ def resolve_from_ldd_output(libraries, output):
          if line.endswith(':'):
              continue
          for word in line.split():
 -            for library, pattern in patterns.items():
 -                m = pattern.match(word)
 +            for library, (pattern, guix_pattern) in patterns.items():
-+                if line.find('/gnu/store') != -1:
++                store_dir = os.environ.get("NIX_STORE", default="/gnu/store")
++                if line.find(store_dir) != -1:
 +                    m = guix_pattern.match(word)
 +                else:
 +                    m = pattern.match(word)
-- 
2.22.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
  2019-07-12 23:22           ` Christopher Baines
  2019-07-13 11:09             ` [bug#36535] [PATCH] gnu: gobject-introspection: Remove hardcoded store from patch Christopher Baines
@ 2019-07-13 11:11             ` Christopher Baines
  2019-07-13 16:46               ` Marius Bakke
  1 sibling, 1 reply; 12+ messages in thread
From: Christopher Baines @ 2019-07-13 11:11 UTC (permalink / raw)
  To: Marius Bakke; +Cc: 36535

[-- Attachment #1: Type: text/plain, Size: 266 bytes --]


Christopher Baines <mail@cbaines.net> writes:

> I have some time now to look at this, I'm currently building libsoup
> with these changes to the patch.

I've now send a patch with these changes. I've managed to build libsoup
with it, and the .gir files look good.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 962 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
  2019-07-13 11:11             ` [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch Christopher Baines
@ 2019-07-13 16:46               ` Marius Bakke
  2019-07-13 22:14                 ` bug#36535: " Christopher Baines
  0 siblings, 1 reply; 12+ messages in thread
From: Marius Bakke @ 2019-07-13 16:46 UTC (permalink / raw)
  To: Christopher Baines; +Cc: 36535

[-- Attachment #1: Type: text/plain, Size: 353 bytes --]

Christopher Baines <mail@cbaines.net> writes:

> Christopher Baines <mail@cbaines.net> writes:
>
>> I have some time now to look at this, I'm currently building libsoup
>> with these changes to the patch.
>
> I've now send a patch with these changes. I've managed to build libsoup
> with it, and the .gir files look good.

Thank you!  The changes LGTM.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#36535: [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch.
  2019-07-13 16:46               ` Marius Bakke
@ 2019-07-13 22:14                 ` Christopher Baines
  0 siblings, 0 replies; 12+ messages in thread
From: Christopher Baines @ 2019-07-13 22:14 UTC (permalink / raw)
  To: Marius Bakke; +Cc: 36535-done

[-- Attachment #1: Type: text/plain, Size: 457 bytes --]


Marius Bakke <mbakke@fastmail.com> writes:

> Christopher Baines <mail@cbaines.net> writes:
>
>> Christopher Baines <mail@cbaines.net> writes:
>>
>>> I have some time now to look at this, I'm currently building libsoup
>>> with these changes to the patch.
>>
>> I've now send a patch with these changes. I've managed to build libsoup
>> with it, and the .gir files look good.
>
> Thank you!  The changes LGTM.

Great, I've pushed this to core-updates now.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 962 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2019-07-13 22:15 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-07 10:48 [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch Christopher Baines
2019-07-08  7:46 ` bug#36535: " Christopher Baines
2019-07-08 14:21   ` [bug#36535] " Marius Bakke
2019-07-08 15:59     ` Christopher Baines
2019-07-08 16:29       ` Marius Bakke
2019-07-10 17:35         ` Marius Bakke
2019-07-12 18:44         ` Marius Bakke
2019-07-12 23:22           ` Christopher Baines
2019-07-13 11:09             ` [bug#36535] [PATCH] gnu: gobject-introspection: Remove hardcoded store from patch Christopher Baines
2019-07-13 11:11             ` [bug#36535] [PATCH] gnu: gobject-introspection: Update absolute-shlib-path.patch Christopher Baines
2019-07-13 16:46               ` Marius Bakke
2019-07-13 22:14                 ` bug#36535: " Christopher Baines

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).