Change:
For some packages, a wrong path to the library is generated. For example, produces an extra directory: Now, the typelib path is supposed to be addressed by It only works when typelibdir is an absolute path but apparently that is not the problem here (it is ). Possibly a bug in the ? This is how the gir file is built (add to expression): Nixpkgs
Indeed, the patch is the problem. The supplied regex matched too eagerly: Simple change should fix it.
Hmm, right it cannot be as simple as adding two slashes it would just match
Hmm, so lets see if I understand this correctly. We want to distinguish between two cases: link is to the and we want the absolute path link is not to the nix store and we only want the soname The original pattern in will produce only sonames, correctly extracting the left hand side of the ldd output (the upstream comment for is rather confusing as it seems to use the wrong library name which doesn't produce any match at all, so I'm assuming they mean `libpangoft2-1). Would it make sense to patch instead, so we don't have to implement control flow in a regular expression? So something like this: where is specifically made to extract the absolute path. Not sure if this is relevant as you've already created a fix which should work okay as I'm assuming nix mostly runs on GNU systems? But I'm thinking it might make things easier.
Yep. Yes, unless you use OpenBSD or something. They meant . Library name would also match , I guess they assume there will be no such library. A problem might occur with gspell, which has as the library name which would also match but only if you linked against both. Yes this would be the cleanest, it will even allow to fix the upstream the two aforementioned bugs without us having to update the thing. I was too focused on regex composition to consider using two functions.

Discussion:
<del> diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py index 89ec193..54f1d2e 100755 </del> --- a/giscanner/scannermain.py +++ b/giscanner/scannermain.py <del> @@ -94,6 +94,39 @@ def get_windows_option_group(parser): </del> <ins> @@ -100,6 +100,39 @@ </ins> return group

def _get_option_parser(): parser = optparse.OptionParser('%prog [options] sources') parser.add_option('', "--quiet", <del> @@ -200,6 +233,10 @@ match the namespace prefix.""") </del> <ins> @@ -209,6 +242,10 @@ </ins> parser.add_option("", "--filelist", action="store", dest="filelist", default=[], help="file containing headers and sources to be scanned")

group = get_preprocessor_option_group(parser) parser.add_option_group(group) <del> diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py index 838d343..ca7fc0d 100644 </del> --- a/giscanner/shlibs.py +++ b/giscanner/shlibs.py <del> @@ -53,10 +53,27 @@ def _resolve_libtool(options, binary, libraries): # Match absolute paths on OS X to conform to how libraries are usually # referenced on OS X systems. def _ldd_library_pattern(library_name): +    nix_store_dir = re.escape('@nixStoreDir@'.rstrip('/')) pattern = "(?<![A-Za-z0-9_-])(lib*%s[^A-Za-z0-9_-][^s()]*)" if platform.system() == 'Darwin': </del> <ins> @@ -63,6 +63,11 @@ </ins> pattern = "([^s]*lib*%s[^A-Za-z0-9_-][^s()]*)" <del> -    return re.compile(pattern % re.escape(library_name)) +        return re.compile(pattern % re.escape(library_name)) +    pattern = r''' +        ( +          (?: +            # First match Nix store paths because they need to be absolute. +            (?:%s(?:/[^/]*)+) +            # Everything else not a store path remains relative, because we +            # would end up with temporary paths that are only valid during +            # build time in the resulting GIR file. +            | (?<=/) +          ) +          # And finally the library itself: +          (?:lib%s[^A-Za-z0-9_-][^s()]*) +        ) +    ''' +    return re.compile(pattern % (nix_store_dir, re.escape(library_name)), +                      re.VERBOSE) </del> <ins> return re.compile(pattern % re.escape(library_name)) +def _ldd_library_nix_pattern(library_name): +    nix_store_dir = re.escape('@nixStoreDir@'.rstrip('/')) +    pattern = r'(%s(?:/[^/]*)+lib%s[^A-Za-z0-9_-][^s()]*)' +    return re.compile(pattern % (nix_store_dir, re.escape(library_name))) + </ins> # This is a what we do for non-la files. We assume that we are on an <del> @@ -115,7 +132,11 @@ def _resolve_non_libtool(options, binary, libraries): m = pattern.search(line) </del> <ins> # ELF-like system where ldd exists and the soname extracted with ldd is @@ -112,7 +117,7 @@ proc = subprocess.Popen(args, stdout=subprocess.PIPE) patterns = {} for library in libraries: -            patterns[library] = _ldd_library_pattern(library) +            patterns[library] = (_ldd_library_pattern(library), _ldd_library_nix_pattern(library)) shlibs = [] for line in proc.stdout: @@ -122,11 +127,14 @@ # possible for the name of the binary to match _ldd_library_pattern. if line == binary.args[0] + ':n': continue -            for library, pattern in patterns.items(): -                m = pattern.search(line) +            for library, (pattern, nix_pattern) in patterns.items(): +                if line.find('@nixStoreDir@') != -1: +                    m = nix_pattern.search(line) +                else: +                    m = pattern.search(line) </ins> if m: del patterns[library] -                    shlibs.append(m.group(1)) <del> +                    match = m.group(1) +                    if not match.startswith('/')  +                       and len(options.fallback_libpath) > 0: +                        match = os.path.join(options.fallback_libpath, match) +                    shlibs.append(match) </del> <ins> +                    shlibs.append(os.path.join(options.fallback_libpath, m.group(1))) </ins> break if len(patterns) > 0: <del> diff --git a/giscanner/utils.py b/giscanner/utils.py index 660081e..c9c767a 100644 </del> --- a/giscanner/utils.py +++ b/giscanner/utils.py <del> @@ -109,17 +109,11 @@ def extract_libtool_shlib(la_file): </del> <ins> @@ -113,17 +113,11 @@ </ins> if dlname is None: return None