Skip to content

Commit

Permalink
Fix *.pdb files missing in meson introspect --installed output
Browse files Browse the repository at this point in the history
On Windows, make sure the introspect command lists all Program database
(PDB) files containing debugging information that Meson will install.
  • Loading branch information
xhaakon committed Oct 9, 2019
1 parent 217036f commit 1bf1782
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 22 deletions.
41 changes: 25 additions & 16 deletions mesonbuild/backend/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -1091,22 +1091,31 @@ def generate_target_install(self, d):
t.get_aliases(), should_strip, mappings,
t.install_rpath, install_mode)
d.targets.append(i)
# On toolchains/platforms that use an import library for
# linking (separate from the shared library with all the
# code), we need to install that too (dll.a/.lib).
if isinstance(t, (build.SharedLibrary, build.SharedModule, build.Executable)) and t.get_import_filename():
if custom_install_dir:
# If the DLL is installed into a custom directory,
# install the import library into the same place so
# it doesn't go into a surprising place
implib_install_dir = outdirs[0]
else:
implib_install_dir = self.environment.get_import_lib_dir()
# Install the import library; may not exist for shared modules
i = TargetInstallData(self.get_target_filename_for_linking(t),
implib_install_dir, {}, False, {}, '', install_mode,
optional=isinstance(t, build.SharedModule))
d.targets.append(i)

if isinstance(t, (build.SharedLibrary, build.SharedModule, build.Executable)):
# On toolchains/platforms that use an import library for
# linking (separate from the shared library with all the
# code), we need to install that too (dll.a/.lib).
if t.get_import_filename():
if custom_install_dir:
# If the DLL is installed into a custom directory,
# install the import library into the same place so
# it doesn't go into a surprising place
implib_install_dir = outdirs[0]
else:
implib_install_dir = self.environment.get_import_lib_dir()
# Install the import library; may not exist for shared modules
i = TargetInstallData(self.get_target_filename_for_linking(t),
implib_install_dir, {}, False, {}, '', install_mode,
optional=isinstance(t, build.SharedModule))
d.targets.append(i)

if not should_strip and t.get_debug_filename():
debug_file = os.path.join(self.get_target_dir(t), t.get_debug_filename())
i = TargetInstallData(debug_file, outdirs[0],
{}, False, {}, '',
install_mode, optional=True)
d.targets.append(i)
# Install secondary outputs. Only used for Vala right now.
if num_outdirs > 1:
for output, outdir in zip(t.get_outputs()[1:], outdirs[1:]):
Expand Down
34 changes: 33 additions & 1 deletion mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,8 @@ def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources
self.vs_import_filename = None
# The import library that GCC would generate (and prefer)
self.gcc_import_filename = None
# The debugging information file this target will generate
self.debug_filename = None

# Check for export_dynamic
self.export_dynamic = False
Expand All @@ -1500,12 +1502,13 @@ def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources
if self.export_dynamic and kwargs.get('implib') is False:
raise InvalidArguments('"implib" keyword argument must not be false for if "export_dynamic" is true')

m = environment.machines[for_machine]

# If using export_dynamic, set the import library name
if self.export_dynamic:
implib_basename = self.name + '.exe'
if not isinstance(kwargs.get('implib', False), bool):
implib_basename = kwargs['implib']
m = environment.machines[for_machine]
if m.is_windows() or m.is_cygwin():
self.vs_import_filename = '{0}.lib'.format(implib_basename)
self.gcc_import_filename = 'lib{0}.a'.format(implib_basename)
Expand All @@ -1514,6 +1517,11 @@ def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources
else:
self.import_filename = self.gcc_import_filename

if m.is_windows() and ('cs' in self.compilers or
self.get_using_rustc() or
self.get_using_msvc()):
self.debug_filename = self.name + '.pdb'

# Only linkwithable if using export_dynamic
self.is_linkwithable = self.export_dynamic

Expand All @@ -1540,6 +1548,14 @@ def get_import_filenameslist(self):
return [self.vs_import_filename, self.gcc_import_filename]
return []

def get_debug_filename(self):
"""
The name of debuginfo file that will be created by the compiler
Returns None if the build won't create any debuginfo file
"""
return self.debug_filename

def is_linkable_target(self):
return self.is_linkwithable

Expand Down Expand Up @@ -1619,6 +1635,8 @@ def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources
self.vs_import_filename = None
# The import library that GCC would generate (and prefer)
self.gcc_import_filename = None
# The debugging information file this target will generate
self.debug_filename = None
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
if 'rust' in self.compilers:
# If no crate type is specified, or it's the generic lib type, use dylib
Expand Down Expand Up @@ -1673,13 +1691,15 @@ def determine_filenames(self, env):
"""
prefix = ''
suffix = ''
create_debug_file = False
self.filename_tpl = self.basic_filename_tpl
# NOTE: manual prefix/suffix override is currently only tested for C/C++
# C# and Mono
if 'cs' in self.compilers:
prefix = ''
suffix = 'dll'
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
create_debug_file = True
# C, C++, Swift, Vala
# Only Windows uses a separate import library for linking
# For all other targets/platforms import_filename stays None
Expand All @@ -1692,11 +1712,13 @@ def determine_filenames(self, env):
prefix = ''
# Import library is called foo.dll.lib
self.import_filename = '{0}.dll.lib'.format(self.name)
create_debug_file = True
elif self.get_using_msvc():
# Shared library is of the form foo.dll
prefix = ''
# Import library is called foo.lib
self.import_filename = self.vs_import_filename
create_debug_file = True
# Assume GCC-compatible naming
else:
# Shared library is of the form libfoo.dll
Expand Down Expand Up @@ -1753,6 +1775,8 @@ def determine_filenames(self, env):
self.suffix = suffix
self.filename = self.filename_tpl.format(self)
self.outputs = [self.filename]
if create_debug_file:
self.debug_filename = os.path.splitext(self.filename)[0] + '.pdb'

@staticmethod
def _validate_darwin_versions(darwin_versions):
Expand Down Expand Up @@ -1866,6 +1890,14 @@ def get_import_filename(self):
"""
return self.import_filename

def get_debug_filename(self):
"""
The name of debuginfo file that will be created by the compiler
Returns None if the build won't create any debuginfo file
"""
return self.debug_filename

def get_import_filenameslist(self):
if self.import_filename:
return [self.vs_import_filename, self.gcc_import_filename]
Expand Down
5 changes: 0 additions & 5 deletions mesonbuild/minstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,11 +460,6 @@ def install_targets(self, d):
print('Stdout:\n%s\n' % stdo)
print('Stderr:\n%s\n' % stde)
sys.exit(1)
pdb_filename = os.path.splitext(fname)[0] + '.pdb'
if not should_strip and os.path.exists(pdb_filename):
pdb_outname = os.path.splitext(outname)[0] + '.pdb'
self.do_copyfile(pdb_filename, pdb_outname)
set_mode(pdb_outname, install_mode, d.install_umask)
if fname.endswith('.js'):
# Emscripten outputs js files and optionally a wasm file.
# If one was generated, install it as well.
Expand Down
14 changes: 14 additions & 0 deletions run_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4424,6 +4424,20 @@ def test_msvc_cpp17(self):
return
self.build()

def test_install_pdb_introspection(self):
testdir = os.path.join(self.platform_test_dir, '1 basic')

env = get_fake_env(testdir, self.builddir, self.prefix)
cc = env.detect_c_compiler(MachineChoice.HOST)
if cc.get_argument_syntax() != 'msvc':
raise unittest.SkipTest('Test only applies to MSVC-like compilers')

self.init(testdir)
installed = self.introspect('--installed')
files = [os.path.basename(path) for path in installed.values()]

self.assertTrue('prog.pdb' in files)

@unittest.skipUnless(is_osx(), "requires Darwin")
class DarwinTests(BasePlatformTests):
'''
Expand Down

0 comments on commit 1bf1782

Please sign in to comment.