From 1bf17824766230a8ad0b2fe56040ff860c841d50 Mon Sep 17 00:00:00 2001 From: Jakub Adam Date: Wed, 6 Mar 2019 15:45:14 +0100 Subject: [PATCH 1/2] Fix *.pdb files missing in meson introspect --installed output On Windows, make sure the introspect command lists all Program database (PDB) files containing debugging information that Meson will install. --- mesonbuild/backend/backends.py | 41 +++++++++++++++++++++------------- mesonbuild/build.py | 34 +++++++++++++++++++++++++++- mesonbuild/minstall.py | 5 ----- run_unittests.py | 14 ++++++++++++ 4 files changed, 72 insertions(+), 22 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 4d3f5d9b5..947be1cbe 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -1091,22 +1091,31 @@ class Backend: 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:]): diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 267bd1664..68fbd187e 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1488,6 +1488,8 @@ class Executable(BuildTarget): 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 @@ -1500,12 +1502,13 @@ class Executable(BuildTarget): 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) @@ -1514,6 +1517,11 @@ class Executable(BuildTarget): 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 @@ -1540,6 +1548,14 @@ class Executable(BuildTarget): 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 @@ -1619,6 +1635,8 @@ class SharedLibrary(BuildTarget): 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 @@ -1673,6 +1691,7 @@ class SharedLibrary(BuildTarget): """ 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 @@ -1680,6 +1699,7 @@ class SharedLibrary(BuildTarget): 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 @@ -1692,11 +1712,13 @@ class SharedLibrary(BuildTarget): 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 @@ -1753,6 +1775,8 @@ class SharedLibrary(BuildTarget): 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): @@ -1866,6 +1890,14 @@ class SharedLibrary(BuildTarget): """ 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] diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py index 731e093c2..9311e8d96 100644 --- a/mesonbuild/minstall.py +++ b/mesonbuild/minstall.py @@ -460,11 +460,6 @@ class Installer: 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. diff --git a/run_unittests.py b/run_unittests.py index 9f8f57608..45b888781 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -4424,6 +4424,20 @@ class WindowsTests(BasePlatformTests): 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): ''' From 9c456e2baf281682569ce89137148d7b5b3487f5 Mon Sep 17 00:00:00 2001 From: Jakub Adam Date: Mon, 9 Sep 2019 18:32:01 +0200 Subject: [PATCH 2/2] tests: Don't expect any *.pdb files installed in 'lib' Static libraries don't have PDB files. A PDB that would previously end up installed alongside a static library belonged in fact to the dynamic version of the same library built at the same time. This was because the former minstall.Installer implementation, when installing a file target, also blindly copied any *.pdb file it found whose filename was matching the target. So, for example installing foo.dll and foo.a would also install two copies of foo.pdb into both bin/ and lib/, which doesn't seem like the right thing to do - foo.pdb should only get installed with foo.dll. --- .../206 install name_prefix name_suffix/installed_files.txt | 3 --- test cases/d/5 mixed/installed_files.txt | 1 - test cases/windows/7 dll versioning/installed_files.txt | 1 - 3 files changed, 5 deletions(-) diff --git a/test cases/common/206 install name_prefix name_suffix/installed_files.txt b/test cases/common/206 install name_prefix name_suffix/installed_files.txt index 240a8be69..be6161168 100644 --- a/test cases/common/206 install name_prefix name_suffix/installed_files.txt +++ b/test cases/common/206 install name_prefix name_suffix/installed_files.txt @@ -1,9 +1,6 @@ ?msvc:usr/bin/baz.pdb ?msvc:usr/bin/bowcorge.pdb ?msvc:usr/bin/foo.pdb -?msvc:usr/lib/baz.pdb -?msvc:usr/lib/bowcorge.pdb -?msvc:usr/lib/foo.pdb usr/?lib/bowcorge.stern usr/lib/?libbaz.cheese usr/lib/bar.a diff --git a/test cases/d/5 mixed/installed_files.txt b/test cases/d/5 mixed/installed_files.txt index 5950753f7..46b7721f6 100644 --- a/test cases/d/5 mixed/installed_files.txt +++ b/test cases/d/5 mixed/installed_files.txt @@ -5,4 +5,3 @@ usr/lib/libstuff.a ?msvc:usr/bin/stuff.dll ?msvc:usr/bin/stuff.pdb ?msvc:usr/lib/stuff.lib -?msvc:usr/lib/stuff.pdb diff --git a/test cases/windows/7 dll versioning/installed_files.txt b/test cases/windows/7 dll versioning/installed_files.txt index 62b5c9a86..f3a1e2d98 100644 --- a/test cases/windows/7 dll versioning/installed_files.txt +++ b/test cases/windows/7 dll versioning/installed_files.txt @@ -4,7 +4,6 @@ ?msvc:usr/bin/noversion.dll ?msvc:usr/bin/noversion.pdb ?msvc:usr/lib/noversion.lib -?msvc:usr/lib/noversion.pdb ?msvc:usr/bin/onlyversion-1.dll ?msvc:usr/bin/onlyversion-1.pdb ?msvc:usr/lib/onlyversion.lib