aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2016-10-07 22:49:25 +0300
committerGitHub <noreply@github.com>2016-10-07 22:49:25 +0300
commit4781f471c227bee330eb459a35c908770cea64fb (patch)
treeb5a65f2beb5310fdd8117aaa26f1df3a3d0da436
parent7ecdf5913058873f0e71af7d9e68ec6804569773 (diff)
parent67c9e520de4194b06fcfa2609f2036dfd9636217 (diff)
downloadmeson-4781f471c227bee330eb459a35c908770cea64fb.zip
meson-4781f471c227bee330eb459a35c908770cea64fb.tar.gz
meson-4781f471c227bee330eb459a35c908770cea64fb.tar.bz2
Merge pull request #856 from centricular/static_library_pic
Add cross-platform PIC support for static libraries
-rw-r--r--mesonbuild/backend/backends.py2
-rw-r--r--mesonbuild/build.py36
-rw-r--r--mesonbuild/compilers.py13
-rw-r--r--test cases/common/62 exe static shared/meson.build5
-rw-r--r--test cases/common/62 exe static shared/prog.c7
-rw-r--r--test cases/common/62 exe static shared/shlib2.c7
-rw-r--r--test cases/common/62 exe static shared/subdir/exports.h12
-rw-r--r--test cases/common/62 exe static shared/subdir/shlib.c11
-rw-r--r--test cases/failing/33 exe static shared/meson.build11
-rw-r--r--test cases/failing/33 exe static shared/prog.c10
-rw-r--r--test cases/failing/33 exe static shared/shlib2.c16
-rw-r--r--test cases/failing/33 exe static shared/stat.c3
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;
+}