Repository: mesonbuild/meson

Issue:
Cross-file binaries not being used for ConfigTool (which LLVM depends on)
This is in the mesa build. When running with a cross file which contains

```
[binaries]
llvm-config = ''
```

It still finds my build machine's llvm-config and proceeds as if it was all fine:

```
The Meson build system
Version: 0.45.0.dev1
Source dir: /home/ilia/src/mesa-meson
Build dir: /home/ilia/src/mesa-meson/armv7-build
Build type: cross build
Program python found: YES (/usr/bin/python)
Project name: mesa
Native C compiler: cc (gcc 6.4.0 "gcc (Gentoo 6.4.0 p1.1) 6.4.0")
Cross C compiler: /usr/bin/armv7a-hardfloat-linux-gnueabi-gcc (gcc 4.9.4)
Native C++ compiler: c++ (gcc 6.4.0 "c++ (Gentoo 6.4.0 p1.1) 6.4.0")
Cross C++ compiler: /usr/bin/armv7a-hardfloat-linux-gnueabi-g++ (gcc 4.9.4)
...
Found llvm-config: /usr/lib/llvm/4/bin/llvm-config (4.0.1)
Dependency LLVM found: YES
```

The following patch makes things work, but not sure if that's the right approach:

```
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index e29d4de5..66f6b015 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -211,7 +211,21 @@ class ConfigToolDependency(ExternalDependency):
     def __init__(self, name, environment, language, kwargs):
         super().__init__('config-tool', environment, language, kwargs)
         self.name = name
-        self.tools = listify(kwargs.get('tools', self.tools))
+
+        if self.want_cross:
+            self.tools = []
+            if self.tool_name not in environment.cross_info.config['binaries']:
+                if self.required:
+                    raise DependencyException('%s binary missing from cross file' % self.tool_name)
+            else:
+                tool = environment.cross_info.config['binaries'][self.tool_name]
+                potential_toolbin = ExternalProgram(tool, silent=True)
+                if potential_toolbin.found():
+                    self.tools = [potential_toolbin.get_command()[0]]
+                else:
+                    mlog.debug('Cross %s not found.' % potential_toolbin.name)
+        else:
+            self.tools = listify(kwargs.get('tools', self.tools))
 
         req_version = kwargs.get('version', None)
         tool, version = self.find_config(req_version)
```

It seems like all this should be centralized a bit, but not 100% sure where.


Discussion:
I have a similar patch, I'll clean it up and send it. The only thing you're missing is support for the 'native' keyword. Especially with LLVM I could see someone needing to do some kind of bootrapping and wanted a native dependency, and that by putting this logic in the `find_config` method it can be simplified a bit.

Resolving patch:
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -211,6 +211,7 @@ class ConfigToolDependency(ExternalDependency):
     def __init__(self, name, environment, language, kwargs):
         super().__init__('config-tool', environment, language, kwargs)
         self.name = name
+        self.native = kwargs.get('native', False)
         self.tools = listify(kwargs.get('tools', self.tools))
 
         req_version = kwargs.get('version', None)
@@ -250,8 +251,20 @@ def find_config(self, versions=None):
         if not isinstance(versions, list) and versions is not None:
             versions = listify(versions)
 
+        if self.env.is_cross_build() and not self.native:
+            cross_file = self.env.cross_info.config['binaries']
+            try:
+                tools = [cross_file[self.tool_name]]
+            except KeyError:
+                mlog.warning('No entry for {0} specified in your cross file. '
+                             'Falling back to searching PATH. This may find a '
+                             'native version of {0}!'.format(self.tool_name))
+                tools = self.tools
+        else:
+            tools = self.tools
+
         best_match = (None, None)
-        for tool in self.tools:
+        for tool in tools:
             try:
                 p, out = Popen_safe([tool, '--version'])[:2]
             except (FileNotFoundError, PermissionError):


Test patch: