aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Installing.md14
-rw-r--r--docs/markdown/snippets/meson_install_elevate.md9
-rw-r--r--mesonbuild/minstall.py22
3 files changed, 39 insertions, 6 deletions
diff --git a/docs/markdown/Installing.md b/docs/markdown/Installing.md
index a692afe..0bc9a47 100644
--- a/docs/markdown/Installing.md
+++ b/docs/markdown/Installing.md
@@ -102,6 +102,20 @@ Telling Meson to run this script at install time is a one-liner.
The argument is the name of the script file relative to the current
subdirectory.
+## Installing as the superuser
+
+When building as a non-root user, but installing to root-owned locations via
+e.g. `sudo ninja install`, ninja will attempt to rebuild any out of date
+targets as root. This results in various bad behaviors due to build outputs and
+ninja internal files being owned by root.
+
+Running `meson install` is preferred for several reasons. It can rebuild out of
+date targets and then re-invoke itself as root.
+
+*(since 1.1.0)* Re-invoking as root will try to guess the user's preferred method for
+re-running commands as root. The order of precedence is: sudo, doas, pkexec
+(polkit). An elevation tool can be forced by setting `$MESON_ROOT_CMD`.
+
## DESTDIR support
Sometimes you need to install to a different directory than the
diff --git a/docs/markdown/snippets/meson_install_elevate.md b/docs/markdown/snippets/meson_install_elevate.md
new file mode 100644
index 0000000..2ba92e6
--- /dev/null
+++ b/docs/markdown/snippets/meson_install_elevate.md
@@ -0,0 +1,9 @@
+## `meson install` now supports user-preferred root elevation tools
+
+Previously, when installing a project, if any files could not be installed due
+to insufficient permissions the install process was automatically re-run using
+polkit. Now it prompts to ask whether that is desirable, and checks for
+CLI-based tools such as sudo or opendoas or `$MESON_ROOT_CMD`, first.
+
+Meson will no longer attempt privilege elevation at all, when not running
+interactively.
diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py
index 9ba36cb..ab797b5 100644
--- a/mesonbuild/minstall.py
+++ b/mesonbuild/minstall.py
@@ -556,13 +556,23 @@ class Installer:
self.log('Preserved {} unchanged files, see {} for the full list'
.format(self.preserved_file_count, os.path.normpath(self.lf.name)))
except PermissionError:
- if shutil.which('pkexec') is not None and 'PKEXEC_UID' not in os.environ and destdir == '':
- print('Installation failed due to insufficient permissions.')
- print('Attempting to use polkit to gain elevated privileges...')
- os.execlp('pkexec', 'pkexec', sys.executable, main_file, *sys.argv[1:],
- '-C', os.getcwd(), '--no-rebuild')
- else:
+ if is_windows() or destdir != '' or not os.isatty(sys.stdout.fileno()) or not os.isatty(sys.stderr.fileno()):
+ # can't elevate to root except in an interactive unix environment *and* when not doing a destdir install
raise
+ rootcmd = os.environ.get('MESON_ROOT_CMD') or shutil.which('sudo') or shutil.which('doas')
+ pkexec = shutil.which('pkexec')
+ if rootcmd is None and pkexec is not None and 'PKEXEC_UID' not in os.environ:
+ rootcmd = pkexec
+
+ if rootcmd is not None:
+ print('Installation failed due to insufficient permissions.')
+ ans = input(f'Attempt to use {rootcmd} to gain elevated privileges? [y/n] ')
+ if ans not in {'y', 'n'}:
+ raise MesonException('Answer not one of [y/n]')
+ elif ans == 'y':
+ os.execlp(rootcmd, rootcmd, sys.executable, main_file, *sys.argv[1:],
+ '-C', os.getcwd(), '--no-rebuild')
+ raise
def do_strip(self, strip_bin: T.List[str], fname: str, outname: str) -> None:
self.log(f'Stripping target {fname!r}.')