Overhaul versioning and naming of libraries

This commit contains several changes to the naming and versioning of
shared and static libraries. The details are documented at:
https://github.com/mesonbuild/meson/pull/417

Here's a brief summary:

* The results of binary and compiler detection via environment functions
  are now cached so that they can be called repeatedly without
  performance penalty. This is necessary because every
  build.SharedLibrary object has to know whether the compiler is MSVC or
  not (output filenames depend on that), and so the compiler detection
  has to be called for each object instantiation.

* Linux shared libraries don't always have a library version. Sometimes
  only soversions are specified (and vice-versa), so support both.

* Don't use versioned filenames when generating DLLs, DLLs are never
  versioned using the suffix in the way that .so libraries are. Hence,
  they don't use "aliases". Only Linux shared libraries use those.

* OS X dylibs do not use filename aliases at all. They only use the
  soversion in the dylib name (libfoo.X.dylib), and that's it. If
  there's no soversion specified, the dylib is called libfoo.dylib.
  Further versioning in dylibs is supposed to be done with the
  -current_version argument to clang, but this is TBD.

  https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html#//apple_ref/doc/uid/TP40002013-SW23

* Install DLLs into bindir and import libraries into libdir

* Static libraries are now always called libfoo.a, even with MSVC

* .lib import libraries are always generated when building with MSVC

* .dll.a import libraries are always generated when building with
  MinGW/GCC or MinGW/clang

* TODO: Use dlltool if available to generate .dll.a when .lib is
  generated and vice-versa.

* Library and executable suffix/prefixes are now always correctly
  overriden by the values of the 'name_prefix' and 'name_suffix' keyword
  arguments.
pull/417/head
Nirbheek Chauhan 9 years ago
parent bc347aed0b
commit 0143c32c7c
  1. 10
      mesonbuild/backend/backends.py
  2. 35
      mesonbuild/backend/ninjabackend.py
  3. 4
      mesonbuild/backend/vs2010backend.py
  4. 8
      mesonbuild/backend/xcodebackend.py
  5. 278
      mesonbuild/build.py
  6. 35
      mesonbuild/compilers.py
  7. 87
      mesonbuild/environment.py

@ -105,9 +105,13 @@ class Backend():
# On some platforms (msvc for instance), the file that is used for
# dynamic linking is not the same as the dynamic library itself. This
# file is called an import library, and we want to link against that.
# On platforms where this distinction is not important, the import
# library is the same as the dynamic library itself.
return os.path.join(self.get_target_dir(target), target.get_import_filename())
# On all other platforms, we link to the library directly.
if isinstance(target, build.SharedLibrary):
link_lib = target.get_import_filename() or target.get_filename()
return os.path.join(self.get_target_dir(target), link_lib)
elif isinstance(target, build.StaticLibrary):
return os.path.join(self.get_target_dir(target), target.get_filename())
raise AssertionError('BUG: Tried to link to something that\'s not a library')
def get_target_dir(self, target):
if self.environment.coredata.get_builtin_option('layout') == 'mirror':

@ -492,18 +492,33 @@ int dummy;
pickle.dump(d, ofile)
def generate_target_install(self, d):
libdir = self.environment.get_libdir()
bindir = self.environment.get_bindir()
should_strip = self.environment.coredata.get_builtin_option('strip')
for t in self.build.get_targets().values():
if t.should_install():
# Find the installation directory
outdir = t.get_custom_install_dir()
if outdir is None:
if isinstance(t, build.Executable):
outdir = bindir
else:
outdir = libdir
if outdir is not None:
pass
elif isinstance(t, build.SharedLibrary):
# For toolchains/platforms that need an import library for
# linking (separate from the shared library with all the
# code), we need to install the import library (dll.a/.lib)
if t.get_import_filename():
# Install the import library.
i = [self.get_target_filename_for_linking(t),
self.environment.get_import_lib_dir(),
# It has no aliases, should not be stripped, and
# doesn't have an install_rpath
[], False, '']
d.targets.append(i)
outdir = self.environment.get_shared_lib_dir()
elif isinstance(t, build.SharedLibrary):
outdir = self.environment.get_static_lib_dir()
elif isinstance(t, build.Executable):
outdir = self.environment.get_bindir()
else:
# XXX: Add BuildTarget-specific install dir cases here
outdir = self.environment.get_libdir()
i = [self.get_target_filename(t), outdir, t.get_aliaslist(),\
should_strip, t.install_rpath]
d.targets.append(i)
@ -1661,8 +1676,12 @@ rule FORTRAN_DEP_HACK
else:
soversion = None
commands += linker.get_soname_args(target.name, abspath, soversion)
# This is only visited when using the Visual Studio toolchain
if target.vs_module_defs and hasattr(linker, 'gen_vs_module_defs_args'):
commands += linker.gen_vs_module_defs_args(target.vs_module_defs.rel_to_builddir(self.build_to_src))
# This is only visited when building for Windows using either MinGW/GCC or Visual Studio
if target.import_filename:
commands += linker.gen_import_library_args(os.path.join(target.subdir, target.import_filename))
elif isinstance(target, build.StaticLibrary):
commands += linker.get_std_link_args()
else:

@ -585,7 +585,7 @@ class Vs2010Backend(backends.Backend):
for t in target.get_dependencies():
lobj = self.build.targets[t.get_id()]
rel_path = self.relpath(lobj.subdir, target.subdir)
linkname = os.path.join(rel_path, lobj.get_import_filename())
linkname = os.path.join(rel_path, self.get_target_filename_for_linking(lobj))
additional_links.append(linkname)
for lib in self.get_custom_target_provided_libraries(target):
additional_links.append(self.relpath(lib, self.get_target_dir(target)))
@ -607,6 +607,8 @@ class Vs2010Backend(backends.Backend):
gendeb = ET.SubElement(link, 'GenerateDebugInformation')
gendeb.text = 'true'
if isinstance(target, build.SharedLibrary):
# DLLs built with MSVC always have an import library except when
# they're data-only DLLs, but we don't support those yet.
ET.SubElement(link, 'ImportLibrary').text = target.get_import_filename()
pdb = ET.SubElement(link, 'ProgramDataBaseFileName')
pdb.text = '$(OutDir}%s.pdb' % target_name

@ -292,12 +292,10 @@ class XCodeBackend(backends.Backend):
reftype = 0
if isinstance(t, build.Executable):
typestr = 'compiled.mach-o.executable'
path = t.get_filename()
path = fname
elif isinstance(t, build.SharedLibrary):
# OSX has a completely different shared library
# naming scheme so do this manually.
typestr = self.get_xcodetype('dummy.dylib')
path = t.get_osx_filename()
path = fname
else:
typestr = self.get_xcodetype(fname)
path = '"%s"' % t.get_filename()
@ -626,7 +624,7 @@ class XCodeBackend(backends.Backend):
headerdirs.append(os.path.join(self.environment.get_build_dir(), cd))
for l in target.link_targets:
abs_path = os.path.join(self.environment.get_build_dir(),
l.subdir, buildtype, l.get_osx_filename())
l.subdir, buildtype, l.get_filename())
dep_libs.append("'%s'" % abs_path)
if isinstance(l, build.SharedLibrary):
links_dylib = True

@ -16,8 +16,9 @@ from . import coredata
from . import environment
from . import dependencies
from . import mlog
import copy, os
import copy, os, re
from .mesonlib import File, flatten, MesonException
from .environment import for_windows, for_darwin
known_basic_kwargs = {'install' : True,
'c_pch' : True,
@ -71,6 +72,35 @@ We are fully aware that these are not really usable or pleasant ways to do
this but it's the best we can do given the way shell quoting works.
'''
def sources_are_suffix(sources, suffix):
return len(sources) > 0 and sources[0].endswith('.' + suffix)
def compiler_is_msvc(sources, is_cross, env):
"""
Since each target does not currently have the compiler information attached
to it, we must do this detection manually here.
This detection is purposely incomplete and will cause bugs if other code is
extended and this piece of code is forgotten.
"""
compiler = None
if sources_are_suffix(sources, 'c'):
try:
compiler = env.detect_c_compiler(is_cross)
except MesonException:
return False
elif sources_are_suffix(sources, 'cxx') or \
sources_are_suffix(sources, 'cpp') or \
sources_are_suffix(sources, 'cc'):
try:
compiler = env.detect_cpp_compiler(is_cross)
except MesonException:
return False
if compiler and compiler.get_id() == 'msvc' and compiler.can_compile(sources[0]):
return True
return False
class InvalidArguments(MesonException):
pass
@ -670,15 +700,19 @@ class GeneratedList():
class Executable(BuildTarget):
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
self.prefix = ''
self.suffix = environment.get_exe_suffix()
suffix = environment.get_exe_suffix()
if len(self.sources) > 0 and self.sources[0].endswith('.cs'):
suffix = 'exe'
if suffix != '':
self.filename = self.name + '.' + suffix
else:
self.filename = self.name
# Unless overriden, executables have no suffix or prefix. Except on
# Windows and with C#/Mono executables where the suffix is 'exe'
if not hasattr(self, 'prefix'):
self.prefix = ''
if not hasattr(self, 'suffix'):
# Executable for Windows or C#/Mono
if for_windows(is_cross, environment) or sources_are_suffix(self.sources, 'cs'):
self.suffix = 'exe'
else:
self.suffix = ''
self.filename = self.name
if self.suffix:
self.filename += '.' + self.suffix
def type_suffix(self):
return "@exe"
@ -686,52 +720,161 @@ class Executable(BuildTarget):
class StaticLibrary(BuildTarget):
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
if len(self.sources) > 0 and self.sources[0].endswith('.cs'):
if sources_are_suffix(self.sources, 'cs'):
raise InvalidArguments('Static libraries not supported for C#.')
# By default a static library is named libfoo.a even on Windows because
# MSVC does not have a consistent convention for what static libraries
# are called. The MSVC CRT uses libfoo.lib syntax but nothing else uses
# it and GCC only looks for static libraries called foo.lib and
# libfoo.a. However, we cannot use foo.lib because that's the same as
# the import library. Using libfoo.a is ok because people using MSVC
# always pass the library filename while linking anyway.
if not hasattr(self, 'prefix'):
self.prefix = environment.get_static_lib_prefix()
self.suffix = environment.get_static_lib_suffix()
if len(self.sources) > 0 and self.sources[0].endswith('.rs'):
self.suffix = 'rlib'
self.prefix = 'lib'
if not hasattr(self, 'suffix'):
# Rust static library crates have .rlib suffix
if sources_are_suffix(self.sources, 'rs'):
self.suffix = 'rlib'
else:
self.suffix = 'a'
self.filename = self.prefix + self.name + '.' + self.suffix
def get_import_filename(self):
return self.filename
def get_osx_filename(self):
return self.get_filename()
def type_suffix(self):
return "@sta"
class SharedLibrary(BuildTarget):
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
self.version = None
self.soversion = None
self.ltversion = None
self.vs_module_defs = None
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs);
if len(self.sources) > 0 and self.sources[0].endswith('.cs'):
# The import library this target will generate
self.import_filename = None
# The import library that Visual Studio would generate (and accept)
self.vs_import_filename = None
# The import library that GCC would generate (and prefer)
self.gcc_import_filename = None
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
if not hasattr(self, 'prefix'):
self.prefix = None
if not hasattr(self, 'suffix'):
self.suffix = None
self.basic_filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
self.determine_filenames(is_cross, environment)
def determine_filenames(self, is_cross, env):
"""
See https://github.com/mesonbuild/meson/pull/417 for details.
First we determine the filename template (self.filename_tpl), then we
set the output filename (self.filename).
The template is needed while creating aliases (self.get_aliaslist),
which are needed while generating .so shared libraries for Linux.
Besides this, there's also the import library name, which is only used
on Windows since on that platform the linker uses a separate library
called the "import library" during linking instead of the shared
library (DLL). The toolchain will output an import library in one of
two formats: GCC or Visual Studio.
When we're building with Visual Studio, the import library that will be
generated by the toolchain is self.vs_import_filename, and with
MinGW/GCC, it's self.gcc_import_filename. self.import_filename will
always contain the import library name this target will generate.
"""
prefix = ''
suffix = ''
self.filename_tpl = self.basic_filename_tpl
# If the user already provided the prefix and suffix to us, we don't
# need to do any filename suffix/prefix detection.
# NOTE: manual prefix/suffix override is currently only tested for C/C++
if self.prefix != None and self.suffix != None:
pass
# C# and Mono
elif sources_are_suffix(self.sources, 'cs'):
prefix = ''
suffix = 'dll'
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
# Rust
elif sources_are_suffix(self.sources, 'rs'):
# Currently, we always build --crate-type=rlib
prefix = 'lib'
suffix = 'rlib'
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
# C, C++, Swift, Vala
# Only Windows uses a separate import library for linking
# For all other targets/platforms import_filename stays None
elif for_windows(is_cross, env):
suffix = 'dll'
self.vs_import_filename = '{0}.lib'.format(self.name)
self.gcc_import_filename = 'lib{0}.dll.a'.format(self.name)
if compiler_is_msvc(self.sources, is_cross, env):
# Shared library is of the form foo.dll
prefix = ''
# Import library is called foo.lib
self.import_filename = self.vs_import_filename
# Assume GCC-compatible naming
else:
# Shared library is of the form libfoo.dll
prefix = 'lib'
# Import library is called libfoo.dll.a
self.import_filename = self.gcc_import_filename
# Shared library has the soversion if it is defined
if self.soversion:
self.filename_tpl = '{0.prefix}{0.name}-{0.soversion}.{0.suffix}'
else:
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
elif for_darwin(is_cross, env):
prefix = 'lib'
suffix = 'dylib'
if self.soversion:
# libfoo.X.dylib
self.filename_tpl = '{0.prefix}{0.name}.{0.soversion}.{0.suffix}'
else:
# libfoo.dylib
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
else:
prefix = environment.get_shared_lib_prefix()
suffix = environment.get_shared_lib_suffix()
if not hasattr(self, 'prefix'):
self.prefix = prefix
if not hasattr(self, 'suffix'):
if len(self.sources) > 0 and self.sources[0].endswith('.rs'):
self.suffix = 'rlib'
prefix = 'lib'
suffix = 'so'
if self.ltversion:
# libfoo.so.X[.Y[.Z]] (.Y and .Z are optional)
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}.{0.ltversion}'
elif self.soversion:
# libfoo.so.X
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}.{0.soversion}'
else:
self.suffix = suffix
self.importsuffix = environment.get_import_lib_suffix()
self.filename = self.prefix + self.name + '.' + self.suffix
# No versioning, libfoo.so
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
if self.prefix == None:
self.prefix = prefix
if self.suffix == None:
self.suffix = suffix
self.filename = self.filename_tpl.format(self)
def process_kwargs(self, kwargs, environment):
super().process_kwargs(kwargs, environment)
# Shared library version
if 'version' in kwargs:
self.set_version(kwargs['version'])
self.ltversion = kwargs['version']
if not isinstance(self.ltversion, str):
raise InvalidArguments('Shared library version needs to be a string, not ' + type(self.ltversion).__name__)
if not re.fullmatch(r'[0-9]+(\.[0-9]+){0,2}', self.ltversion):
raise InvalidArguments('Invalid Shared library version "{0}". Must be of the form X.Y.Z where all three are numbers. Y and Z are optional.'.format(self.ltversion))
# Try to extract/deduce the soversion
if 'soversion' in kwargs:
self.set_soversion(kwargs['soversion'])
self.soversion = kwargs['soversion']
if isinstance(self.soversion, int):
self.soversion = str(self.soversion)
if not isinstance(self.soversion, str):
raise InvalidArguments('Shared library soversion is not a string or integer.')
try:
int(self.soversion)
except ValueError:
raise InvalidArguments('Shared library soversion must be a valid integer')
elif self.ltversion:
# library version is defined, get the soversion from that
self.soversion = self.ltversion.split('.')[0]
# Visual Studio module-definitions file
if 'vs_module_defs' in kwargs:
path = kwargs['vs_module_defs']
if (os.path.isabs(path)):
@ -742,46 +885,41 @@ class SharedLibrary(BuildTarget):
def check_unknown_kwargs(self, kwargs):
self.check_unknown_kwargs_int(kwargs, known_shlib_kwargs)
def get_shbase(self):
return self.prefix + self.name + '.' + self.suffix
def get_import_filename(self):
return self.prefix + self.name + '.' + self.importsuffix
"""
The name of the import library that will be outputted by the compiler
def get_all_link_deps(self):
return [self] + self.get_transitive_link_deps()
Returns None if there is no import library required for this platform
"""
return self.import_filename
def get_filename(self):
'''Works on all platforms except OSX, which does its own thing.'''
fname = self.get_shbase()
if self.version is None:
return fname
else:
return fname + '.' + self.version
def get_osx_filename(self):
if self.version is None:
return self.get_shbase()
return self.prefix + self.name + '.' + self.version + '.' + self.suffix
def set_version(self, version):
if not isinstance(version, str):
raise InvalidArguments('Shared library version is not a string.')
self.version = version
def get_import_filenameslist(self):
if self.import_filename:
return [self.vs_import_filename, self.gcc_import_filename]
return []
def set_soversion(self, version):
if isinstance(version, int):
version = str(version)
if not isinstance(version, str):
raise InvalidArguments('Shared library soversion is not a string or integer.')
self.soversion = version
def get_all_link_deps(self):
return [self] + self.get_transitive_link_deps()
def get_aliaslist(self):
aliases = []
if self.soversion is not None:
aliases.append(self.get_shbase() + '.' + self.soversion)
if self.version is not None:
aliases.append(self.get_shbase())
"""
If the versioned library name is libfoo.so.0.100.0, aliases are:
* libfoo.so.0 (soversion)
* libfoo.so (unversioned; for linking)
"""
# Aliases are only useful with .so libraries. Also if the .so library
# ends with .so (no versioning), we don't need aliases.
if self.suffix != 'so' or self.filename.endswith('.so'):
return []
# Unversioned alias: libfoo.so
aliases = [self.basic_filename_tpl.format(self)]
# If ltversion != soversion we create an soversion alias: libfoo.so.X
if self.ltversion and self.ltversion != self.soversion:
if not self.soversion:
# This is done in self.process_kwargs()
raise AssertionError('BUG: If library version is defined, soversion must have been defined')
alias_tpl = self.filename_tpl.replace('ltversion', 'soversion')
aliases.append(alias_tpl.format(self))
return aliases
def type_suffix(self):

@ -263,6 +263,13 @@ class Compiler():
def get_linker_always_args(self):
return []
def gen_import_library_args(self, implibname):
"""
Used only on Windows for libraries that need an import library.
This currently means C, C++, Fortran.
"""
return []
def get_options(self):
return {} # build afresh every time
@ -459,6 +466,14 @@ class CCompiler(Compiler):
def get_linker_search_args(self, dirname):
return ['-L'+dirname]
def gen_import_library_args(self, implibname):
"""
The name of the outputted import library
This implementation is used only on Windows by compilers that use GNU ld
"""
return ['-Wl,--out-implib=' + implibname]
def sanity_check_impl(self, work_dir, environment, sname, code):
mlog.debug('Sanity testing ' + self.language + ' compiler:', ' '.join(self.exelist))
mlog.debug('Is cross compiler: %s.' % str(self.is_cross))
@ -1485,6 +1500,10 @@ class VisualStudioCCompiler(CCompiler):
objname = os.path.splitext(pchname)[0] + '.obj'
return (objname, ['/Yc' + header, '/Fp' + pchname, '/Fo' + objname ])
def gen_import_library_args(self, implibname):
"The name of the outputted import library"
return ['/IMPLIB:' + implibname]
def build_rpath_args(self, build_dir, rpath_paths, install_rpath):
return []
@ -2031,6 +2050,14 @@ class GnuFortranCompiler(FortranCompiler):
def get_always_args(self):
return ['-pipe']
def gen_import_library_args(self, implibname):
"""
The name of the outputted import library
Used only on Windows
"""
return ['-Wl,--out-implib=' + implibname]
class G95FortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
@ -2042,6 +2069,14 @@ class G95FortranCompiler(FortranCompiler):
def get_always_args(self):
return ['-pipe']
def gen_import_library_args(self, implibname):
"""
The name of the outputted import library
Used only on Windows
"""
return ['-Wl,--out-implib=' + implibname]
class SunFortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)

@ -80,11 +80,37 @@ def detect_system():
return platform.system().lower()
def for_windows(is_cross, env):
"""
Host machine is windows?
Note: 'host' is the machine on which compiled binaries will run
"""
if not is_cross:
return mesonlib.is_windows()
elif env.cross_info.has_host():
return env.cross_info.config['host_machine']['system'] == 'windows'
return False
def for_darwin(is_cross, env):
"""
Host machine is Darwin (iOS/OS X)?
Note: 'host' is the machine on which compiled binaries will run
"""
if not is_cross:
return mesonlib.is_osx()
elif env.cross_info.has_host():
return env.cross_info.config['host_machine']['system'] == 'darwin'
return False
class Environment():
private_dir = 'meson-private'
log_dir = 'meson-logs'
coredata_file = os.path.join(private_dir, 'coredata.dat')
version_regex = '\d+(\.\d+)+(-[a-zA-Z0-9]+)?'
def __init__(self, source_dir, build_dir, main_script_file, options, original_cmd_line_args):
assert(os.path.isabs(main_script_file))
assert(not os.path.islink(main_script_file))
@ -122,33 +148,22 @@ class Environment():
self.default_static_linker = 'ar'
self.vs_static_linker = 'lib'
# Various prefixes and suffixes for import libraries, shared libraries,
# static libraries, and executables.
# Versioning is added to these names in the backends as-needed.
cross = self.is_cross_build()
if (not cross and mesonlib.is_windows()) \
or (cross and self.cross_info.has_host() and self.cross_info.config['host_machine']['system'] == 'windows'):
self.exe_suffix = 'exe'
if self.detect_c_compiler(cross).get_id() == 'msvc':
self.import_lib_suffix = 'lib'
else:
# MinGW-GCC doesn't generate and can't link with a .lib
# It uses the DLL file as the import library
self.import_lib_suffix = 'dll'
self.shared_lib_suffix = 'dll'
self.shared_lib_prefix = ''
self.static_lib_suffix = 'lib'
self.static_lib_prefix = ''
self.object_suffix = 'obj'
self.shared_lib_dir = self.get_bindir()
else:
self.exe_suffix = ''
if (not cross and mesonlib.is_osx()) or \
(cross and self.cross_info.has_host() and self.cross_info.config['host_machine']['system'] == 'darwin'):
self.shared_lib_suffix = 'dylib'
else:
self.shared_lib_suffix = 'so'
self.shared_lib_prefix = 'lib'
self.static_lib_suffix = 'a'
self.static_lib_prefix = 'lib'
self.object_suffix = 'o'
self.import_lib_suffix = self.shared_lib_suffix
self.shared_lib_dir = self.get_libdir()
# Common to all platforms
self.import_lib_dir = self.get_libdir()
self.static_lib_dir = self.get_libdir()
def is_cross_build(self):
return self.cross_info is not None
@ -641,22 +656,17 @@ class Environment():
def get_exe_suffix(self):
return self.exe_suffix
# On Windows (MSVC) the library has suffix dll
# but you link against a file that has suffix lib.
def get_import_lib_suffix(self):
return self.import_lib_suffix
def get_import_lib_dir(self):
"Install dir for the import library (library used for linking)"
return self.import_lib_dir
def get_shared_lib_prefix(self):
return self.shared_lib_prefix
def get_shared_lib_dir(self):
"Install dir for the shared library"
return self.shared_lib_dir
def get_shared_lib_suffix(self):
return self.shared_lib_suffix
def get_static_lib_prefix(self):
return self.static_lib_prefix
def get_static_lib_suffix(self):
return self.static_lib_suffix
def get_static_lib_dir(self):
"Install dir for the static library"
return self.static_lib_dir
def get_object_suffix(self):
return self.object_suffix
@ -682,17 +692,6 @@ class Environment():
def get_datadir(self):
return self.coredata.get_builtin_option('datadir')
def find_library(self, libname, dirs):
if dirs is None:
dirs = mesonlib.get_library_dirs()
suffixes = [self.get_shared_lib_suffix(), self.get_static_lib_suffix()]
prefix = self.get_shared_lib_prefix()
for d in dirs:
for suffix in suffixes:
trial = os.path.join(d, prefix + libname + '.' + suffix)
if os.path.isfile(trial):
return trial
def get_args_from_envvars(lang):
if lang == 'c':

Loading…
Cancel
Save