Repository: mesonbuild/meson

Issue:
0.44 throws an exception when python is on another drive on Windows
### Steps to reproduce:

- change the drive, e.g.

> echo %cd%

`e:\projects\meson-relpath-issue`

- obtain the latest release of meson
> git clone https://github.com/mesonbuild/meson.git third_party/meson
> cd third_party\meson
> git checkout -b last-release 0.44.0
> cd ..\\..
- put ninja.exe into the current directory
- create meson.build with the following content

```
project('relpath_issue', license: ['GPL3'], meson_version: '0.44.0')

python = import('python3').find_python()

command = run_command(python, '-c', 'print("hello")')
```
- run meson
> py -3 third_party\meson build
### Observed error
> The Meson build system
> Version: 0.44.0
> Source dir: e:\projects\meson-relpath-issue
> Build dir: e:\projects\meson-relpath-issue\build
> Build type: native build
> Project name: relpath_issue
> Build machine cpu family: x86_64
> Build machine cpu: x86_64
> Traceback (most recent call last):
>   File "third_party\meson\mesonbuild\mesonmain.py", line 365, in run
>     app.generate()
>   File "third_party\meson\mesonbuild\mesonmain.py", line 151, in generate
>     self._generate(env)
>   File "third_party\meson\mesonbuild\mesonmain.py", line 199, in _generate
>     intr.run()
>   File "third_party\meson\mesonbuild\interpreter.py", line 2868, in run
>     super().run()
>   File "third_party\meson\mesonbuild\interpreterbase.py", line 171, in run
>     self.evaluate_codeblock(self.ast, start=1)
>   File "third_party\meson\mesonbuild\interpreterbase.py", line 193, in evaluate_codeblock
>     raise e
>   File "third_party\meson\mesonbuild\interpreterbase.py", line 187, in evaluate_codeblock
>     self.evaluate_statement(cur)
>   File "third_party\meson\mesonbuild\interpreterbase.py", line 200, in evaluate_statement
>     return self.assignment(cur)
>   File "third_party\meson\mesonbuild\interpreterbase.py", line 659, in assignment
>     value = self.evaluate_statement(node.value)
>   File "third_party\meson\mesonbuild\interpreterbase.py", line 198, in evaluate_statement
>     return self.function_call(cur)
>   File "third_party\meson\mesonbuild\interpreterbase.py", line 441, in function_call
>     return self.funcs[func_name](node, self.flatten(posargs), kwargs)
>   File "third_party\meson\mesonbuild\interpreterbase.py", line 47, in wrapped
>     return f(self, node, args, kwargs)
>   File "third_party\meson\mesonbuild\interpreter.py", line 1648, in func_run_command
>     return self.run_command_impl(node, args, kwargs)
>   File "third_party\meson\mesonbuild\interpreter.py", line 1673, in run_command_impl
>     cmd_path = os.path.relpath(cmd.get_path(), start=srcdir)
>   File "C:\Users\\-----\AppData\Local\Programs\Python\Python36\lib\ntpath.py", line 585, in relpath
>     path_drive, start_drive))
> ValueError: path is on mount 'C:', start on mount 'e:'


### Expected to work without errors, e.g.
> cd third_party\meson
> git reset --hard 0.43.0
> cd ..\\..
- change meson.build to use 0.43.0
> py -3 third_party\meson build

> The Meson build system
> Version: 0.43.0
> Source dir: e:\projects\meson-relpath-issue
> Build dir: e:\projects\meson-relpath-issue\build
> Build type: native build
> Project name: relpath_issue
> Build machine cpu family: x86_64
> Build machine cpu: x86_64
> Build targets in project: 0
> Found ninja-1.8.2 at '.\ninja.EXE'


Discussion:
This also happens when trying to run the unit tests with meson source on a different drive than Windows (due to the tests being built in the temp folder).

Resolving patch:
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1684,7 +1684,14 @@ def run_command_impl(self, node, args, kwargs, in_builddir=False):
                 raise InterpreterException('Program or command {!r} not found '
                                            'or not executable'.format(cmd))
             cmd = prog
-        cmd_path = os.path.relpath(cmd.get_path(), start=srcdir)
+        try:
+            cmd_path = os.path.relpath(cmd.get_path(), start=srcdir)
+        except ValueError:
+            # On Windows a relative path can't be evaluated for
+            # paths on two different drives (i.e. c:\foo and f:\bar).
+            # The only thing left to is is to use the original absolute
+            # path.
+            cmd_path = cmd.get_path()
         if not cmd_path.startswith('..') and cmd_path not in self.build_def_files:
             self.build_def_files.append(cmd_path)
         expanded_args = []


Test patch: