Repository: mesonbuild/meson

Issue:
b_sanitize=address requires b_lundef=false?
If I don't specify `-Db_lundef=false` at the same time I specify `-Db_sanitize=address` I get linker errors when building shared objects.

```
CC=clang CXX=clang++ meson.py -Db_sanitize=address -Db_lundef=false --buildtype=debugoptimized build-clang-asan
```

This caught me by surprise and took a while to figure out why the linker was failing.

Is it reasonable to automatically set `b_lundef` to false if `b_sanitize` is set to address (and possibly others)?



Discussion:
I tested this on Ubuntu and GCC works fine with `undef` but Clang does not. This makes things complicated we don't know if this is a gcc/clang behavioural mismatch or if gcc has been patched in Ubuntu to allow missing sanitizer symbols or to make `-fsanitize` link in the necessary symbols. The latter seems like the most sensible thing to me.

A good start would probably be to file a Clang bug about this difference. IMHO it should not complain about missing asan symbols if linker flag `-fsanitize=address` is passed (which we do).

My environment is centos 7 with gcc 4.8.5 and clang 3.4.2. It works fine with gcc but not clang - same as you on ubuntu.

[Reported upstream](https://llvm.org/bugs/show_bug.cgi?id=30333).

It seems like there is no resolution in sight to this in the upstream bug report. 

One guys says:

> Perhaps the easiest thing would be to make Clang ignore -Wl,--no-undefined (with a warning) when compiling with a sanitizer enabled. Presumably non-sanitized builds will perform the checks the user is looking for.

Then someone says:

> I've gone down that path previously and it breaks some people using -z defs as part of their configure checks.

Which meson doesn't have to care about - right? So maybe it's safe to have meson remove the `-Wl,--no-undefined` if a ASAN is specified?

Meson does not have functionality to set the default value of an option based on another option. Adding it would take a fair bit of work. 

Maybe output a warning or info string then? It took a fair bit of googling to figure out what was happening when I came across this issue.

setting `LDFLAGS=-lasan` seems to be a workaround for this issue.

Resolving patch:
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -3631,6 +3631,25 @@ def run(self):
         mlog.log('Build targets in project:', mlog.bold(str(len(self.build.targets))))
         FeatureNew.called_features_report()
         FeatureDeprecated.called_features_report()
+        if self.subproject == '':
+            self.print_extra_warnings()
+
+    def print_extra_warnings(self):
+        for c in self.build.compilers.values():
+            if c.get_id() == 'clang':
+                self.check_clang_asan_lundef()
+                break
+
+    def check_clang_asan_lundef(self):
+        if 'b_lundef' not in self.coredata.base_options:
+            return
+        if 'b_sanitize' not in self.coredata.base_options:
+            return
+        if 'address' in self.coredata.base_options['b_sanitize'].value:
+            if self.coredata.base_options['b_lundef'].value:
+                mlog.warning('''Trying to use address sanitizer on Clang with b_lundef.
+This will probably not work.
+Try setting b_lundef to false instead.''')
 
     def evaluate_subproject_info(self, path_from_source_root, subproject_dirname):
         depth = 0


Test patch: