Repository: mesonbuild/meson

Issue:
llvm fallback code computes wrong build flags
While preparing a backport of meson for stretch, I noticed that the test-suite failed:
https://buildd.debian.org/status/fetch.php?pkg=meson&arch=all&ver=0.47.2-1~bpo9%2B1&stamp=1535598649&raw=0

The relevant part is
```
[0/1] /usr/bin/python3 /<<PKGBUILDDIR>>/meson.py --internal regenerate '/<<PKGBUILDDIR>>/test cases/frameworks/15 llvm' '/<<PKGBUILDDIR>>/b aa8b0c8a24' --backend ninja
The Meson build system
Version: 0.47.2
Source dir: /<<PKGBUILDDIR>>/test cases/frameworks/15 llvm
Build dir: /<<PKGBUILDDIR>>/b aa8b0c8a24
Build type: native build
Project name: llvmtest
Project version: undefined
Native C compiler: cc (gcc 6.3.0 "cc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516")
Native C++ compiler: c++ (gcc 6.3.0 "c++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516")
Build machine cpu family: x86_64
Build machine cpu: x86_64
Dependency llvm found: YES (cached)
Found llvm-config: /usr/bin/llvm-config (3.8.1)
Dependency LLVM found: YES
LLVM module not-found found: NO 
Found llvm-config '3.8.1' NO (needed <0.1 )
Dependency LLVM found: NO
Dependency llvm found: YES (cached)
Dependency tinfo found: YES (cached)
Found llvm-config: /usr/bin/llvm-config (3.8.1)
Dependency LLVM found: YES
LLVM module asmprinter found: YES
LLVM module bitwriter found: YES
LLVM module executionengine found: YES
LLVM module mcjit found: YES
LLVM module nativecodegen found: YES
LLVM module target found: YES
Dependency zlib found: YES (cached)
Library dl found: YES
Found llvm-config: /usr/bin/llvm-config (3.8.1)
Dependency LLVM found: YES
LLVM module asmprinter found: YES
LLVM module bitwriter found: YES
LLVM module executionengine found: YES
LLVM module mcjit found: YES
LLVM module nativecodegen found: YES
LLVM module target found: YES
Dependency zlib found: YES (cached)
Library dl found: YES
Build targets in project: 2
Found ninja-1.7.2 at /usr/bin/ninja
[1/4] cc -Isum-static@exe -I. '-I../test cases/frameworks/15 llvm' -I/usr/lib/llvm-3.8/include -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c99 -O0 -g -g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -D_DEFAULT_SOURCE -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -pthread  -MD -MQ 'sum-static@exe/sum.c.o' -MF 'sum-static@exe/sum.c.o.d' -o 'sum-static@exe/sum.c.o' -c '../test cases/frameworks/15 llvm/sum.c'
[2/4] cc -Isum-dynamic@exe -I. '-I../test cases/frameworks/15 llvm' -I/usr/lib/llvm-3.8/include -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c99 -O0 -g -g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -D_DEFAULT_SOURCE -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -pthread  -MD -MQ 'sum-dynamic@exe/sum.c.o' -MF 'sum-dynamic@exe/sum.c.o.d' -o 'sum-dynamic@exe/sum.c.o' -c '../test cases/frameworks/15 llvm/sum.c'
[3/4] c++  -o sum-dynamic 'sum-dynamic@exe/sum.c.o' -Wl,--no-undefined -Wl,--as-needed -g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-z,relro -L/usr/lib/llvm-3.8/lib -Wl,--start-group LLVM-3.8.1.so /usr/lib/x86_64-linux-gnu/libtinfo.so /usr/lib/x86_64-linux-gnu/libz.so -ldl -Wl,--end-group -pthread  
FAILED: sum-dynamic 
c++  -o sum-dynamic 'sum-dynamic@exe/sum.c.o' -Wl,--no-undefined -Wl,--as-needed -g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-z,relro -L/usr/lib/llvm-3.8/lib -Wl,--start-group LLVM-3.8.1.so /usr/lib/x86_64-linux-gnu/libtinfo.so /usr/lib/x86_64-linux-gnu/libz.so -ldl -Wl,--end-group -pthread  
c++: error: LLVM-3.8.1.so: No such file or directory
[4/4] c++  -o sum-static 'sum-static@exe/sum.c.o' -Wl,--no-undefined -Wl,--as-needed -g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-z,relro -L/usr/lib/llvm-3.8/lib -Wl,--start-group -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Info -lLLVMMCDisassembler -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMSelectionDAG -lLLVMMCJIT -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMAsmPrinter -lLLVMCodeGen -lLLVMTarget -lLLVMScalarOpts -lLLVMInstCombine -lLLVMInstrumentation -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMTransformUtils -lLLVMMC -lLLVMBitWriter -lLLVMBitReader -lLLVMAnalysis -lLLVMCore -lLLVMSupport -lrt -ldl -ltinfo -lpthread -lz -lm /usr/lib/x86_64-linux-gnu/libtinfo.so /usr/lib/x86_64-linux-gnu/libz.so -ldl -Wl,--end-group -pthread  
ninja: build stopped: subcommand failed.
```

With help from #debian-devel the problem turned out to be a bug in the llvm fallback code at
https://github.com/mesonbuild/meson/blob/master/mesonbuild/dependencies/dev.py#L232 which gives different results depending on the  order of files retured by readdir().

The attached patch, courtesy of Jakub Wilk <jwilk@debian.org>, fixes the issue
```
--- a/mesonbuild/dependencies/dev.py
+++ b/mesonbuild/dependencies/dev.py
@@ -219,7 +219,7 @@
             libdir = self.get_config_value(['--libdir'], 'link_args')[0]
 
             expected_name = 'libLLVM-{}'.format(self.version)
-            re_name = re.compile(r'{}.(so|dll|dylib)'.format(expected_name))
+            re_name = re.compile(r'{}.(so|dll|dylib)$'.format(expected_name))
 
             for file_ in os.listdir(libdir):
                 if re_name.match(file_):
```



Discussion:
```
c++  -o sum-dynamic 'sum-dynamic@exe/sum.c.o' -Wl,--no-undefined -Wl,--as-needed -g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-z,relro -L/usr/lib/llvm-3.8/lib -Wl,--start-group LLVM-3.8.1.so /usr/lib/x86_64-linux-gnu/libtinfo.so /usr/lib/x86_64-linux-gnu/libz.so -ldl -Wl,--end-group -pthread  
```
Note the missing ```-l``` for ```LLVM-3.8.1.so```


I wrote that code, and yes the existing code could cause problems depending on the sort order of the returned values. Could you or Jakub submit that patch as a pull request? Feel free to mention me on the patch, that should be merged, and pulled into the next stable release.
@nirbheek could you tag this for 0.48? It's super trivial to fix and is a real bug.

Resolving patch:
diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py
--- a/mesonbuild/dependencies/dev.py
+++ b/mesonbuild/dependencies/dev.py
@@ -288,7 +288,7 @@ def _set_old_link_args(self):
             libdir = self.get_config_value(['--libdir'], 'link_args')[0]
 
             expected_name = 'libLLVM-{}'.format(self.version)
-            re_name = re.compile(r'{}.(so|dll|dylib)'.format(expected_name))
+            re_name = re.compile(r'{}.(so|dll|dylib)$'.format(expected_name))
 
             for file_ in os.listdir(libdir):
                 if re_name.match(file_):


Test patch: