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.
This commit is contained in:
parent
5f00c30200
commit
07818dac6a
|
@ -35,6 +35,7 @@ from .compilers import (
|
||||||
get_largefile_args,
|
get_largefile_args,
|
||||||
gnu_winlibs,
|
gnu_winlibs,
|
||||||
msvc_winlibs,
|
msvc_winlibs,
|
||||||
|
unixy_compiler_internal_libs,
|
||||||
vs32_instruction_set_args,
|
vs32_instruction_set_args,
|
||||||
vs64_instruction_set_args,
|
vs64_instruction_set_args,
|
||||||
ArmCompiler,
|
ArmCompiler,
|
||||||
|
@ -52,8 +53,6 @@ from .compilers import (
|
||||||
CcrxCompiler,
|
CcrxCompiler,
|
||||||
)
|
)
|
||||||
|
|
||||||
gnu_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt')
|
|
||||||
|
|
||||||
|
|
||||||
class CCompiler(Compiler):
|
class CCompiler(Compiler):
|
||||||
# TODO: Replace this manual cache with functools.lru_cache
|
# TODO: Replace this manual cache with functools.lru_cache
|
||||||
|
@ -61,7 +60,7 @@ class CCompiler(Compiler):
|
||||||
program_dirs_cache = {}
|
program_dirs_cache = {}
|
||||||
find_library_cache = {}
|
find_library_cache = {}
|
||||||
find_framework_cache = {}
|
find_framework_cache = {}
|
||||||
internal_libs = gnu_compiler_internal_libs
|
internal_libs = unixy_compiler_internal_libs
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def attribute_check_func(name):
|
def attribute_check_func(name):
|
||||||
|
@ -1375,7 +1374,7 @@ class IntelCCompiler(IntelCompiler, CCompiler):
|
||||||
class VisualStudioCCompiler(CCompiler):
|
class VisualStudioCCompiler(CCompiler):
|
||||||
std_warn_args = ['/W3']
|
std_warn_args = ['/W3']
|
||||||
std_opt_args = ['/O2']
|
std_opt_args = ['/O2']
|
||||||
ignore_libs = gnu_compiler_internal_libs
|
ignore_libs = unixy_compiler_internal_libs
|
||||||
internal_libs = ()
|
internal_libs = ()
|
||||||
|
|
||||||
crt_args = {'none': [],
|
crt_args = {'none': [],
|
||||||
|
|
|
@ -81,6 +81,9 @@ cflags_mapping = {'c': 'CFLAGS',
|
||||||
'vala': 'VALAFLAGS',
|
'vala': 'VALAFLAGS',
|
||||||
'rust': 'RUSTFLAGS'}
|
'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.
|
# All these are only for C-linkable languages; see `clink_langs` above.
|
||||||
|
|
||||||
def sort_clink(lang):
|
def sort_clink(lang):
|
||||||
|
@ -659,6 +662,9 @@ class CompilerArgs(list):
|
||||||
# Only UNIX shared libraries require this. Others have a fixed extension.
|
# 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_regex = re.compile(r'([\/\\]|\A)lib.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$')
|
||||||
dedup1_args = ('-c', '-S', '-E', '-pipe', '-pthread')
|
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
|
compiler = None
|
||||||
|
|
||||||
def _check_args(self, args):
|
def _check_args(self, args):
|
||||||
|
@ -793,7 +799,7 @@ class CompilerArgs(list):
|
||||||
normal_flags = []
|
normal_flags = []
|
||||||
lflags = []
|
lflags = []
|
||||||
for i in iterable:
|
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)
|
lflags.append(i)
|
||||||
else:
|
else:
|
||||||
normal_flags.append(i)
|
normal_flags.append(i)
|
||||||
|
|
|
@ -3893,7 +3893,7 @@ class WindowsTests(BasePlatformTests):
|
||||||
if cc.get_argument_syntax() != 'msvc':
|
if cc.get_argument_syntax() != 'msvc':
|
||||||
raise unittest.SkipTest('Not using MSVC')
|
raise unittest.SkipTest('Not using MSVC')
|
||||||
# To force people to update this test, and also test
|
# 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:
|
for l in cc.ignore_libs:
|
||||||
self.assertEqual(cc.find_library(l, env, []), [])
|
self.assertEqual(cc.find_library(l, env, []), [])
|
||||||
|
|
||||||
|
@ -5043,6 +5043,19 @@ endian = 'little'
|
||||||
max_count = max(max_count, line.count(search_term))
|
max_count = max(max_count, line.count(search_term))
|
||||||
self.assertEqual(max_count, 1, 'Export dynamic incorrectly deduplicated.')
|
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 should_run_cross_arm_tests():
|
def should_run_cross_arm_tests():
|
||||||
return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm')
|
return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm')
|
||||||
|
|
|
@ -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…
Reference in New Issue