Repository: mesonbuild/meson

Issue:
Compiler base options ('b_lundef', 'b_asneeded', etc) are not always valid for the cross-compiler
Have `-Wl,--no-undefined` and `-Wl,--as-needed` any meaning when cross-comliling?
In case of cross-compilation linker can't check for this correctly, I'm wrong?

I'm asking because cross-compiler to macosx ([osxcross](https://github.com/tpoechtrager/osxcross)) does not support these options, and I'm unsure is this bug of that toolchain, or bug of meson?


Discussion:
I don't see why the linker wouldn't be able to check such things? Certainly clang natively on OSX can do it.

This is related to #1040. Basically, right now we set the same compiler and build options on both the native and the cross compiler. We need to think of a way to fix this and make it such that only options that are common to both are applied, and that the rest can be overridden in the cross-info file.
If an option is valid for the native compiler but not cross compiler, then the cross compiler will just ignore that option (and vice versa). The question really is whether we want to have an option that is valid on both compilers but has opposite values.

I would really, _really_, **really** like to not have to support that. It complicates the implementation and common case a lot because _all_ options become duplicated. Having only one setting for forbidding missing symbols (and for all compiler options really) seems like a reasonable limitation to have.

Note that we already have a similar limitation. Many options (including lundef) is the same across languages, so you can't, for example, permit missing symbols in C++ libraries but forbid them in plain C libraries.
> then the cross compiler will just ignore that option (and vice versa).

This one - does not:
```
meson build --buildtype release^
 --cross-file compilers\osx-clang-64.txt^
 -D b_lundef=false -D b_asneeded=false
ninja -C build
```

```
.....
ninja: Entering directory `build'
[1/2] Compiling c object hello@exe/hello.c.o
[2/2] Linking target hello
FAILED: hello 
c:/cygwin-cross/bin/x86_64-apple-darwin14-clang @hello.rsp
ld: unknown option: -O1
clang-3.8: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
Command exited with code 1
```
Full log here - https://ci.appveyor.com/project/msink/hello-c/build/job/e5ejhl0onqa9mrdo
Project - https://github.com/msink/hello-c
As I can see, actually compiler.py have some special cases for 'b_lundef', 'b_asneeded' and -Wl,O1 on OSX, but only in native mode.
And cross-compiling for OSX is detected in environment.for_darwin()
So everything is in place, but not connected :)

Resolving patch:
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -103,23 +103,19 @@ def is_library(fname):
                        'minsize': ["/MD", "/Zi", "/Os", "/Ob1"],
                        }
 
-gnulike_buildtype_linker_args = {}
-
-
-if mesonlib.is_osx():
-    gnulike_buildtype_linker_args.update({'plain': [],
-                                          'debug': [],
-                                          'debugoptimized': [],
-                                          'release': [],
-                                          'minsize': [],
-                                          })
-else:
-    gnulike_buildtype_linker_args.update({'plain': [],
-                                          'debug': [],
-                                          'debugoptimized': [],
-                                          'release': ['-Wl,-O1'],
-                                          'minsize': [],
-                                          })
+apple_buildtype_linker_args = {'plain': [],
+                               'debug': [],
+                               'debugoptimized': [],
+                               'release': [],
+                               'minsize': [],
+                               }
+
+gnulike_buildtype_linker_args = {'plain': [],
+                                 'debug': [],
+                                 'debugoptimized': [],
+                                 'release': ['-Wl,-O1'],
+                                 'minsize': [],
+                                 }
 
 msvc_buildtype_linker_args = {'plain': [],
                               'debug': [],
@@ -286,12 +282,12 @@ def get_base_link_args(options, linker, is_shared_module):
     except KeyError:
         pass
     try:
-        if not is_shared_module and options['b_lundef'].value:
+        if not is_shared_module and 'b_lundef' in linker.base_options and options['b_lundef'].value:
             args.append('-Wl,--no-undefined')
     except KeyError:
         pass
     try:
-        if options['b_asneeded'].value:
+        if 'b_asneeded' in linker.base_options and options['b_asneeded'].value:
             args.append('-Wl,--as-needed')
     except KeyError:
         pass
@@ -2128,6 +2124,8 @@ def get_buildtype_args(self, buildtype):
         return gnulike_buildtype_args[buildtype]
 
     def get_buildtype_linker_args(self, buildtype):
+        if self.gcc_type == GCC_OSX:
+            return apple_buildtype_linker_args[buildtype]
         return gnulike_buildtype_linker_args[buildtype]
 
     def get_always_args(self):
@@ -2275,6 +2273,8 @@ def get_buildtype_args(self, buildtype):
         return gnulike_buildtype_args[buildtype]
 
     def get_buildtype_linker_args(self, buildtype):
+        if self.clang_type == CLANG_OSX:
+            return apple_buildtype_linker_args[buildtype]
         return gnulike_buildtype_linker_args[buildtype]
 
     def get_pch_suffix(self):
@@ -2435,6 +2435,8 @@ def get_buildtype_args(self, buildtype):
         return gnulike_buildtype_args[buildtype]
 
     def get_buildtype_linker_args(self, buildtype):
+        if mesonlib.is_osx():
+            return apple_buildtype_linker_args[buildtype]
         return gnulike_buildtype_linker_args[buildtype]
 
     def split_shlib_to_parts(self, fname):
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -386,7 +386,7 @@ def detect_c_compiler(self, want_cross):
                 version = self.get_gnu_version_from_defines(defines)
                 return GnuCCompiler(ccache + [compiler], version, gtype, is_cross, exe_wrap, defines)
             if 'clang' in out:
-                if 'Apple' in out:
+                if 'Apple' in out or for_darwin(want_cross, self):
                     cltype = CLANG_OSX
                 else:
                     cltype = CLANG_STANDARD


Test patch: