Repository: mesonbuild/meson

Issue:
meson does not add "-pthread" from cmake-based dependency
I tried to use build a simple http client using Microsoft's [cpprestsdk](https://github.com/Microsoft/cpprestsdk/). The cpprest library is installed system-wide (Fedora 30 x86_64, cpprest 2.10.13-1.fc30).

However meson 0.51.1 fails to link the code while a cmake-based project works fine:

    $ meson . build
    The Meson build system
    Version: 0.51.1
    Source dir: …/httptest
    Build dir: …/httptest/build
    Build type: native build
    Project name: httptest
    Project version: undefined
    C++ compiler for the build machine: c++ (gcc 9.1.1 "c++ (GCC) 9.1.1 20190503 (Red Hat 9.1.1-1)")
    C++ compiler for the host machine: c++ (gcc 9.1.1 "c++ (GCC) 9.1.1 20190503 (Red Hat 9.1.1-1)")
    Build machine cpu family: x86_64
    Build machine cpu: x86_64
    Found CMake: /usr/bin/cmake (3.14.5)
    Run-time dependency cpprestsdk (modules: cpprestsdk::cpprest) found: YES 
    Build targets in project: 1
    Found ninja-1.9.0 at /usr/bin/ninja

    $ ninja -C build
    ninja: Entering directory `build'
    [2/2] Linking target httptest.
    FAILED: httptest 
    c++  -o httptest 'httptest@exe/src_test.cpp.o' -Wl,--no-undefined -Wl,--as-needed -Wl,--start-group /usr/lib64/libcpprest.so.2.10 /usr/lib64/libcrypto.so /usr/lib64/libssl.so -Wl,--end-group
    /usr/bin/ld: httptest@exe/src_test.cpp.o: undefined reference to symbol 'pthread_join@@GLIBC_2.2.5'
    /usr/bin/ld: //usr/lib64/libpthread.so.0: error adding symbols: DSO missing from command line
    collect2: Fehler: ld gab 1 als Ende-Status zurück
    ninja: build stopped: subcommand failed.

The problem is that the `c++` invocation is missing `-pthread`. When I add this manually or force it via `export CXXFLAGS=-pthread` everything works fine. This is my [meson.build](https://github.com/mesonbuild/meson/files/3524203/meson.build.txt) file (source code for test.cpp is copied from the [cpprest tutorial](https://github.com/Microsoft/cpprestsdk/wiki/Getting-Started-Tutorial) and also included in my `cmake.zip` below).

The cpprest library declares the pthread dependency correctly as far as I can tell. On my system there the file `/usr/lib64/cmake/cpprestsdk/cpprestsdk-targets.cmake` contains:

    set_target_properties(cpprestsdk::cpprest PROPERTIES
      INTERFACE_COMPILE_DEFINITIONS "CPPREST_FORCE_HTTP_CLIENT_ASIO;CPPREST_FORCE_HTTP_LISTENER_ASIO"
      INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
      INTERFACE_LINK_LIBRARIES "-lpthread;cpprestsdk::cpprestsdk_boost_internal;cpprestsdk::cpprestsdk_openssl_internal;cpprestsdk::cpprestsdk_boost_internal;cpprestsdk::cpprestsdk_openssl_internal;cpprestsdk::cpprestsdk_boost_internal;cpprestsdk::cpprestsdk_openssl_internal"
    )

I created a trivial cmake project which works fine ([cmake.zip](https://github.com/mesonbuild/meson/files/3524181/cmake.zip)) so somehow meson misses the linker arguments.

I hope it is easy to reproduce the issue. cpprest should be easily installable on most systems. If necessary I can also try building a minimal cmake-based library so you don't need cpprest but I hope that won't be necessary.

Also as a workaround I'd be interested if it is possible to force meson to link to with pthread (and declare this in meson.build).



Discussion:

Resolving patch:
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -1326,6 +1326,7 @@ def _detect_dep(self, name: str, modules: List[Tuple[str, bool]], args: List[str
                                       'Valid targets are:\n{}'.format(name, list(self.traceparser.targets.keys())))
 
         # Set dependencies with CMake targets
+        reg_is_lib = re.compile(r'^(-l[a-zA-Z0-9_]+|-pthread)$')
         processed_targets = []
         incDirs = []
         compileDefinitions = []
@@ -1393,14 +1394,16 @@ def _detect_dep(self, name: str, modules: List[Tuple[str, bool]], args: List[str
                 for j in otherDeps:
                     if j in self.traceparser.targets:
                         targets += [j]
+                    elif reg_is_lib.match(j) or os.path.exists(j):
+                        libraries += [j]
 
                 processed_targets += [curr]
 
         # Make sure all elements in the lists are unique and sorted
-        incDirs = list(sorted(list(set(incDirs))))
-        compileDefinitions = list(sorted(list(set(compileDefinitions))))
-        compileOptions = list(sorted(list(set(compileOptions))))
-        libraries = list(sorted(list(set(libraries))))
+        incDirs = sorted(set(incDirs))
+        compileDefinitions = sorted(set(compileDefinitions))
+        compileOptions = sorted(set(compileOptions))
+        libraries = sorted(set(libraries))
 
         mlog.debug('Include Dirs:         {}'.format(incDirs))
         mlog.debug('Compiler Definitions: {}'.format(compileDefinitions))


Test patch: