diff options
-rw-r--r-- | mesonbuild/backend/backends.py | 2 | ||||
-rw-r--r-- | mesonbuild/build.py | 36 | ||||
-rw-r--r-- | mesonbuild/compilers.py | 13 | ||||
-rw-r--r-- | test cases/common/62 exe static shared/meson.build | 5 | ||||
-rw-r--r-- | test cases/common/62 exe static shared/prog.c | 7 | ||||
-rw-r--r-- | test cases/common/62 exe static shared/shlib2.c | 7 | ||||
-rw-r--r-- | test cases/common/62 exe static shared/subdir/exports.h | 12 | ||||
-rw-r--r-- | test cases/common/62 exe static shared/subdir/shlib.c | 11 | ||||
-rw-r--r-- | test cases/failing/33 exe static shared/meson.build | 11 | ||||
-rw-r--r-- | test cases/failing/33 exe static shared/prog.c | 10 | ||||
-rw-r--r-- | test cases/failing/33 exe static shared/shlib2.c | 16 | ||||
-rw-r--r-- | test cases/failing/33 exe static shared/stat.c | 3 |
12 files changed, 109 insertions, 24 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index d5af056..16f7ada 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -341,6 +341,8 @@ class Backend(): commands += compiler.get_werror_args() if isinstance(target, build.SharedLibrary): commands += compiler.get_pic_args() + if isinstance(target, build.StaticLibrary) and target.pic: + commands += compiler.get_pic_args() for dep in target.get_external_deps(): # Cflags required by external deps might have UNIX-specific flags, # so filter them out if needed diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 1ef183b..3d41cda 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -44,12 +44,19 @@ known_basic_kwargs = {'install' : True, 'native' : True, } -known_shlib_kwargs = known_basic_kwargs.copy() -known_shlib_kwargs.update({'version' : True, - 'soversion' : True, - 'name_prefix' : True, - 'name_suffix' : True, - 'vs_module_defs' : True}) +# These contain kwargs supported by both static and shared libraries. These are +# combined here because a library() call might be shared_library() or +# static_library() at runtime based on the configuration. +# FIXME: Find a way to pass that info down here so we can have proper target +# kwargs checking when specifically using shared_library() or static_library(). +known_lib_kwargs = known_basic_kwargs.copy() +known_lib_kwargs.update({'version' : True, # Only for shared libs + 'soversion' : True, # Only for shared libs + 'name_prefix' : True, + 'name_suffix' : True, + 'vs_module_defs' : True, # Only for shared libs + 'pic' : True, # Only for static libs + }) def compilers_are_msvc(compilers): """ @@ -516,6 +523,16 @@ class BuildTarget(): if not isinstance(name_suffix, str): raise InvalidArguments('Name suffix must be a string.') self.suffix = name_suffix + if isinstance(self, StaticLibrary): + # You can't disable PIC on OS X. The compiler ignores -fno-PIC. + # PIC is always on for Windows (all code is position-independent + # since library loading is done differently) + if for_darwin(self.is_cross, self.environment) or for_windows(self.is_cross, self.environment): + self.pic = True + else: + self.pic = kwargs.get('pic', False) + if not isinstance(self.pic, bool): + raise InvalidArguments('Argument pic must be boolean') def get_subdir(self): return self.subdir @@ -618,6 +635,8 @@ by calling get_variable() on the subproject object.''') t = t.held_object if not isinstance(t, (StaticLibrary, SharedLibrary)): raise InvalidArguments('Link target is not library.') + if isinstance(self, SharedLibrary) and isinstance(t, StaticLibrary) and not t.pic: + raise InvalidArguments("Can't link a non-PIC static library into a shared library") if self.is_cross != t.is_cross: raise InvalidArguments('Tried to mix cross built and native libraries in target %s.' % self.name) self.link_targets.append(t) @@ -831,6 +850,9 @@ class StaticLibrary(BuildTarget): def type_suffix(self): return "@sta" + def check_unknown_kwargs(self, kwargs): + self.check_unknown_kwargs_int(kwargs, known_lib_kwargs) + class SharedLibrary(BuildTarget): def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs): self.soversion = None @@ -988,7 +1010,7 @@ class SharedLibrary(BuildTarget): self.link_depends.append(path) def check_unknown_kwargs(self, kwargs): - self.check_unknown_kwargs_int(kwargs, known_shlib_kwargs) + self.check_unknown_kwargs_int(kwargs, known_lib_kwargs) def get_import_filename(self): """ diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 19fb888..c81a599 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -1934,8 +1934,8 @@ class GnuCompiler: return defines[define] def get_pic_args(self): - if self.gcc_type == GCC_MINGW: - return [] # On Window gcc defaults to fpic being always on. + if self.gcc_type in (GCC_MINGW, GCC_OSX): + return [] # On Window and OS X, pic is always on. return ['-fPIC'] def get_buildtype_args(self, buildtype): @@ -2059,6 +2059,11 @@ class ClangCompiler(): self.base_options.append('b_lundef') self.base_options.append('b_asneeded') + def get_pic_args(self): + if self.clang_type in (CLANG_WIN, CLANG_OSX): + return [] # On Window and OS X, pic is always on. + return ['-fPIC'] + def get_buildtype_args(self, buildtype): return gnulike_buildtype_args[buildtype] @@ -2174,8 +2179,8 @@ class FortranCompiler(Compiler): return ' '.join(self.exelist) def get_pic_args(self): - if self.gcc_type == GCC_MINGW: - return [] # On Windows gcc defaults to fpic being always on. + if self.gcc_type in (GCC_MINGW, GCC_OSX): + return [] # On Window and OS X, pic is always on. return ['-fPIC'] def get_std_shared_lib_link_args(self): diff --git a/test cases/common/62 exe static shared/meson.build b/test cases/common/62 exe static shared/meson.build index 3c75391..8631e68 100644 --- a/test cases/common/62 exe static shared/meson.build +++ b/test cases/common/62 exe static shared/meson.build @@ -1,6 +1,7 @@ project('statchain', 'c') subdir('subdir') -statlib = static_library('stat', 'stat.c', link_with : shlib) -exe = executable('prog', 'prog.c', link_with : statlib) +statlib = static_library('stat', 'stat.c', link_with : shlib, pic : true) +shlib2 = shared_library('shr2', 'shlib2.c', link_with : statlib) +exe = executable('prog', 'prog.c', link_with : shlib2) test('runtest', exe) diff --git a/test cases/common/62 exe static shared/prog.c b/test cases/common/62 exe static shared/prog.c index 4f82a6b..26603b6 100644 --- a/test cases/common/62 exe static shared/prog.c +++ b/test cases/common/62 exe static shared/prog.c @@ -1,5 +1,10 @@ +int shlibfunc2(); int statlibfunc(); int main(int argc, char **argv) { - return statlibfunc() == 42 ? 0 : 1; + if (statlibfunc() != 42) + return 1; + if (shlibfunc2() != 24) + return 1; + return 0; } diff --git a/test cases/common/62 exe static shared/shlib2.c b/test cases/common/62 exe static shared/shlib2.c new file mode 100644 index 0000000..e26d11c --- /dev/null +++ b/test cases/common/62 exe static shared/shlib2.c @@ -0,0 +1,7 @@ +#include "subdir/exports.h" + +int statlibfunc(void); + +int DLL_PUBLIC shlibfunc2(void) { + return statlibfunc() - 18; +} diff --git a/test cases/common/62 exe static shared/subdir/exports.h b/test cases/common/62 exe static shared/subdir/exports.h new file mode 100644 index 0000000..c89ccb2 --- /dev/null +++ b/test cases/common/62 exe static shared/subdir/exports.h @@ -0,0 +1,12 @@ +#pragma once + +#if defined _WIN32 || defined __CYGWIN__ + #define DLL_PUBLIC __declspec(dllexport) +#else + #if defined __GNUC__ + #define DLL_PUBLIC __attribute__ ((visibility("default"))) + #else + #pragma message ("Compiler does not support symbol visibility.") + #define DLL_PUBLIC + #endif +#endif diff --git a/test cases/common/62 exe static shared/subdir/shlib.c b/test cases/common/62 exe static shared/subdir/shlib.c index d649c7d..002c83f 100644 --- a/test cases/common/62 exe static shared/subdir/shlib.c +++ b/test cases/common/62 exe static shared/subdir/shlib.c @@ -1,13 +1,4 @@ -#if defined _WIN32 || defined __CYGWIN__ - #define DLL_PUBLIC __declspec(dllexport) -#else - #if defined __GNUC__ - #define DLL_PUBLIC __attribute__ ((visibility("default"))) - #else - #pragma message ("Compiler does not support symbol visibility.") - #define DLL_PUBLIC - #endif -#endif +#include "exports.h" int DLL_PUBLIC shlibfunc() { return 42; diff --git a/test cases/failing/33 exe static shared/meson.build b/test cases/failing/33 exe static shared/meson.build new file mode 100644 index 0000000..b102764 --- /dev/null +++ b/test cases/failing/33 exe static shared/meson.build @@ -0,0 +1,11 @@ +project('statchain', 'c') + +host_system = host_machine.system() +if host_system == 'windows' or host_system == 'darwin' + error('Test only fails on Linux and BSD') +endif + +statlib = static_library('stat', 'stat.c', pic : false) +shlib2 = shared_library('shr2', 'shlib2.c', link_with : statlib) +exe = executable('prog', 'prog.c', link_with : shlib2) +test('runtest', exe) diff --git a/test cases/failing/33 exe static shared/prog.c b/test cases/failing/33 exe static shared/prog.c new file mode 100644 index 0000000..26603b6 --- /dev/null +++ b/test cases/failing/33 exe static shared/prog.c @@ -0,0 +1,10 @@ +int shlibfunc2(); +int statlibfunc(); + +int main(int argc, char **argv) { + if (statlibfunc() != 42) + return 1; + if (shlibfunc2() != 24) + return 1; + return 0; +} diff --git a/test cases/failing/33 exe static shared/shlib2.c b/test cases/failing/33 exe static shared/shlib2.c new file mode 100644 index 0000000..5b68843 --- /dev/null +++ b/test cases/failing/33 exe static shared/shlib2.c @@ -0,0 +1,16 @@ +#if defined _WIN32 || defined __CYGWIN__ + #define DLL_PUBLIC __declspec(dllexport) +#else + #if defined __GNUC__ + #define DLL_PUBLIC __attribute__ ((visibility("default"))) + #else + #pragma message ("Compiler does not support symbol visibility.") + #define DLL_PUBLIC + #endif +#endif + +int statlibfunc(void); + +int DLL_PUBLIC shlibfunc2(void) { + return 24; +} diff --git a/test cases/failing/33 exe static shared/stat.c b/test cases/failing/33 exe static shared/stat.c new file mode 100644 index 0000000..56ec66c --- /dev/null +++ b/test cases/failing/33 exe static shared/stat.c @@ -0,0 +1,3 @@ +int statlibfunc() { + return 42; +} |