Skip to content

Commit

Permalink
compilers: Try harder to dedup builtin libs
Browse files Browse the repository at this point in the history
Compiler internal libs should always be de-duplicated, no matter what.

Closes #2150
  • Loading branch information
nirbheek committed Mar 13, 2019
1 parent 9409155 commit 97dc00d
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 5 deletions.
7 changes: 3 additions & 4 deletions mesonbuild/compilers/c.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
get_largefile_args,
gnu_winlibs,
msvc_winlibs,
unixy_compiler_internal_libs,
vs32_instruction_set_args,
vs64_instruction_set_args,
ArmCompiler,
Expand All @@ -52,16 +53,14 @@
CcrxCompiler,
)

gnu_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt')


class CCompiler(Compiler):
# TODO: Replace this manual cache with functools.lru_cache
library_dirs_cache = {}
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):
Expand Down Expand Up @@ -1375,7 +1374,7 @@ def get_option_compile_args(self, options):
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': [],
Expand Down
8 changes: 7 additions & 1 deletion mesonbuild/compilers/compilers.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@
'vala': 'VALAFLAGS',
'rust': 'RUSTFLAGS'}

# execinfo is a compiler lib on BSD
unixy_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt', 'execinfo')

This comment has been minimized.

Copy link
@kusalananda

kusalananda May 29, 2019

Note that execinfo is not an internal library with e.g. Clang on OpenBSD. This breaks detection of libexecinfo on OpenBSD.

This comment has been minimized.

Copy link
@nirbheek

nirbheek May 29, 2019

Author Member

Please always file a new issue about such things instead of commenting on a diff or it will simply be lost.


# All these are only for C-linkable languages; see `clink_langs` above.

def sort_clink(lang):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -793,7 +799,7 @@ def extend_preserving_lflags(self, iterable):
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)
Expand Down
13 changes: 13 additions & 0 deletions run_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5039,6 +5039,19 @@ def test_ldflag_dedup(self):
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 should_run_cross_arm_tests():
return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm')
Expand Down
13 changes: 13 additions & 0 deletions test cases/unit/55 dedup compiler libs/app/app.c
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 2 additions & 0 deletions test cases/unit/55 dedup compiler libs/app/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
executable('app', 'app.c',
dependencies: [get_variable('dep_liba'), get_variable('dep_libb')])
18 changes: 18 additions & 0 deletions test cases/unit/55 dedup compiler libs/liba/liba.c
Original file line number Diff line number Diff line change
@@ -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;
}
8 changes: 8 additions & 0 deletions test cases/unit/55 dedup compiler libs/liba/liba.h
Original file line number Diff line number Diff line change
@@ -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
10 changes: 10 additions & 0 deletions test cases/unit/55 dedup compiler libs/liba/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
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)

set_variable('dep_liba', liba_dep)
7 changes: 7 additions & 0 deletions test cases/unit/55 dedup compiler libs/libb/libb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <liba.h>
#include "libb.h"

void libb_mul(int x)
{
liba_add(liba_get() * (x - 1));
}
6 changes: 6 additions & 0 deletions test cases/unit/55 dedup compiler libs/libb/libb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _LIBB_H_
#define _LIBB_H_

void libb_mul(int x);

#endif
9 changes: 9 additions & 0 deletions test cases/unit/55 dedup compiler libs/libb/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
libb = library('b', 'libb.c',
dependencies: liba_dep)

libb_dep = declare_dependency(link_with: libb,
include_directories: include_directories('.'),
dependencies: liba_dep)

set_variable('dep_libb', libb_dep)

7 changes: 7 additions & 0 deletions test cases/unit/55 dedup compiler libs/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
project('temp', 'C')

cc = meson.get_compiler('c')

subdir('liba')
subdir('libb')
subdir('app')

0 comments on commit 97dc00d

Please sign in to comment.