compilers: Try harder to dedup builtin libs

Compiler internal libs should always be de-duplicated, no matter what.

Closes https://github.com/mesonbuild/meson/issues/2150

Test case is by Bruce Richardson in the issue.
pull/5271/head
Nirbheek Chauhan 6 years ago
parent 9b29fef07a
commit 8a2c2c9fca
  1. 7
      mesonbuild/compilers/c.py
  2. 8
      mesonbuild/compilers/compilers.py
  3. 15
      run_unittests.py
  4. 13
      test cases/unit/55 dedup compiler libs/app/app.c
  5. 2
      test cases/unit/55 dedup compiler libs/app/meson.build
  6. 18
      test cases/unit/55 dedup compiler libs/liba/liba.c
  7. 8
      test cases/unit/55 dedup compiler libs/liba/liba.h
  8. 8
      test cases/unit/55 dedup compiler libs/liba/meson.build
  9. 7
      test cases/unit/55 dedup compiler libs/libb/libb.c
  10. 6
      test cases/unit/55 dedup compiler libs/libb/libb.h
  11. 6
      test cases/unit/55 dedup compiler libs/libb/meson.build
  12. 7
      test cases/unit/55 dedup compiler libs/meson.build

@ -35,6 +35,7 @@ from .compilers import (
get_largefile_args,
gnu_winlibs,
msvc_winlibs,
unixy_compiler_internal_libs,
vs32_instruction_set_args,
vs64_instruction_set_args,
ArmCompiler,
@ -52,8 +53,6 @@ from .compilers import (
CcrxCompiler,
)
gnu_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt')
class CCompiler(Compiler):
# TODO: Replace this manual cache with functools.lru_cache
@ -61,7 +60,7 @@ class CCompiler(Compiler):
program_dirs_cache = {}
find_library_cache = {}
find_framework_cache = {}
internal_libs = gnu_compiler_internal_libs
internal_libs = unixy_compiler_internal_libs
@staticmethod
def attribute_check_func(name):
@ -1374,7 +1373,7 @@ class IntelCCompiler(IntelCompiler, CCompiler):
class VisualStudioCCompiler(CCompiler):
std_warn_args = ['/W3']
std_opt_args = ['/O2']
ignore_libs = gnu_compiler_internal_libs
ignore_libs = unixy_compiler_internal_libs
internal_libs = ()
crt_args = {'none': [],

@ -81,6 +81,9 @@ cflags_mapping = {'c': 'CFLAGS',
'vala': 'VALAFLAGS',
'rust': 'RUSTFLAGS'}
# execinfo is a compiler lib on BSD
unixy_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt', 'execinfo')
# All these are only for C-linkable languages; see `clink_langs` above.
def sort_clink(lang):
@ -659,6 +662,9 @@ class CompilerArgs(list):
# Only UNIX shared libraries require this. Others have a fixed extension.
dedup1_regex = re.compile(r'([\/\\]|\A)lib.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$')
dedup1_args = ('-c', '-S', '-E', '-pipe', '-pthread')
# In generate_link() we add external libs without de-dup, but we must
# *always* de-dup these because they're special arguments to the linker
always_dedup_args = tuple('-l' + lib for lib in unixy_compiler_internal_libs)
compiler = None
def _check_args(self, args):
@ -793,7 +799,7 @@ class CompilerArgs(list):
normal_flags = []
lflags = []
for i in iterable:
if i.startswith('-l') or i.startswith('-L'):
if i not in self.always_dedup_args and (i.startswith('-l') or i.startswith('-L')):
lflags.append(i)
else:
normal_flags.append(i)

@ -3900,7 +3900,7 @@ class WindowsTests(BasePlatformTests):
if cc.get_argument_syntax() != 'msvc':
raise unittest.SkipTest('Not using MSVC')
# To force people to update this test, and also test
self.assertEqual(set(cc.ignore_libs), {'c', 'm', 'pthread', 'dl', 'rt'})
self.assertEqual(set(cc.ignore_libs), {'c', 'm', 'pthread', 'dl', 'rt', 'execinfo'})
for l in cc.ignore_libs:
self.assertEqual(cc.find_library(l, env, []), [])
@ -5050,6 +5050,19 @@ endian = 'little'
max_count = max(max_count, line.count(search_term))
self.assertEqual(max_count, 1, 'Export dynamic incorrectly deduplicated.')
def test_compiler_libs_static_dedup(self):
testdir = os.path.join(self.unit_test_dir, '55 dedup compiler libs')
self.init(testdir)
build_ninja = os.path.join(self.builddir, 'build.ninja')
with open(build_ninja, 'r', encoding='utf-8') as f:
lines = f.readlines()
for lib in ('-ldl', '-lm', '-lc', '-lrt'):
for line in lines:
if lib not in line:
continue
# Assert that
self.assertEqual(len(line.split(lib)), 2, msg=(lib, line))
def test_identity_cross(self):
testdir = os.path.join(self.unit_test_dir, '58 identity cross')
crossfile = tempfile.NamedTemporaryFile(mode='w')

@ -0,0 +1,13 @@
#include <stdio.h>
#include <liba.h>
#include <libb.h>
int
main(void)
{
printf("start value = %d\n", liba_get());
liba_add(2);
libb_mul(5);
printf("end value = %d\n", liba_get());
return 0;
}

@ -0,0 +1,2 @@
executable('app', 'app.c',
dependencies: [liba_dep, libb_dep])

@ -0,0 +1,18 @@
#include "liba.h"
static int val;
void liba_add(int x)
{
val += x;
}
void liba_sub(int x)
{
val -= x;
}
int liba_get(void)
{
return val;
}

@ -0,0 +1,8 @@
#ifndef LIBA_H_
#define LIBA_H_
void liba_add(int x);
void liba_sub(int x);
int liba_get(void);
#endif

@ -0,0 +1,8 @@
deps = [dependency('threads'), cc.find_library('dl'), cc.find_library('m')]
liba = library('a', 'liba.c',
dependencies: deps)
liba_dep = declare_dependency(link_with: liba,
include_directories: include_directories('.'),
dependencies: deps)

@ -0,0 +1,7 @@
#include <liba.h>
#include "libb.h"
void libb_mul(int x)
{
liba_add(liba_get() * (x - 1));
}

@ -0,0 +1,6 @@
#ifndef _LIBB_H_
#define _LIBB_H_
void libb_mul(int x);
#endif

@ -0,0 +1,6 @@
libb = library('b', 'libb.c',
dependencies: liba_dep)
libb_dep = declare_dependency(link_with: libb,
include_directories: include_directories('.'),
dependencies: liba_dep)

@ -0,0 +1,7 @@
project('temp', 'c')
cc = meson.get_compiler('c')
subdir('liba')
subdir('libb')
subdir('app')
Loading…
Cancel
Save