aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/ast/interpreter.py1
-rw-r--r--mesonbuild/backend/backends.py15
-rw-r--r--mesonbuild/build.py14
-rw-r--r--mesonbuild/interpreter/interpreter.py13
-rw-r--r--mesonbuild/interpreter/interpreterobjects.py3
-rw-r--r--mesonbuild/minstall.py18
6 files changed, 62 insertions, 2 deletions
diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py
index 7954b9b..ec93ff5 100644
--- a/mesonbuild/ast/interpreter.py
+++ b/mesonbuild/ast/interpreter.py
@@ -103,6 +103,7 @@ class AstInterpreter(InterpreterBase):
'install_man': self.func_do_nothing,
'install_data': self.func_do_nothing,
'install_subdir': self.func_do_nothing,
+ 'install_emptydir': self.func_do_nothing,
'configuration_data': self.func_do_nothing,
'configure_file': self.func_do_nothing,
'find_program': self.func_do_nothing,
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 6218156..3d8654e 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -120,6 +120,7 @@ class InstallData:
self.targets: T.List[TargetInstallData] = []
self.headers: T.List[InstallDataBase] = []
self.man: T.List[InstallDataBase] = []
+ self.emptydir: T.List[InstallEmptyDir] = []
self.data: T.List[InstallDataBase] = []
self.install_scripts: T.List[ExecutableSerialisation] = []
self.install_subdirs: T.List[SubdirInstallData] = []
@@ -147,6 +148,13 @@ class TargetInstallData:
self.optional = optional
self.tag = tag
+class InstallEmptyDir:
+ def __init__(self, path: str, install_mode: 'FileMode', subproject: str, tag: T.Optional[str] = None):
+ self.path = path
+ self.install_mode = install_mode
+ self.subproject = subproject
+ self.tag = tag
+
class InstallDataBase:
def __init__(self, path: str, install_path: str, install_path_name: str,
install_mode: 'FileMode', subproject: str, tag: T.Optional[str] = None,
@@ -1470,6 +1478,7 @@ class Backend:
self.generate_target_install(d)
self.generate_header_install(d)
self.generate_man_install(d)
+ self.generate_emptydir_install(d)
self.generate_data_install(d)
self.generate_custom_install_script(d)
self.generate_subdir_install(d)
@@ -1665,6 +1674,12 @@ class Backend:
i = InstallDataBase(srcabs, dstabs, dstname, m.get_custom_install_mode(), m.subproject, tag='man')
d.man.append(i)
+ def generate_emptydir_install(self, d: InstallData) -> None:
+ emptydir: T.List[build.EmptyDir] = self.build.get_emptydir()
+ for e in emptydir:
+ i = InstallEmptyDir(e.path, e.install_mode, e.subproject, e.install_tag)
+ d.emptydir.append(i)
+
def generate_data_install(self, d: InstallData) -> None:
data = self.build.get_data()
srcdir = self.environment.get_source_dir()
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 311732e..ef2210e 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -187,6 +187,16 @@ class Man(HoldableObject):
return self.sources
+class EmptyDir(HoldableObject):
+
+ def __init__(self, path: str, install_mode: 'FileMode', subproject: str,
+ install_tag: T.Optional[str] = None):
+ self.path = path
+ self.install_mode = install_mode
+ self.subproject = subproject
+ self.install_tag = install_tag
+
+
class InstallDir(HoldableObject):
def __init__(self, src_subdir: str, inst_subdir: str, install_dir: str,
@@ -239,6 +249,7 @@ class Build:
self.benchmarks: T.List['Test'] = []
self.headers: T.List[Headers] = []
self.man: T.List[Man] = []
+ self.emptydir: T.List[EmptyDir] = []
self.data: T.List[Data] = []
self.static_linker: PerMachine[StaticLinker] = PerMachine(None, None)
self.subprojects = {}
@@ -316,6 +327,9 @@ class Build:
def get_data(self) -> T.List['Data']:
return self.data
+ def get_emptydir(self) -> T.List['EmptyDir']:
+ return self.emptydir
+
def get_install_subdirs(self) -> T.List['InstallDir']:
return self.install_dirs
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 9a89b0c..8ac92c8 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -349,6 +349,7 @@ class Interpreter(InterpreterBase, HoldableObject):
'install_data': self.func_install_data,
'install_headers': self.func_install_headers,
'install_man': self.func_install_man,
+ 'install_emptydir': self.func_install_emptydir,
'install_subdir': self.func_install_subdir,
'is_disabler': self.func_is_disabler,
'is_variable': self.func_is_variable,
@@ -410,6 +411,7 @@ class Interpreter(InterpreterBase, HoldableObject):
build.AliasTarget: OBJ.AliasTargetHolder,
build.Headers: OBJ.HeadersHolder,
build.Man: OBJ.ManHolder,
+ build.EmptyDir: OBJ.EmptyDirHolder,
build.Data: OBJ.DataHolder,
build.InstallDir: OBJ.InstallDirHolder,
build.IncludeDirs: OBJ.IncludeDirsHolder,
@@ -1896,6 +1898,17 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
return m
+ @FeatureNew('install_emptydir', '0.60.0')
+ @typed_kwargs(
+ 'install_emptydir',
+ INSTALL_MODE_KW
+ )
+ def func_install_emptydir(self, node: mparser.BaseNode, args: T.Tuple[str], kwargs) -> None:
+ d = build.EmptyDir(args[0], kwargs['install_mode'], self.subproject)
+ self.build.emptydir.append(d)
+
+ return d
+
@FeatureNewKwargs('subdir', '0.44.0', ['if_found'])
@permittedKwargs({'if_found'})
@typed_pos_args('subdir', str)
diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py
index 072d2f0..b0447e6 100644
--- a/mesonbuild/interpreter/interpreterobjects.py
+++ b/mesonbuild/interpreter/interpreterobjects.py
@@ -646,6 +646,9 @@ class InstallDirHolder(ObjectHolder[build.InstallDir]):
class ManHolder(ObjectHolder[build.Man]):
pass
+class EmptyDirHolder(ObjectHolder[build.EmptyDir]):
+ pass
+
class GeneratedObjectsHolder(ObjectHolder[build.ExtractedObjects]):
pass
diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py
index 6284f95..7864742 100644
--- a/mesonbuild/minstall.py
+++ b/mesonbuild/minstall.py
@@ -25,7 +25,7 @@ import sys
import typing as T
from . import environment
-from .backend.backends import InstallData, InstallDataBase, TargetInstallData, ExecutableSerialisation
+from .backend.backends import InstallData, InstallDataBase, InstallEmptyDir, TargetInstallData, ExecutableSerialisation
from .coredata import major_versions_differ, MesonVersionMismatchException
from .coredata import version as coredata_version
from .mesonlib import Popen_safe, RealPathAction, is_windows
@@ -370,7 +370,7 @@ class Installer:
return run_exe(*args, **kwargs)
return 0
- def should_install(self, d: T.Union[TargetInstallData, InstallDataBase, ExecutableSerialisation]) -> bool:
+ def should_install(self, d: T.Union[TargetInstallData, InstallEmptyDir, InstallDataBase, ExecutableSerialisation]) -> bool:
if d.subproject and (d.subproject in self.skip_subprojects or '*' in self.skip_subprojects):
return False
if self.tags and d.tag not in self.tags:
@@ -531,6 +531,7 @@ class Installer:
self.install_targets(d, dm, destdir, fullprefix)
self.install_headers(d, dm, destdir, fullprefix)
self.install_man(d, dm, destdir, fullprefix)
+ self.install_emptydir(d, dm, destdir, fullprefix)
self.install_data(d, dm, destdir, fullprefix)
self.restore_selinux_contexts(destdir)
self.apply_ldconfig(destdir)
@@ -581,6 +582,19 @@ class Installer:
self.did_install_something = True
self.set_mode(outfilename, m.install_mode, d.install_umask)
+ def install_emptydir(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix: str) -> None:
+ for e in d.emptydir:
+ if not self.should_install(e):
+ continue
+ self.did_install_something = True
+ full_dst_dir = get_destdir_path(destdir, fullprefix, e.path)
+ self.log(f'Installing new directory {full_dst_dir}')
+ if os.path.isfile(full_dst_dir):
+ print(f'Tried to create directory {full_dst_dir} but a file of that name already exists.')
+ sys.exit(1)
+ dm.makedirs(full_dst_dir, exist_ok=True)
+ self.set_mode(full_dst_dir, e.install_mode, d.install_umask)
+
def install_headers(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix: str) -> None:
for t in d.headers:
if not self.should_install(t):