summaryrefslogtreecommitdiff
path: root/run_unittests.py
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2018-07-25 12:59:41 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2018-09-14 20:32:56 +0530
commit2d370c24ec83de889c83511c4a32e52e75a38aca (patch)
tree76db4b8adfb9f969b4f28cb2211e617389394486 /run_unittests.py
parent3f51745b414d027785666aa6790aff1bdb36b3c8 (diff)
downloadmeson-nirbheek/fix-internal-lib-static-linking.tar.gz
Fix linking of shared/static libs with static libsnirbheek/fix-internal-lib-static-linking
This commit contains the following fixes: 1. When a shared library A does `link_with:` to static library B, the parts of B used by A will be added to A, and so we don't need to return B in A.get_dependencies() for targets that link to A. This already is the behaviour when a shared library A does `link_whole:` on B. 2. In situation (1), when generating a pkg-config file for A, we must also not add B to Libs.private for A. This already is the behaviour when a shared library A does `link_whole:` on B. 3. When a static library A does `link_whole:` to static library B, we must add the objects in B to A. 4. When a static library A does `link_with:` to static library B, and B is not installed (which makes it an internal static library), we must add the objects in B to A, otherwise nothing can use A. 5. In situation (4), when generating a pkg-config file for A, we must also not add B to Libs.private for A. All these situations are tested by the unit test added in this commit. Closes https://github.com/mesonbuild/meson/issues/3934 Closes https://github.com/mesonbuild/meson/issues/3937
Diffstat (limited to 'run_unittests.py')
-rwxr-xr-xrun_unittests.py85
1 files changed, 84 insertions, 1 deletions
diff --git a/run_unittests.py b/run_unittests.py
index 96802cc8c..87518a8e9 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -96,6 +96,14 @@ def _git_init(project_dir):
subprocess.check_call(['git', 'commit', '-a', '-m', 'I am a project'], cwd=project_dir,
stdout=subprocess.DEVNULL)
+def can_use_pkgconfig():
+ # CI provides pkg-config, and we should fail the test if it isn't found
+ if is_ci():
+ return True
+ if shutil.which('pkg-config'):
+ return True
+ return False
+
def skipIfNoPkgconfig(f):
'''
Skip this test if no pkg-config is found, unless we're on Travis or
@@ -106,7 +114,7 @@ def skipIfNoPkgconfig(f):
Note: Yes, we provide pkg-config even while running Windows CI
'''
def wrapped(*args, **kwargs):
- if not is_ci() and shutil.which('pkg-config') is None:
+ if not can_use_pkgconfig():
raise unittest.SkipTest('pkg-config not found')
return f(*args, **kwargs)
return wrapped
@@ -2744,6 +2752,81 @@ recommended as it is not supported on some platforms''')
self.assertEqual(opts['debug'], True)
self.assertEqual(opts['optimization'], '0')
+ def test_static_and_shared_library_usability(self):
+ '''
+ Test that static and shared libraries with various kinds of static
+ library internal dependencies are usable after installation, and that
+ the pkg-config files generated for such libraries have the correct
+ Libs: and Libs.private: lines.
+ '''
+ env = get_fake_env('', self.builddir, self.prefix)
+ cc = env.detect_c_compiler(False)
+ if cc.get_id() == 'msvc':
+ static_args = '-DPROVIDER_STATIC'
+ # FIXME: Can't reliably test mixed shared/static because of
+ # __declspec linkage issues and because it will greatly complicate
+ # the build files. Waiting for static_c_args support.
+ libtypes = ('static',)
+ else:
+ static_args = ''
+ libtypes = ('static', 'shared', 'both')
+ # Test
+ for libtype in libtypes:
+ oldprefix = self.prefix
+ # Install external library so we can find it
+ testdir = os.path.join(self.unit_test_dir, '35 both library usability', 'provider')
+ # install into installdir without using DESTDIR
+ installdir = self.installdir
+ self.prefix = installdir
+ if libtype == 'static':
+ c_args = static_args
+ else:
+ c_args = ''
+ self.init(testdir, extra_args=['--default-library=' + libtype, '-Dc_args=' + c_args])
+ self.prefix = oldprefix
+ for each in ('whole-installed', 'whole-internal', 'with-installed', 'with-internal'):
+ pc = os.path.join(self.privatedir, '{}.pc'.format(each))
+ with open(pc, 'r') as f:
+ for l in f:
+ l = l.strip()
+ if l.startswith('Libs:'):
+ if libtype == 'static' and each == 'with-installed':
+ self.assertEqual(l, 'Libs: -L${libdir} -linstalled-some -l' + each)
+ else:
+ self.assertEqual(l, 'Libs: -L${libdir} -l' + each)
+ if l.startswith('Libs.private:'):
+ if each == 'with-installed':
+ self.assertEqual(l, 'Libs.private: -L${libdir} -linstalled-some')
+ else:
+ self.assertNotIn('internal-some', l)
+ self.build()
+ self.run_tests()
+ # Rest of the test requires pkg-config
+ if not can_use_pkgconfig():
+ ## New builddir for the next iteration
+ self.new_builddir()
+ continue
+ self.install(use_destdir=False)
+ if is_windows() or is_cygwin():
+ os.environ['PATH'] += os.pathsep + os.path.join(installdir, 'bin')
+ os.environ['PKG_CONFIG_PATH'] = os.path.join(installdir, self.libdir, 'pkgconfig')
+ testdir = os.path.join(self.unit_test_dir, '35 both library usability', 'consumer')
+ for _libtype in libtypes:
+ if _libtype == 'static':
+ _c_args = static_args
+ else:
+ _c_args = ''
+ ## New builddir for the consumer
+ self.new_builddir()
+ self.init(testdir, extra_args=['--default-library=' + _libtype, '-Dc_args=' + _c_args])
+ self.build()
+ self.run_tests()
+ ## New builddir for the next iteration
+ self.new_builddir()
+ # Deliver a skip status to signal incomplete test
+ if not can_use_pkgconfig():
+ raise unittest.SkipTest('pkg-config not found, test incomplete')
+
class FailureTests(BasePlatformTests):
'''