dependencies: Add a test for static libs with pkg-config

Demonstrates that pkg-config does not prefer static libs over shared
libs even if we use the `static: true` kwarg.
pull/2610/head
Nirbheek Chauhan 7 years ago
parent 9e2d078948
commit 4405a1297b
  1. 126
      run_unittests.py
  2. 8
      test cases/unit/17 pkgconfig static/foo.c
  3. 10
      test cases/unit/17 pkgconfig static/foo.pc.in
  4. 3
      test cases/unit/17 pkgconfig static/include/foo.h
  5. 14
      test cases/unit/17 pkgconfig static/main.c
  6. 19
      test cases/unit/17 pkgconfig static/meson.build

@ -1342,34 +1342,31 @@ int main(int argc, char **argv) {
self.assertPathExists(os.path.join(testdir, i)) self.assertPathExists(os.path.join(testdir, i))
def detect_prebuild_env(self): def detect_prebuild_env(self):
env = Environment('', self.builddir, self.meson_command,
get_fake_options(self.prefix), [])
cc = env.detect_c_compiler(False)
if mesonbuild.mesonlib.is_windows(): if mesonbuild.mesonlib.is_windows():
object_suffix = 'obj' object_suffix = 'obj'
else:
object_suffix = 'o'
static_suffix = 'a'
shared_suffix = 'so'
if shutil.which('cl'):
compiler = 'cl'
static_suffix = 'lib'
shared_suffix = 'dll' shared_suffix = 'dll'
elif shutil.which('cc'): elif mesonbuild.mesonlib.is_osx():
compiler = 'cc' object_suffix = 'o'
elif shutil.which('gcc'): shared_suffix = 'dylib'
compiler = 'gcc'
else: else:
raise RuntimeError("Could not find C compiler.") object_suffix = 'o'
return (compiler, object_suffix, static_suffix, shared_suffix) shared_suffix = 'so'
return (cc, object_suffix, shared_suffix)
def pbcompile(self, compiler, source, objectfile, extra_args=[]): def pbcompile(self, compiler, source, objectfile, extra_args=[]):
if compiler == 'cl': cmd = compiler.get_exelist()
cmd = [compiler, '/nologo', '/Fo' + objectfile, '/c', source] + extra_args if compiler.id == 'msvc':
cmd += ['/nologo', '/Fo' + objectfile, '/c', source] + extra_args
else: else:
cmd = [compiler, '-c', source, '-o', objectfile] + extra_args cmd += ['-c', source, '-o', objectfile] + extra_args
subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def test_prebuilt_object(self): def test_prebuilt_object(self):
(compiler, object_suffix, _, _) = self.detect_prebuild_env() (compiler, object_suffix, _) = self.detect_prebuild_env()
tdir = os.path.join(self.unit_test_dir, '14 prebuilt object') tdir = os.path.join(self.unit_test_dir, '14 prebuilt object')
source = os.path.join(tdir, 'source.c') source = os.path.join(tdir, 'source.c')
objectfile = os.path.join(tdir, 'prebuilt.' + object_suffix) objectfile = os.path.join(tdir, 'prebuilt.' + object_suffix)
@ -1381,21 +1378,27 @@ int main(int argc, char **argv) {
finally: finally:
os.unlink(objectfile) os.unlink(objectfile)
def test_prebuilt_static_lib(self): def build_static_lib(self, compiler, source, objectfile, outfile, extra_args=None):
(compiler, object_suffix, static_suffix, _) = self.detect_prebuild_env() if extra_args is None:
tdir = os.path.join(self.unit_test_dir, '15 prebuilt static') extra_args = []
source = os.path.join(tdir, 'libdir/best.c') if compiler.id == 'msvc':
objectfile = os.path.join(tdir, 'libdir/best.' + object_suffix) link_cmd = ['lib', '/NOLOGO', '/OUT:' + outfile, objectfile]
stlibfile = os.path.join(tdir, 'libdir/libbest.' + static_suffix)
if compiler == 'cl':
link_cmd = ['lib', '/NOLOGO', '/OUT:' + stlibfile, objectfile]
else: else:
link_cmd = ['ar', 'csr', stlibfile, objectfile] link_cmd = ['ar', 'csr', outfile, objectfile]
self.pbcompile(compiler, source, objectfile) self.pbcompile(compiler, source, objectfile, extra_args=extra_args)
try: try:
subprocess.check_call(link_cmd) subprocess.check_call(link_cmd)
finally: finally:
os.unlink(objectfile) os.unlink(objectfile)
def test_prebuilt_static_lib(self):
(cc, object_suffix, _) = self.detect_prebuild_env()
tdir = os.path.join(self.unit_test_dir, '15 prebuilt static')
source = os.path.join(tdir, 'libdir/best.c')
objectfile = os.path.join(tdir, 'libdir/best.' + object_suffix)
stlibfile = os.path.join(tdir, 'libdir/libbest.a')
self.build_static_lib(cc, source, objectfile, stlibfile)
# Run the test
try: try:
self.init(tdir) self.init(tdir)
self.build() self.build()
@ -1403,26 +1406,35 @@ int main(int argc, char **argv) {
finally: finally:
os.unlink(stlibfile) os.unlink(stlibfile)
def test_prebuilt_shared_lib(self): def build_shared_lib(self, compiler, source, objectfile, outfile, impfile, extra_args=None):
(compiler, object_suffix, _, shared_suffix) = self.detect_prebuild_env() if extra_args is None:
tdir = os.path.join(self.unit_test_dir, '16 prebuilt shared')
source = os.path.join(tdir, 'alexandria.c')
objectfile = os.path.join(tdir, 'alexandria.' + object_suffix)
if compiler == 'cl':
extra_args = [] extra_args = []
shlibfile = os.path.join(tdir, 'alexandria.' + shared_suffix) if compiler.id == 'msvc':
link_cmd = ['link', '/NOLOGO','/DLL', '/DEBUG', '/IMPLIB:' + os.path.join(tdir, 'alexandria.lib'), '/OUT:' + shlibfile, objectfile] link_cmd = ['link', '/NOLOGO', '/DLL', '/DEBUG',
'/IMPLIB:' + impfile, '/OUT:' + outfile, objectfile]
else: else:
extra_args = ['-fPIC'] extra_args += ['-fPIC']
shlibfile = os.path.join(tdir, 'libalexandria.' + shared_suffix) link_cmd = compiler.get_exelist() + ['-shared', '-o', outfile, objectfile]
link_cmd = [compiler, '-shared', '-o', shlibfile, objectfile]
if not mesonbuild.mesonlib.is_osx(): if not mesonbuild.mesonlib.is_osx():
link_cmd += ['-Wl,-soname=libalexandria.so'] link_cmd += ['-Wl,-soname=' + os.path.basename(outfile)]
self.pbcompile(compiler, source, objectfile, extra_args=extra_args) self.pbcompile(compiler, source, objectfile, extra_args=extra_args)
try: try:
subprocess.check_call(link_cmd) subprocess.check_call(link_cmd)
finally: finally:
os.unlink(objectfile) os.unlink(objectfile)
def test_prebuilt_shared_lib(self):
(cc, object_suffix, shared_suffix) = self.detect_prebuild_env()
tdir = os.path.join(self.unit_test_dir, '16 prebuilt shared')
source = os.path.join(tdir, 'alexandria.c')
objectfile = os.path.join(tdir, 'alexandria.' + object_suffix)
impfile = os.path.join(tdir, 'alexandria.lib')
if cc.id == 'msvc':
shlibfile = os.path.join(tdir, 'alexandria.' + shared_suffix)
else:
shlibfile = os.path.join(tdir, 'libalexandria.' + shared_suffix)
self.build_shared_lib(cc, source, objectfile, shlibfile, impfile)
# Run the test
try: try:
self.init(tdir) self.init(tdir)
self.build() self.build()
@ -1436,6 +1448,42 @@ int main(int argc, char **argv) {
if os.path.splitext(fname)[1] not in ['.c', '.h']: if os.path.splitext(fname)[1] not in ['.c', '.h']:
os.unlink(fname) os.unlink(fname)
def test_pkgconfig_static(self):
'''
Test that the we only use static libraries when `static: true` is
passed to dependency() with pkg-config. Can't be an ordinary test
because we need to build libs and try to find them from meson.build
'''
(cc, objext, shext) = self.detect_prebuild_env()
testdir = os.path.join(self.unit_test_dir, '17 pkgconfig static')
source = os.path.join(testdir, 'foo.c')
objectfile = os.path.join(testdir, 'foo.' + objext)
stlibfile = os.path.join(testdir, 'libfoo.a')
impfile = os.path.join(testdir, 'foo.lib')
if cc.id == 'msvc':
shlibfile = os.path.join(testdir, 'foo.' + shext)
else:
shlibfile = os.path.join(testdir, 'libfoo.' + shext)
# Build libs
self.build_static_lib(cc, source, objectfile, stlibfile, extra_args=['-DFOO_STATIC'])
self.build_shared_lib(cc, source, objectfile, shlibfile, impfile)
# Run test
os.environ['PKG_CONFIG_LIBDIR'] = self.builddir
try:
self.init(testdir)
self.build()
self.run_tests()
finally:
os.unlink(stlibfile)
os.unlink(shlibfile)
if mesonbuild.mesonlib.is_windows():
# Clean up all the garbage MSVC writes in the
# source tree.
for fname in glob(os.path.join(testdir, 'foo.*')):
if os.path.splitext(fname)[1] not in ['.c', '.h', '.in']:
os.unlink(fname)
class FailureTests(BasePlatformTests): class FailureTests(BasePlatformTests):
''' '''
Tests that test failure conditions. Build files here should be dynamically Tests that test failure conditions. Build files here should be dynamically

@ -0,0 +1,8 @@
int power_level (void)
{
#ifdef FOO_STATIC
return 9001;
#else
return 8999;
#endif
}

@ -0,0 +1,10 @@
prefix=@PREFIX@
libdir=${prefix}
includedir=${prefix}/include
datadir=${prefix}/data
Name: libfoo
Description: A foo library.
Version: 1.0
Libs: -L${libdir} -lfoo
Cflags: -I${includedir}

@ -0,0 +1,3 @@
#pragma once
int power_level (void);

@ -0,0 +1,14 @@
#include <foo.h>
#include <stdio.h>
int
main (int argc, char * argv[])
{
int value = power_level ();
if (value < 9000) {
printf ("Power level is %i\n", value);
return 1;
}
printf ("IT'S OVER 9000!!!\n");
return 0;
}

@ -0,0 +1,19 @@
project('pkg-config static', 'c')
if build_machine.system() != 'windows'
prefix = meson.source_root()
else
# pkg-config files should not use paths with \
prefix_parts = meson.source_root().split('\\')
prefix = '/'.join(prefix_parts)
endif
conf = configuration_data()
conf.set('PREFIX', prefix)
configure_file(input : 'foo.pc.in',
output : 'foo.pc',
configuration : conf)
foo_dep = dependency('foo', static : true)
test('footest', executable('foomain', 'main.c', dependencies : foo_dep))
Loading…
Cancel
Save