mirror of
https://github.com/mesonbuild/meson.git
synced 2026-06-30 19:57:45 +00:00
Convert configure command path and prefix to unix style on windows
On Cygwin, MSYS2 and GitBash, the configure command and the prefix should be converted to unix style path by cygpath command, because the colon in the drive letter breaks many configure scripts. This also fixes bugs of previous approach where leading slash was missing from prefix and it sometimes use wrong directory as base path. In addition removing drive letter should be done on rel_prefix only.
This commit is contained in:
committed by
Paolo Bonzini
parent
57820c92ea
commit
9de3a8fddd
@@ -0,0 +1,7 @@
|
||||
## The external_project module uses the cygpath command to convert paths
|
||||
|
||||
In previous versions, the external_project module on Windows used a Windows-style path (e.g., `C:/path/to/configure`) to execute the configure file, and a relative path from the drive root (e.g., `/path/to/prefix`) as the installation prefix.
|
||||
However, since configure scripts are typically intended to be run in a POSIX-like environment (MSYS2, Cygwin, or GitBash), these paths were incompatible with some configure scripts.
|
||||
|
||||
The external_project module now uses the `cygpath` command to convert the configure command path and prefix to Unix-style paths (e.g., `/c/path/to/configure` for MSYS2 and `/cygdrive/c/path/to/configure` for Cygwin).
|
||||
If the `cygpath` command is not found in the PATH, it will fall back to the previous behavior.
|
||||
@@ -6,6 +6,7 @@ from __future__ import annotations
|
||||
from pathlib import Path
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import typing as T
|
||||
|
||||
@@ -19,7 +20,7 @@ from ..interpreterbase import FeatureNew
|
||||
from ..interpreter.type_checking import ENV_KW, DEPENDS_KW
|
||||
from ..interpreterbase.decorators import ContainerTypeInfo, KwargInfo, typed_kwargs, typed_pos_args
|
||||
from ..mesonlib import (EnvironmentException, MesonException, Popen_safe, MachineChoice,
|
||||
get_variable_regex, do_replacement, join_args, relpath)
|
||||
get_variable_regex, do_replacement, join_args)
|
||||
from ..options import OptionKey
|
||||
|
||||
if T.TYPE_CHECKING:
|
||||
@@ -89,19 +90,29 @@ class ExternalProject(NewExtensionModule):
|
||||
self.includedir = Path(_i)
|
||||
self.name = self.src_dir.name
|
||||
|
||||
# On Windows if the prefix is "c:/foo" and DESTDIR is "c:/bar", `make`
|
||||
# will install files into "c:/bar/c:/foo" which is an invalid path.
|
||||
# Work around that issue by removing the drive from prefix.
|
||||
if self.prefix.drive:
|
||||
self.prefix = Path(relpath(self.prefix, self.prefix.drive))
|
||||
self.prefix = self._cygpath_convert(self.prefix)
|
||||
|
||||
# self.prefix is an absolute path, so we cannot append it to another path.
|
||||
self.rel_prefix = Path(relpath(self.prefix, self.prefix.root))
|
||||
# On Windows (where cygpath is not applied),
|
||||
# if the prefix is "c:/foo" and DESTDIR is "c:/bar",
|
||||
# `make` will install files into "c:/bar/c:/foo" which is an invalid path.
|
||||
# This also removes the drive letter from the prefix to workaround the issue.
|
||||
self.rel_prefix = self.prefix.relative_to(self.prefix.anchor)
|
||||
|
||||
self._configure(state)
|
||||
|
||||
self.targets = self._create_targets(extra_depends)
|
||||
|
||||
def _cygpath_convert(self, winpath: Path) -> Path:
|
||||
# On Cygwin, MSYS2 and GitBash, the configure command and the prefix
|
||||
# should be converted to unix style path like "/c/foo" by cygpath command,
|
||||
# because the colon in the drive letter breaks many configure scripts.
|
||||
# Do nothing on other environment where cygpath is not available.
|
||||
if winpath.drive and shutil.which('cygpath'):
|
||||
_p, o, _e = Popen_safe(['cygpath', '-u', winpath.as_posix()])
|
||||
return Path(o.strip('\n'))
|
||||
return winpath
|
||||
|
||||
def _configure(self, state: 'ModuleState') -> None:
|
||||
if self.configure_command == 'waf':
|
||||
FeatureNew('Waf external project', '0.60.0').use(self.subproject, state.current_node)
|
||||
@@ -116,6 +127,8 @@ class ExternalProject(NewExtensionModule):
|
||||
configure_path = Path(self.src_dir, self.configure_command)
|
||||
configure_prog = state.find_program(configure_path.as_posix())
|
||||
configure_cmd = configure_prog.get_command()
|
||||
if len(configure_cmd) >= 2 and configure_cmd[-1] == configure_path.as_posix():
|
||||
configure_cmd = configure_cmd[:-1] + [self._cygpath_convert(configure_path).as_posix()]
|
||||
workdir = self.build_dir
|
||||
self.make = state.find_program('make').get_command()
|
||||
|
||||
|
||||
@@ -2,6 +2,23 @@
|
||||
|
||||
srcdir=$(dirname "$0")
|
||||
|
||||
# some configure scripts seem to iterate over srcdir and other paths
|
||||
# with for-loop using path_separator (most cases colon.)
|
||||
PATH_SEPARATOR=:
|
||||
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
|
||||
(PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
|
||||
PATH_SEPARATOR=';'
|
||||
}
|
||||
IFS=$PATH_SEPARATOR
|
||||
for i in $srcdir
|
||||
do
|
||||
if [ "$i" != "$srcdir" ]
|
||||
then
|
||||
echo "failed to extract $srcdir using path separator $PATH_SEPARATOR"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
for i in "$@"
|
||||
do
|
||||
case $i in
|
||||
|
||||
Reference in New Issue
Block a user