meson: Ambiguous threads dependency

dependency('threads') is poorly-documented.

Looking at the code (0.31.0), it seems that all that dependency('threads') does is create a dependency object that has needs_threads() == True.

needs_threads() == True makes the implementation add compiler.thread_flags() and compiler.thread_link_flags() to the flags that are actually used.

compiler.thread_flags() is -pthread for C and an empty string for C++ compiler.thread_link_flags() is -pthread for C and an empty string for C++

<threading-rant>

This does not seem like a good idea. A better approach is to focus on threading APIs.

I.e. meson.build would request threading API X for language Y. Meson will then do appropriate lookups and provide appropriate flags.

Threading APIs that i know of:

Name OS library flags languages
POSIX GNU libc -pthread? C/C++, bindings
POSIX *BSD libpthread -lpthread C/C++, bindings
POSIX W32 libpthread -lpthread C/C++, bindings
W32 W32 libkernel32 -lkernel32 C/C++, bindings
Python Any Python stdlib Python

and so on for C#, Rust and other languages (Fortran?).

That said, it doesn’t make much sense to check for these, as, for example, Python threading API is always part of Python stdlib, and W32 threading API is always available on W32 (-lkernel32 is hardcoded into GCC spec files, IIRC, you have to make an effort to not to link to it; dunno about MSVC).

POSIX threads is the only API that needs actual checking (as it might be in libc or in libpthread or somewhere else, in exotic OSes, and it might need special compiler flags).

Projects can also support multiple threading APIs (glib supports pthreads and W32 threads, at least) in their code. Which one is used is usually decided at configuration time by a configure option.

I would propose to document that dependency('threads') looks for POSIX threads (renaming it to dependency('pthreads') would probably break backward compatibility). Then actually either do check which flags are needed to link a pthread program (a simple pthread_create()) or hardcode that info into specific compiler profiles (i.e. -lpthread is sufficient for all MinGW flavors, as they traditionally come with some kind of pthreads implementation; standard GCC just needs -pthread). It should be overridable (in case someone wants to supply a threading library that implements POSIX threads, but does not provide a library named libpthread and does not provide a header named /include/pthread.h; it could be instead libmythread and /include/mythread/pthread.h, which means -lmythread -I/include/mythread).

Someone who knows obscure POSIX-ish platforms would need to verify the above. Digging into autotools source code (which does contain info about obscure OS quirks) is probably not an option, as it’s GPL-ed, while meson is Apache2.0-ed.

As for the rest of the APIs, i don’t know them well enough (even for W32 threading API, which i do know, there may be special MSVC flags that i’m not aware of, because i don’t use MSVC) to judge whether it’s enough to just imply their availability for a specific platform, or whether they need some kind of flags as well.

Looking back, i think this is an OS quirk - the only case where you need special compiler flags for threading support is when it comes from the OS. When it’s in stdlib of a language, you don’t need to do anything special, and stdlib uses appropriate OS API under the hood. When it’s just a 3rd-party library, you treat it as such, and the library uses appropriate OS API under the hood. Therefore, the number of really quirky threading APIs would actually be roughly equal to the number of OSes supported by meson, which right now is, like, 4?

</threading-rant>

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 1
  • Comments: 27 (23 by maintainers)

Commits related to this issue

Most upvoted comments

Sorry, which getconf value are you suggesting contains -pthread on systems where the compiler uses that flag?

@jpakkane But does that matter for the user? std::thread has a specific API and the user will only care if that works or not, not how you enabled that with the compiler?

Sure, I just thought a kwarg would be easier as we already have lots of custom dependencies and it would clobber the namespace of these less and avoid that we ever clash with anything that actually exists with the same name but is something else…