Meson: find_library() prefer .a to .so

Created on 10 Dec 2015  路  15Comments  路  Source: mesonbuild/meson

Hi Jussi,

Is there a way to get find_library to find the .a instead of the corresponding .so?

Thanks!

bug compilers dependencies help wanted

Most helpful comment

For me, lacking this is one of the biggest downsides of CMake. Overall, the static linking topic is unbelievably vague for C/C++ and usually requires ugly hacks to produce a fine statically linked binary on Linux. find_library() should definitely have the same static parameter as dependency().

All 15 comments

If they are in the same dir, no.

would you accept a pull request that did something like this?

diff --git a/environment.py b/environment.py
index e09f6ae..431f457 100644
--- a/environment.py
+++ b/environment.py
@@ -581,10 +581,13 @@ class Environment():
     def get_datadir(self):
         return self.coredata.get_builtin_option('datadir')

-    def find_library(self, libname, dirs):
+    def find_library(self, libname, dirs, prefer_static):
         if dirs is None:
             dirs = mesonlib.get_library_dirs()
-        suffixes = [self.get_shared_lib_suffix(), self.get_static_lib_suffix()]
+        if prefer_static:
+            suffixes = [self.get_shared_lib_suffix(), self.get_static_lib_suffi
+        else:
+            suffixes = [self.get_static_lib_suffix(), self.get_shared_lib_suffi
         prefix = self.get_shared_lib_prefix()
         for d in dirs:
             for suffix in suffixes:
diff --git a/interpreter.py b/interpreter.py
index 47ce716..e1ca7aa 100644
--- a/interpreter.py
+++ b/interpreter.py
@@ -1535,6 +1535,9 @@ class Interpreter():
         required = kwargs.get('required', True)
         if not isinstance(required, bool):
             raise InvalidArguments('"required" argument must be a boolean.')
+        prefer_static = kwargs.get('prefer_static', False)
+        if not isinstance(prefer_static, bool):
+            raise InvalidArguments('"prefer_static" argument must be a boolean.
         libname = args[0]
         # We do not cache found libraries because they can come
         # and go between invocations wildly. As an example we

Hi Jussi,

Actually, I'd like to add other args to find_library as well. Such as 'prepend_dirs' and 'append_dirs'.

Reason:
I had this: pthread = find_library('pthread')

It worked fine on my ubuntu box (location: /usr/lib/x86_64-linux-gnu/libpthread.so), but on the 64bit redhat 6.x dev box it picked up the pthread in /usr/lib instead of /usr/lib64 - thus, linking failed.

So, now I have to have this in the meson.build file (unless there is another way?)

pthread = find_library('pthread', dirs: ['/usr/lib64'], required: false)
if not pthread.found()
    pthread = find_library('pthread')
endif

Is there a way to get the current lib search directories? Can you think of another way to make this work better? Maybe meson can be smart about 64 vs 32 bit libraries somehow?

EDIT: fix paths
EDIT2: fix meson code snippet

You should never do pthreads manually, it leads to madness. There should instead be a flag to say "use threads" because on non-posix platforms you need to do it differently (and you need to use compiler flags and all that stuff). I have considered something like this:

thread_dep = dependency('threads')

which you would then pass around as a regular dependency.

pthread was just an example. The other library I had issue with was libz being picked up in /usr/lib instead of /usr/lib64 on redhat 6.x. And it's probably in /usr/lib/x86_64-linux-gnu/ on my ubuntu box.

Really, I should have started a new issue for this :/

Issue 1: Prefer static objects over shared objects
Issue 2: More fine grained library search path options.

BTW, :+1: for thread_dep = dependency('threads')

find_library is a relic from the era without pkg-config. You should never ever use it if possible. If it were up to me that function would not even exist, but on some braindead platforms it is unfortunately still needed.

As an example for zlib you should use dependency('zlib'). It will work on all Linux platforms and on others you should use wrapdb. It's so much simpler.

Now there is a dependency('threads').

@jpakkane BTW I just refreshed today and added in my linux box dependency('threads') and add it to my target and it seems not to add -pthread. Should I fill an issue?

For me, lacking this is one of the biggest downsides of CMake. Overall, the static linking topic is unbelievably vague for C/C++ and usually requires ugly hacks to produce a fine statically linked binary on Linux. find_library() should definitely have the same static parameter as dependency().

It seems that this issue will be resolved with https://github.com/mesonbuild/meson/pull/3747, if/when it is merged.

Is there a way to get find_library to find the .a instead of the corresponding .so?

If they are in the same dir, no.

@jpakkane
Is your answer still valid in context of v0.49 and/or trunk (even workaround would be fine)?
The inability to select type of the library breaks quite a few scenarios for us (and thus preventing me from advocating the migration to meson =( ) E.g. external dependency supplies both .a and .so (in the same folder), but depending on the build options we need either static or dynamic linkage.

Someone would need to rebase and finish the linked PR for this to work. Perhaps you'd like to do that?

@nirbheek I would love to, but my Python knowledge is pretty lacking. At best I could rebase PR and maybe fix simple errors (if there are any), I wouldn't trust myself with actually developing the feature...

3747 is merged.

Was this page helpful?
0 / 5 - 0 ratings