mirror of
https://github.com/mesonbuild/meson.git
synced 2026-11-06 05:16:42 +00:00
mesonlib: introduce as_posix
Introduce a new function that can be used to join and normalize paths, and canonicalize them to forward slashes. It avoids (or rather hides) use of pathlib for string->string operations. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
1 parent
c7fd49a490
commit
7fdfe0eb47
16 files changed
+54
-44
No files matched your search
@@ -27,7 +27,7 @@ from .. import mlog
|
||||
from .. import compilers
|
||||
from ..compilers import detect
|
||||
from ..mesonlib import (
|
||||
File, MachineChoice, MesonException, MesonBugException, OrderedSet,
|
||||
as_posix, File, MachineChoice, MesonException, MesonBugException, OrderedSet,
|
||||
ExecutableSerialisation, FileMode, InstallScriptFailure,
|
||||
classify_unity_sources, get_compiler_for_source,
|
||||
get_rsp_threshold, unique_list
|
||||
@@ -374,16 +374,16 @@ class Backend:
|
||||
link_lib = target.get_import_filename() or target.get_filename()
|
||||
# In AIX, if we archive .so, the blibpath must link to archived shared library otherwise to the .so file.
|
||||
link_lib = self.get_aix_so_archive_name(target, link_lib) or link_lib
|
||||
return Path(self.get_target_dir(target), link_lib).as_posix()
|
||||
return as_posix(self.get_target_dir(target), link_lib)
|
||||
elif isinstance(target, build.StaticLibrary):
|
||||
return Path(self.get_target_dir(target), target.get_filename()).as_posix()
|
||||
return as_posix(self.get_target_dir(target), target.get_filename())
|
||||
elif isinstance(target, (build.CustomTarget, build.CustomTargetIndex)):
|
||||
if not target.is_linkable_target():
|
||||
raise MesonException(f'Tried to link against custom target "{target.name}", which is not linkable.')
|
||||
return Path(self.get_target_dir(target), target.get_filename()).as_posix()
|
||||
return as_posix(self.get_target_dir(target), target.get_filename())
|
||||
elif isinstance(target, build.Executable):
|
||||
if target.import_filename:
|
||||
return Path(self.get_target_dir(target), target.get_import_filename()).as_posix()
|
||||
return as_posix(self.get_target_dir(target), target.get_import_filename())
|
||||
else:
|
||||
return None
|
||||
raise AssertionError(f'BUG: Tried to link to {target!r} which is not linkable')
|
||||
|
||||
@@ -33,7 +33,7 @@ from ..mesonlib import (
|
||||
File, LibType, MachineChoice, MesonBugException, MesonException, OrderedSet, PerMachine,
|
||||
ProgressBar, quote_arg, unique_list
|
||||
)
|
||||
from ..mesonlib import get_compiler_for_source, has_path_sep, is_parent_path, lookbehind, path_has_root
|
||||
from ..mesonlib import as_posix, get_compiler_for_source, has_path_sep, is_parent_path, lookbehind, path_has_root
|
||||
from ..options import OptionKey
|
||||
from .backends import CleanTrees
|
||||
from ..build import GeneratedList, InvalidArguments
|
||||
@@ -1341,7 +1341,7 @@ class NinjaBackend(backends.Backend):
|
||||
elem.add_item('DEPFILE', rel_dfile)
|
||||
if target.console:
|
||||
elem.add_item('pool', 'console')
|
||||
full_name = Path(target.subdir, target.name).as_posix()
|
||||
full_name = as_posix(target.subdir, target.name)
|
||||
elem.add_item('COMMAND', cmd)
|
||||
elem.add_item('description', target.description.format(full_name) + cmd_type)
|
||||
self.add_build(elem)
|
||||
|
||||
+4
-4
@@ -21,7 +21,7 @@ from . import mlog
|
||||
from . import programs
|
||||
from .environment import MachineMap
|
||||
from .mesonlib import (
|
||||
HoldableObject, SecondLevelHolder, SimpleABC, SubProject,
|
||||
as_posix, HoldableObject, SecondLevelHolder, SimpleABC, SubProject,
|
||||
File, MesonException, MachineChoice, ThreeMachineChoice, PerMachine,
|
||||
OrderedSet, classify_unity_sources, ROOT_SUBPROJECT,
|
||||
get_filenames_templates_dict, substitute_values, has_path_sep,
|
||||
@@ -776,11 +776,11 @@ class StructuredSources(HoldableObject):
|
||||
def canonicalize(path: str) -> str:
|
||||
"""Canonicalize a path within the structure.
|
||||
|
||||
The root of the structure is spelled as an empty string.
|
||||
Like as_posix, but the root of the structure is spelled as an empty string.
|
||||
"""
|
||||
if not path:
|
||||
return ''
|
||||
path = pathlib.PurePath(os.path.normpath(path)).as_posix()
|
||||
path = as_posix(path)
|
||||
return '' if path == '.' else path
|
||||
|
||||
def extend(self, path: str, sources: T.Iterable[TargetSources]) -> None:
|
||||
@@ -1396,7 +1396,7 @@ class BuildTarget(Target, BuildTargetProto):
|
||||
break
|
||||
else:
|
||||
if is_known_suffix(s) and not is_header(s):
|
||||
path = pathlib.Path(str(s)).as_posix()
|
||||
path = as_posix(str(s))
|
||||
m = f'No {self.for_machine.get_lower_case_name()} machine compiler for {path!r}'
|
||||
raise MesonException(m)
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ from .manifest import (
|
||||
validate_patch,
|
||||
)
|
||||
from ..mesonlib import (
|
||||
is_parent_path, lazy_property, MesonException, MachineChoice,
|
||||
as_posix, is_parent_path, lazy_property, MesonException, MachineChoice,
|
||||
PerMachine, unique_list, SubProject,
|
||||
)
|
||||
from .. import coredata, mlog
|
||||
@@ -519,7 +519,7 @@ class Interpreter:
|
||||
|
||||
if extra_members is not None:
|
||||
for m in extra_members:
|
||||
m = PurePath(m).as_posix()
|
||||
m = as_posix(m)
|
||||
if m not in workspace.members:
|
||||
l = ', '.join(sorted(list(workspace.members)))
|
||||
raise MesonException(f'{m} is not a workspace member for {subdir}/Cargo.toml (valid members are {l})')
|
||||
|
||||
@@ -11,11 +11,10 @@ import glob
|
||||
import os
|
||||
import re
|
||||
import typing as T
|
||||
from pathlib import PurePath
|
||||
|
||||
|
||||
from . import version
|
||||
from ..mesonlib import MesonException, is_parent_path, lazy_property, MachineChoice
|
||||
from ..mesonlib import MesonException, as_posix, is_parent_path, lazy_property, MachineChoice
|
||||
from .. import mlog
|
||||
|
||||
if T.TYPE_CHECKING:
|
||||
@@ -733,7 +732,7 @@ class Workspace:
|
||||
}
|
||||
|
||||
def is_excluded(self, path: str) -> bool:
|
||||
path = PurePath(path).as_posix()
|
||||
path = as_posix(path)
|
||||
if '.' in self.exclude:
|
||||
# If the workspace directory is excluded, so is everything below it,
|
||||
# even explicitly listed members (Cargo weirdness), but the root
|
||||
@@ -755,10 +754,10 @@ class Workspace:
|
||||
ws.patch = raw.get('patch')
|
||||
ws.profile = {k: Profile.from_raw(v) for k, v in raw.get('profile', {}).items()}
|
||||
|
||||
ws.members = list(PurePath(m).as_posix() for m in ws.members)
|
||||
ws.exclude = list(PurePath(e).as_posix() for e in ws.exclude)
|
||||
ws.members = list(as_posix(m) for m in ws.members)
|
||||
ws.exclude = list(as_posix(e) for e in ws.exclude)
|
||||
if ws.default_members:
|
||||
ws.default_members = list(PurePath(m).as_posix() for m in ws.default_members)
|
||||
ws.default_members = list(as_posix(m) for m in ws.default_members)
|
||||
else:
|
||||
ws.default_members = ['.'] if ws.root_package else list(ws.members)
|
||||
|
||||
@@ -773,7 +772,7 @@ class Workspace:
|
||||
continue
|
||||
|
||||
if keep_glob_results:
|
||||
expanded.extend(PurePath(exp).as_posix()
|
||||
expanded.extend(as_posix(exp)
|
||||
for exp in glob.glob(entry, root_dir=path)
|
||||
if os.path.isdir(os.path.join(path, exp)))
|
||||
return literals, expanded
|
||||
|
||||
@@ -25,7 +25,7 @@ from ... import arglist
|
||||
from ... import mesonlib
|
||||
from ... import mlog
|
||||
from ...linkers.linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker, CompCertDynamicLinker
|
||||
from ...mesonlib import LibType
|
||||
from ...mesonlib import as_posix, LibType
|
||||
from .. import compilers
|
||||
from ..compilers import CompileCheckMode
|
||||
from .visualstudio import VisualStudioLikeCompiler
|
||||
@@ -1197,7 +1197,7 @@ class CLikeCompiler(Compiler):
|
||||
continue
|
||||
if libname.startswith('lib') and trial_result.startswith(libname) and lib_prefix_warning:
|
||||
mlog.warning(f'find_library({libname!r}) starting in "lib" only works by accident and is not portable')
|
||||
return [Path(trial_result).as_posix()]
|
||||
return [as_posix(trial_result)]
|
||||
return None
|
||||
|
||||
def _find_library_impl(self, libname: str, extra_dirs: T.List[str], code: str, libtype: LibType,
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .base import ExternalDependency, DependencyException, sort_libpaths, DependencyTypeName
|
||||
from ..mesonlib import (EnvironmentVariables, OrderedSet, PerMachine, Popen_safe, Popen_safe_logged, MachineChoice,
|
||||
join_args, MesonException, path_has_root)
|
||||
from ..mesonlib import (as_posix, EnvironmentVariables, OrderedSet, PerMachine, Popen_safe, Popen_safe_logged,
|
||||
MachineChoice, join_args, MesonException, path_has_root)
|
||||
from ..options import OptionKey
|
||||
from ..programs import find_external_program, ExternalProgram
|
||||
from .. import mlog
|
||||
from enum import Enum
|
||||
from pathlib import Path, PurePath
|
||||
from pathlib import PurePath
|
||||
from functools import lru_cache
|
||||
import re
|
||||
import os
|
||||
@@ -287,7 +287,7 @@ class PkgConfigCLI(PkgConfigInterface):
|
||||
bpath = self.env.get_build_dir()
|
||||
if bpath is not None:
|
||||
# uninstalled can only be used if a build dir exists.
|
||||
uninstalled_path = Path(bpath, 'meson-uninstalled').as_posix()
|
||||
uninstalled_path = as_posix(bpath, 'meson-uninstalled')
|
||||
if uninstalled_path not in extra_paths:
|
||||
extra_paths.insert(0, uninstalled_path)
|
||||
env.set('PKG_CONFIG_PATH', extra_paths)
|
||||
|
||||
@@ -9,7 +9,6 @@ from __future__ import annotations
|
||||
import abc
|
||||
import re
|
||||
import os
|
||||
from pathlib import Path
|
||||
import typing as T
|
||||
|
||||
from .base import DependencyException, DependencyMethods
|
||||
@@ -53,7 +52,7 @@ def _qt_get_private_includes(mod_inc_dir: str, module: str, mod_version: str) ->
|
||||
if len(dirname.split('.')) == 3:
|
||||
private_dir = dirname
|
||||
break
|
||||
return [private_dir, Path(private_dir, f'Qt{module}').as_posix()]
|
||||
return [private_dir, mesonlib.as_posix(private_dir, f'Qt{module}')]
|
||||
|
||||
|
||||
def get_qmake_host_bins(qvars: T.Dict[str, str]) -> str:
|
||||
@@ -322,7 +321,7 @@ class QmakeQtDependency(_QtBase, ConfigToolDependency, metaclass=mesonlib.Simple
|
||||
modules_lib_suffix = _get_modules_lib_suffix(self.version, self.env.machines[self.for_machine], is_debug)
|
||||
|
||||
for module in self.requested_modules:
|
||||
mincdir = Path(incdir, f'Qt{module}').as_posix()
|
||||
mincdir = mesonlib.as_posix(incdir, f'Qt{module}')
|
||||
self.compile_args.append('-I' + mincdir)
|
||||
|
||||
if module == 'QuickTest':
|
||||
|
||||
@@ -7,7 +7,7 @@ import textwrap
|
||||
import threading
|
||||
import sys
|
||||
|
||||
from pathlib import Path, PurePath
|
||||
from pathlib import Path
|
||||
|
||||
from .. import mesonlib
|
||||
from .. import build
|
||||
@@ -29,7 +29,7 @@ from ..interpreter.type_checking import (
|
||||
)
|
||||
from ..dependencies import Dependency, ExternalLibrary, InternalDependency
|
||||
from ..programs import Program
|
||||
from ..mesonlib import File, HoldableObject, listify, MachineChoice, MesonException
|
||||
from ..mesonlib import as_posix, File, HoldableObject, listify, MachineChoice, MesonException
|
||||
|
||||
import typing as T
|
||||
|
||||
@@ -891,7 +891,7 @@ class SubprojectHolder(MesonInterpreterObject):
|
||||
self.warnings = warnings
|
||||
self.disabled_feature = disabled_feature
|
||||
self.exception = exception
|
||||
self.subdir = PurePath(subdir).as_posix()
|
||||
self.subdir = as_posix(subdir)
|
||||
self.cm_interpreter: T.Optional[CMakeInterpreter] = None
|
||||
self.callstack = callstack
|
||||
|
||||
|
||||
@@ -316,7 +316,7 @@ def find_buildsystem_files_list(src_dir: str) -> T.List[str]:
|
||||
|
||||
def list_buildsystem_files(coredata: cdata.CoreData, builddata: build.Build, backend: backends.Backend) -> T.List[str]:
|
||||
src_dir = builddata.environment.get_source_dir()
|
||||
filelist = [PurePath(src_dir, x).as_posix() for x in builddata.def_files]
|
||||
filelist = [mesonlib.as_posix(src_dir, x) for x in builddata.def_files]
|
||||
return filelist
|
||||
|
||||
def list_compilers(coredata: cdata.CoreData, builddata: build.Build, backend: backends.Backend) -> T.Dict[str, T.Dict[str, T.Dict[str, str]]]:
|
||||
|
||||
@@ -415,7 +415,7 @@ class CmakeModule(ExtensionModule):
|
||||
abs_install_dir = os.path.join(prefix, install_dir)
|
||||
|
||||
# path used in cmake scripts are POSIX even on Windows
|
||||
PACKAGE_RELATIVE_PATH = pathlib.PurePath(os.path.relpath(prefix, abs_install_dir)).as_posix()
|
||||
PACKAGE_RELATIVE_PATH = mesonlib.as_posix(prefix, relative_to=abs_install_dir)
|
||||
extra = ''
|
||||
if re.match('^(/usr)?/lib(64)?/.+', abs_install_dir):
|
||||
extra = PACKAGE_INIT_EXT.replace('@absInstallDir@', abs_install_dir)
|
||||
|
||||
@@ -8,7 +8,6 @@ from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import itertools
|
||||
import pathlib
|
||||
import functools
|
||||
import os
|
||||
import subprocess
|
||||
@@ -1026,7 +1025,7 @@ class GnomeModule(ExtensionModule):
|
||||
# g-ir-scanner uses distutils/setuptools which splits CC with both Posix
|
||||
# and Windows rules to get the first argument, which breaks if there are
|
||||
# backslashes, so best avoid them entirely.
|
||||
cc_exelist = [pathlib.Path(exe).as_posix() for exe in cc_exelist]
|
||||
cc_exelist = [mesonlib.as_posix(exe) for exe in cc_exelist]
|
||||
run_env.set('CC', [quote_arg(x) for x in cc_exelist], ' ')
|
||||
run_env.set('CFLAGS', [quote_arg(x) for x in env_flags], ' ')
|
||||
run_env.merge(kwargs['env'])
|
||||
|
||||
@@ -16,7 +16,7 @@ import zipfile
|
||||
|
||||
from . import mlog
|
||||
from .ast import IntrospectionInterpreter
|
||||
from .mesonlib import quiet_git, GitException, Popen_safe, MesonException, windows_proof_rmtree
|
||||
from .mesonlib import as_posix, quiet_git, GitException, Popen_safe, MesonException, windows_proof_rmtree
|
||||
from .wrap.wrap import (Resolver, WrapException, WrapType,
|
||||
parse_patch_url, update_wrap_file, get_releases)
|
||||
|
||||
@@ -753,7 +753,7 @@ def run(options: 'Arguments') -> int:
|
||||
pre_func(options)
|
||||
logger = Logger(len(wraps))
|
||||
for wrap in wraps:
|
||||
dirname = Path(source_dir, subproject_dir, wrap.directory).as_posix()
|
||||
dirname = as_posix(source_dir, subproject_dir, wrap.directory)
|
||||
runner = Runner(logger, r, wrap, dirname, options)
|
||||
task = loop.run_in_executor(executor, runner.run)
|
||||
tasks.append(task)
|
||||
|
||||
@@ -99,6 +99,7 @@ __all__ = [
|
||||
'RealPathAction',
|
||||
'TemporaryDirectoryWinProof',
|
||||
'Version',
|
||||
'as_posix',
|
||||
'check_direntry_issues',
|
||||
'classify_unity_sources',
|
||||
'current_vs_supports_modules',
|
||||
@@ -1356,6 +1357,18 @@ def determine_worker_count(varnames: T.Optional[T.List[str]] = None) -> int:
|
||||
num_workers = 1
|
||||
return num_workers
|
||||
|
||||
def as_posix(*args: str, relative_to: T.Optional[str] = None) -> str:
|
||||
'''Join and normalize @args into a path that uses forward slashes as the separator,
|
||||
so that it can be compared with other paths and used as a dictionary key. If
|
||||
@relative_to is given, the result is relative to that directory.'''
|
||||
path = os.path.normpath(os.path.join(*args))
|
||||
if relative_to is not None:
|
||||
path = os.path.relpath(path, relative_to)
|
||||
if is_windows():
|
||||
path = path.replace('\\', '/')
|
||||
return path
|
||||
|
||||
|
||||
def is_parent_path(parent: str, trial: str) -> bool:
|
||||
'''Checks if @trial is a file under the directory @parent. Both @trial and @parent should be
|
||||
adequately normalized, though empty and '.' segments in @parent and @trial are accepted
|
||||
|
||||
@@ -26,13 +26,13 @@ import gzip
|
||||
from base64 import b64encode
|
||||
from enum import Enum
|
||||
from netrc import netrc
|
||||
from pathlib import Path, PurePath
|
||||
from pathlib import Path
|
||||
from functools import lru_cache
|
||||
|
||||
from . import WrapMode
|
||||
from .. import coredata
|
||||
from ..mesonlib import (
|
||||
DirectoryLock, DirectoryLockAction, quiet_git, GIT, ProgressBar, MesonException,
|
||||
as_posix, DirectoryLock, DirectoryLockAction, quiet_git, GIT, ProgressBar, MesonException,
|
||||
windows_proof_rmtree, Popen_safe, SubProject,
|
||||
)
|
||||
from ..interpreterbase import FeatureNew
|
||||
@@ -585,7 +585,7 @@ class Resolver:
|
||||
with open(main_fname, 'w', encoding='utf-8') as f:
|
||||
f.write(textwrap.dedent(f'''\
|
||||
[wrap-redirect]
|
||||
filename = {PurePath(os.path.relpath(self.wrap.original_filename, self.subdir_root)).as_posix()}
|
||||
filename = {as_posix(self.wrap.original_filename, relative_to=self.subdir_root)}
|
||||
'''))
|
||||
|
||||
# Map each supported method to a file that must exist at the root of source tree.
|
||||
@@ -997,7 +997,7 @@ class Resolver:
|
||||
# Always pass a POSIX path to patch, because on Windows it's MSYS
|
||||
# Ignore whitespace when applying patches to workaround
|
||||
# line-ending differences
|
||||
cmd = [patch_command(), '-l', '-f', '-p1', '-i', str(Path(relpath).as_posix())]
|
||||
cmd = [patch_command(), '-l', '-f', '-p1', '-i', as_posix(relpath)]
|
||||
elif GIT:
|
||||
# If the `patch` command is not available, fall back to `git
|
||||
# apply`. The `--work-tree` is necessary in case we're inside a
|
||||
|
||||
@@ -38,7 +38,7 @@ from mesonbuild.mesonlib import (
|
||||
is_sunos, windows_proof_rmtree, python_command, version_compare, split_args, quote_arg,
|
||||
relpath, is_linux, git, search_version, do_conf_file, do_conf_str, default_prefix,
|
||||
SubProject, MesonException, EnvironmentException,
|
||||
windows_proof_rm, first
|
||||
as_posix, windows_proof_rm, first
|
||||
)
|
||||
from mesonbuild.options import OptionKey
|
||||
from mesonbuild.programs import ExternalProgram
|
||||
@@ -2126,7 +2126,7 @@ class AllPlatformTests(BasePlatformTests):
|
||||
Version: 1.0.0
|
||||
Libs: {}
|
||||
''').format(
|
||||
Path(linkfile).as_posix().replace(' ', r'\ '),
|
||||
as_posix(linkfile).replace(' ', r'\ '),
|
||||
))
|
||||
|
||||
# Run the test
|
||||
|
||||
Reference in new issue
Block a user