(self, out: str, out_raw: str)
return link_args, raw_link_args
@out: PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 pkg-config --libs
        @out_raw: pkg-config --libs

        We always look for the file ourselves instead of depending on the
        compiler to find it with -lfoo or foo.lib (if possible) because:
        1. We want to be able to select static or shared
        2. We need the full path of the library to calculate RPATH values
        3. De-dup of libraries is easier when we have absolute paths

        Libraries that are provided by the toolchain or are not found by
        find_library() will be added with -L -l pairs.
@out: PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 pkg-config --libs
        @out_raw: pkg-config --libs
@out : PKG_CONFIG_ALLOW_SYSTEM_LIBS = 1 pkg - config -- libs @out_raw : pkg - config -- libs
def _search_libs(self, out: str, out_raw: str) -> T.Tuple[T.List[str], T.List[str]]:
        '''
        @out: PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 pkg-config --libs
        @out_raw: pkg-config --libs

        We always look for the file ourselves instead of depending on the
        compiler to find it with -lfoo or foo.lib (if possible) because:
        1. We want to be able to select static or shared
        2. We need the full path of the library to calculate RPATH values
        3. De-dup of libraries is easier when we have absolute paths

        Libraries that are provided by the toolchain or are not found by
        find_library() will be added with -L -l pairs.
        '''
        # Library paths should be safe to de-dup
        #
        # First, figure out what library paths to use. Originally, we were
        # doing this as part of the loop, but due to differences in the order
        # of -L values between pkg-config and pkgconf, we need to do that as
        # a separate step. See:
        # https://github.com/mesonbuild/meson/issues/3951
        # https://github.com/mesonbuild/meson/issues/4023
        #
        # Separate system and prefix paths, and ensure that prefix paths are
        # always searched first.
        prefix_libpaths: OrderedSet[str] = OrderedSet()
        # We also store this raw_link_args on the object later
        raw_link_args = self._convert_mingw_paths(self._split_args(out_raw))
        for arg in raw_link_args:
            if arg.startswith('-L') and not arg.startswith(('-L-l', '-L-L')):
                path = arg[2:]
                if not os.path.isabs(path):
                    # Resolve the path as a compiler in the build directory would
                    path = os.path.join(self.env.get_build_dir(), path)
                prefix_libpaths.add(path)
        # Library paths are not always ordered in a meaningful way
        #
        # Instead of relying on pkg-config or pkgconf to provide -L flags in a
        # specific order, we reorder library paths ourselves, according to th
        # order specified in PKG_CONFIG_PATH. See:
        # https://github.com/mesonbuild/meson/issues/4271
        #
        # Only prefix_libpaths are reordered here because there should not be
        # too many system_libpaths to cause library version issues.
        pkg_config_path: T.List[str] = self.env.coredata.options[OptionKey('pkg_config_path', machine=self.for_machine)].value
        pkg_config_path = self._convert_mingw_paths(pkg_config_path)
        prefix_libpaths = OrderedSet(sort_libpaths(list(prefix_libpaths), pkg_config_path))
        system_libpaths: OrderedSet[str] = OrderedSet()
        full_args = self._convert_mingw_paths(self._split_args(out))
        for arg in full_args:
            if arg.startswith(('-L-l', '-L-L')):
                # These are D language arguments, not library paths
                continue
            if arg.startswith('-L') and arg[2:] not in prefix_libpaths:
                system_libpaths.add(arg[2:])
        # Use this re-ordered path list for library resolution
        libpaths = list(prefix_libpaths) + list(system_libpaths)
        # Track -lfoo libraries to avoid duplicate work
        libs_found: OrderedSet[str] = OrderedSet()
        # Track not-found libraries to know whether to add library paths
        libs_notfound = []
        # Generate link arguments for this library
        link_args = []
        for lib in full_args:
            if lib.startswith(('-L-l', '-L-L')):
                # These are D language arguments, add them as-is
                pass
            elif lib.startswith('-L'):
                # We already handled library paths above
                continue
            elif lib.startswith('-l:'):
                # see: https://stackoverflow.com/questions/48532868/gcc-library-option-with-a-colon-llibevent-a
                # also : See the documentation of -lnamespec | --library=namespec in the linker manual
                #                     https://sourceware.org/binutils/docs-2.18/ld/Options.html

                # Don't resolve the same -l:libfoo.a argument again
                if lib in libs_found:
                    continue
                libfilename = lib[3:]
                foundname = None
                for libdir in libpaths:
                    target = os.path.join(libdir, libfilename)
                    if os.path.exists(target):
                        foundname = target
                        break
                if foundname is None:
                    if lib in libs_notfound:
                        continue
                    else:
                        mlog.warning('Library {!r} not found for dependency {!r}, may '
                                    'not be successfully linked'.format(libfilename, self.name))
                    libs_notfound.append(lib)
                else:
                    lib = foundname
            elif lib.startswith('-l'):
                # Don't resolve the same -lfoo argument again
                if lib in libs_found:
                    continue
                if self.clib_compiler:
                    args = self.clib_compiler.find_library(lib[2:], self.env,
                                                           libpaths, self.libtype)
                # If the project only uses a non-clib language such as D, Rust,
                # C#, Python, etc, all we can do is limp along by adding the
                # arguments as-is and then adding the libpaths at the end.
                else:
                    args = None
                if args is not None:
                    libs_found.add(lib)
                    # Replace -l arg with full path to library if available
                    # else, library is either to be ignored, or is provided by
                    # the compiler, can't be resolved, and should be used as-is
                    if args:
                        if not args[0].startswith('-l'):
                            lib = args[0]
                    else:
                        continue
                else:
                    # Library wasn't found, maybe we're looking in the wrong
                    # places or the library will be provided with LDFLAGS or
                    # LIBRARY_PATH from the environment (on macOS), and many
                    # other edge cases that we can't account for.
                    #
                    # Add all -L paths and use it as -lfoo
                    if lib in libs_notfound:
                        continue
                    if self.static:
                        mlog.warning('Static library {!r} not found for dependency {!r}, may '
                                     'not be statically linked'.format(lib[2:], self.name))
                    libs_notfound.append(lib)
            elif lib.endswith(".la"):
                shared_libname = self.extract_libtool_shlib(lib)
                shared_lib = os.path.join(os.path.dirname(lib), shared_libname)
                if not os.path.exists(shared_lib):
                    shared_lib = os.path.join(os.path.dirname(lib), ".libs", shared_libname)

                if not os.path.exists(shared_lib):
                    raise DependencyException(f'Got a libtools specific "{lib}" dependencies'
                                              'but we could not compute the actual shared'
                                              'library path')
                self.is_libtool = True
                lib = shared_lib
                if lib in link_args:
                    continue
            link_args.append(lib)
        # Add all -Lbar args if we have -lfoo args in link_args
        if libs_notfound:
            # Order of -L flags doesn't matter with ld, but it might with other
            # linkers such as MSVC, so prepend them.
            link_args = ['-L' + lp for lp in prefix_libpaths] + link_args
        return link_args, raw_link_args
def _search_libs ( self , out : str , out_raw : str ) -> T . Tuple [ T . List [ str ] , T . List [ str ] ] : # Library paths should be safe to de-dup # # First, figure out what library paths to use. Originally, we were # doing this as part of the loop, but due to differences in the order # of -L values between pkg-config and pkgconf, we need to do that as # a separate step. See: # https://github.com/mesonbuild/meson/issues/3951 # https://github.com/mesonbuild/meson/issues/4023 # # Separate system and prefix paths, and ensure that prefix paths are # always searched first. prefix_libpaths : OrderedSet [ str ] = OrderedSet ( ) # We also store this raw_link_args on the object later raw_link_args = self . _convert_mingw_paths ( self . _split_args ( out_raw ) ) for arg in raw_link_args : if arg . startswith ( '-L' ) and not arg . startswith ( ( '-L-l' , '-L-L' ) ) : path = arg [ 2 : ] if not os . path . isabs ( path ) : # Resolve the path as a compiler in the build directory would path = os . path . join ( self . env . get_build_dir ( ) , path ) prefix_libpaths . add ( path ) # Library paths are not always ordered in a meaningful way # # Instead of relying on pkg-config or pkgconf to provide -L flags in a # specific order, we reorder library paths ourselves, according to th # order specified in PKG_CONFIG_PATH. See: # https://github.com/mesonbuild/meson/issues/4271 # # Only prefix_libpaths are reordered here because there should not be # too many system_libpaths to cause library version issues. pkg_config_path : T . List [ str ] = self . env . coredata . options [ OptionKey ( 'pkg_config_path' , machine = self . for_machine ) ] . value pkg_config_path = self . _convert_mingw_paths ( pkg_config_path ) prefix_libpaths = OrderedSet ( sort_libpaths ( list ( prefix_libpaths ) , pkg_config_path ) ) system_libpaths : OrderedSet [ str ] = OrderedSet ( ) full_args = self . _convert_mingw_paths ( self . _split_args ( out ) ) for arg in full_args : if arg . startswith ( ( '-L-l' , '-L-L' ) ) : # These are D language arguments, not library paths continue if arg . startswith ( '-L' ) and arg [ 2 : ] not in prefix_libpaths : system_libpaths . add ( arg [ 2 : ] ) # Use this re-ordered path list for library resolution libpaths = list ( prefix_libpaths ) + list ( system_libpaths ) # Track -lfoo libraries to avoid duplicate work libs_found : OrderedSet [ str ] = OrderedSet ( ) # Track not-found libraries to know whether to add library paths libs_notfound = [ ] # Generate link arguments for this library link_args = [ ] for lib in full_args : if lib . startswith ( ( '-L-l' , '-L-L' ) ) : # These are D language arguments, add them as-is pass elif lib . startswith ( '-L' ) : # We already handled library paths above continue elif lib . startswith ( '-l:' ) : # see: https://stackoverflow.com/questions/48532868/gcc-library-option-with-a-colon-llibevent-a # also : See the documentation of -lnamespec | --library=namespec in the linker manual #                     https://sourceware.org/binutils/docs-2.18/ld/Options.html # Don't resolve the same -l:libfoo.a argument again if lib in libs_found : continue libfilename = lib [ 3 : ] foundname = None for libdir in libpaths : target = os . path . join ( libdir , libfilename ) if os . path . exists ( target ) : foundname = target break if foundname is None : if lib in libs_notfound : continue else : mlog . warning ( 'Library {!r} not found for dependency {!r}, may ' 'not be successfully linked' . format ( libfilename , self . name ) ) libs_notfound . append ( lib ) else : lib = foundname elif lib . startswith ( '-l' ) : # Don't resolve the same -lfoo argument again if lib in libs_found : continue if self . clib_compiler : args = self . clib_compiler . find_library ( lib [ 2 : ] , self . env , libpaths , self . libtype ) # If the project only uses a non-clib language such as D, Rust, # C#, Python, etc, all we can do is limp along by adding the # arguments as-is and then adding the libpaths at the end. else : args = None if args is not None : libs_found . add ( lib ) # Replace -l arg with full path to library if available # else, library is either to be ignored, or is provided by # the compiler, can't be resolved, and should be used as-is if args : if not args [ 0 ] . startswith ( '-l' ) : lib = args [ 0 ] else : continue else : # Library wasn't found, maybe we're looking in the wrong # places or the library will be provided with LDFLAGS or # LIBRARY_PATH from the environment (on macOS), and many # other edge cases that we can't account for. # # Add all -L paths and use it as -lfoo if lib in libs_notfound : continue if self . static : mlog . warning ( 'Static library {!r} not found for dependency {!r}, may ' 'not be statically linked' . format ( lib [ 2 : ] , self . name ) ) libs_notfound . append ( lib ) elif lib . endswith ( ".la" ) : shared_libname = self . extract_libtool_shlib ( lib ) shared_lib = os . path . join ( os . path . dirname ( lib ) , shared_libname ) if not os . path . exists ( shared_lib ) : shared_lib = os . path . join ( os . path . dirname ( lib ) , ".libs" , shared_libname ) if not os . path . exists ( shared_lib ) : raise DependencyException ( f'Got a libtools specific "{lib}" dependencies' 'but we could not compute the actual shared' 'library path' ) self . is_libtool = True lib = shared_lib if lib in link_args : continue link_args . append ( lib ) # Add all -Lbar args if we have -lfoo args in link_args if libs_notfound : # Order of -L flags doesn't matter with ld, but it might with other # linkers such as MSVC, so prepend them. link_args = [ '-L' + lp for lp in prefix_libpaths ] + link_args return link_args , raw_link_args