Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

artificial limitation of directories (forced to be in prefix) #2561

Closed
arekm opened this issue Oct 31, 2017 · 23 comments · Fixed by #9903
Closed

artificial limitation of directories (forced to be in prefix) #2561

arekm opened this issue Oct 31, 2017 · 23 comments · Fixed by #9903

Comments

@arekm
Copy link

arekm commented Oct 31, 2017

meson artificially limits location of directories for example:

Meson encountered an error:
The value of the 'sbindir' option is '/sbin' which must be a subdir of the prefix '/usr'.
Note that if you pass a relative path, it is assumed to be a subdir of prefix.

The common configuration here is to specify exact destination for directories like:

        --bindir=%{_bindir} \
        --datadir=%{_datadir} \
        --includedir=%{_includedir} \
        --infodir=%{_infodir} \
        --libdir=%{_libdir} \
        --libexecdir=%{_libexecdir} \
        --localedir=%{_localedir} \
        --localstatedir=%{_localstatedir} \
        --mandir=%{_mandir} \
        --prefix=%{_prefix} \
        --sbindir=%{_sbindir} \
        --sharedstatedir=%{_sharedstatedir} \
        --sysconfdir=%{_sysconfdir} \

but sometimes it's desired to put one directory outside prefix for example

--prefix=/usr \
--bindir=/usr/bin \
--sbindir=/sbin \

That's the case where /usr is on separate partition, sbin tools are needed at boot, bin tools are additional utilities that are not required at boot and thus live in /usr.

Currently meson forbits such configuration which is a problem.
Workaround: mv files around after meson finishes installation. Ugly workaround.

Not sure what's the point of limiting flexibility. If none exists then please drop this check and allow such configuration to succeed.

@bluetech
Copy link
Contributor

Generally I think this restriction is good to have.

meson excludes a few directories from this check:

builtin_dir_noprefix_options = {'sysconfdir', 'localstatedir', 'sharedstatedir'}
it might make sense to add sbindir to the list.

@ghost
Copy link

ghost commented Oct 31, 2017

Generally I think this restriction is good to have.

The problem is that in this case, meson would impose a specific worldview onto the user/downstream developer using meson.

As arekm showed, GNU Autoconfigure allows for this fine-tuning. We can of course argue about the merits, pros and cons of either approach, but GNU Autoconfigure provides more flexibility here WHEN needed, whereas this appears to not be the case for meson.

In general I believe that flexibility is better, but I can also understand restrictions coming from another point of view since it may lead to a more complex/complicated codebase.

What I disagree with is to limit the flexibility-discussion solely to the NAMES of directories alone, though, because users can already, at their own discretion, arbitrarily rename all directories anyway - so I really think that this is just an option for more flexibility, and from this point of view, I completely agree with arekm. But it's just my half 2 cc anyway on the general topic of directory names; often the "bin/" versus "sbin/" distinction does not even make any real sense either, IMO. :)

@bluetech
Copy link
Contributor

You convinced me! I mean, DESTDIR should have some assurances, prefix maybenot so much.

Relevant issue #1299 and PR #1308 (I haven't read them).

@nirbheek
Copy link
Member

The solution in such a case is to set the prefix as /. In Meson, the prefix is the path inside which everything else is installed. In the last release, setting prefix to / was inadvertently broken, but it has been fixed with #2674.

This restriction is on purpose, and is useful in many situations, see #1209 for why.

@arekm
Copy link
Author

arekm commented Nov 29, 2017

Setting prefix to / forces me to set every other possible path to something desired like /usr/share or /usr/lib64 etc which sucks badly especially I can not automate that (or is there a sane way to list all directories that can to be set in a project at build time? )

@nirbheek
Copy link
Member

meson --help lists all the directories that can be set, and these are the same for all projects. Generally, if you're doing packaging you have a pre-defined list of xxxdirs that you use for Autotools. You can use the same here.

jtojnar added a commit to NixOS/nixpkgs that referenced this issue Mar 14, 2018
Upstream insists on not allowing bindir and other dir options
outside of prefix for some reason:

mesonbuild/meson#2561

We remove the check so multiple outputs can work sanely.
jtojnar added a commit to NixOS/nixpkgs that referenced this issue Mar 16, 2018
Upstream insists on not allowing bindir and other dir options
outside of prefix for some reason:

mesonbuild/meson#2561

We remove the check so multiple outputs can work sanely.
jtojnar added a commit to NixOS/nixpkgs that referenced this issue Mar 17, 2018
Upstream insists on not allowing bindir and other dir options
outside of prefix for some reason:

mesonbuild/meson#2561

We remove the check so multiple outputs can work sanely.
jtojnar added a commit to NixOS/nixpkgs that referenced this issue Mar 18, 2018
Upstream insists on not allowing bindir and other dir options
outside of prefix for some reason:

mesonbuild/meson#2561

We remove the check so multiple outputs can work sanely.
jtojnar added a commit to NixOS/nixpkgs that referenced this issue Mar 20, 2018
Upstream insists on not allowing bindir and other dir options
outside of prefix for some reason:

mesonbuild/meson#2561

We remove the check so multiple outputs can work sanely.
@jtojnar
Copy link
Contributor

jtojnar commented Jul 16, 2018

There are legitimate reasons for having multiple prefixes. To allow installing multiple versions of the same package, Nix uses different directories in /nix/store for each instance of a package. It also allows to split package into multiple outputs (directories), which makes it possible for binary packages not to depend on headers and other development files (they will be installed to a different prefix that will not be downloaded).

@nirbheek could you clarify why single prefix is on purpose, I do not see any explanation in #1209.


Trying to emulate multiple prefixes with --prefix=/ will fail when a project uses prefix option to install a file.

For example, systemd files need to go to lib/systemd directory in prefix, not libdir.

Some projects also do it for other reasons (e.g. https://github.com/elementary/greeter/blob/ae716eb3af636f7ea52da8f8ee40f569c6b1d20a/src/meson.build#L11), though, these should probably be fixed.

@nirbheek
Copy link
Member

nirbheek commented Aug 7, 2018

@nirbheek could you clarify why single prefix is on purpose,

The reason is because Meson allows passing either a path relative to the prefix or an absolute path for --bindir and friends. Inside the build file, get_option('bindir') will always return a path relative to the prefix because almost everyone assumes that everything is installed into a single prefix.

This behavior is impossible to adhere to if bindir can be outside of prefix.

For example, systemd files need to go to lib/systemd directory in prefix, not libdir.

How does NixOS handle that?

@jtojnar
Copy link
Contributor

jtojnar commented Aug 7, 2018

How does NixOS handle that?

We are patching meson to allow out-of-prefix paths:

https://github.com/NixOS/nixpkgs/blob/8bd8c09f98ece814185a0e9b0285ac3c5e51d062/pkgs/development/tools/build-managers/meson/allow-dirs-outside-of-prefix.patch

@nirbheek
Copy link
Member

nirbheek commented Aug 7, 2018

I meant, where does NixOS install systemd's unit files? It seems to me that on ordinary Linux systems, the installation path should be libdir/../lib

@jtojnar
Copy link
Contributor

jtojnar commented Aug 7, 2018

To $prefix/lib/systemd usually.

@orbea
Copy link

orbea commented Jun 9, 2020

The reason is because Meson allows passing either a path relative to the prefix or an absolute path for --bindir and friends. Inside the build file, get_option('bindir') will always return a path relative to the prefix because almost everyone assumes that everything is installed into a single prefix.

This behavior is impossible to adhere to if bindir can be outside of prefix.

@nirbheek It should only return a path relative to prefix when bindir is unset or indeed a relative path. If a user sets it to a full path which starts with an explicit / it should just use that. I don't understand what the problem is...

@jtojnar
Copy link
Contributor

jtojnar commented Jun 10, 2020

Agreed. This is what CMake’s GNUInstallDirs module does.

We (Nixpkgs) have been patching Meson to allow this for ages and only encountered few projects where it caused breakage (they were concatenating a *dir variable to prefix instead of using join_paths or Meson’s pkgconfig module) and we fixed the issues upstream in the affected projects.

@Ericson2314
Copy link
Member

Yes given a major distro like NixOS needs this, and given that it hasn't proved a problem in practice, I don't see why we don't just do this.

@nirbheek
Copy link
Member

Why isn't Nix setting prefix to be /? It's part of Meson's API contract that bindir is inside prefix.

@jtojnar
Copy link
Contributor

jtojnar commented Jun 11, 2020

Because packages are not allowed to install to arbitrary paths in /, only into their own prefixes /nix/store/${hash}-${name}-${output}/. Each package’s prefixes contains the regular FHS-like tree and GNU directory flags are set appropriately.

I am aware that it is part of the API contract but contracts can change. Yes, it would be a backwards incompatible change but in practice, we have only encountered few breakages in Nixpkgs, one of the largest software repositories there is. And all of those breakages were just caused by not following best practices like joining paths with join_paths or using pkgconfig module.

There would not even be effect on users and we are more than willing to continue to work with upstream project to improve their Meson build files. Having this artificial limitation (that neither Autotools or CMake exhibit) relaxed would allow us to link to official Meson documentation as one more point.

Since it is an artificial limitation that fortunately almost no-one relies on, I see no reason to hold onto it when there are clearly use cases and a demand.

@orbea
Copy link

orbea commented Jun 11, 2020

To be entirely blunt I still don't understand why this conversation needs to happen. This is just yet another example of meson doing things terribly wrong and making things harder for distro maintainers for no perceivable reason. Just fix it?

@mbakke
Copy link

mbakke commented Jun 11, 2020

@orbea there is no need to resort to insults. This is an honest design mistake that affects just a few distributions.

It's unfortunate that we are discussing this in a closed issue though. @nirbheek do you mind reopening this?

@Ericson2314
Copy link
Member

I could reopen this, but I'll wait a bit first, as I think it would be better if @nirbheek or somebody no afiliated with one of the affected distros did.

andyhhp pushed a commit to andyhhp/xen that referenced this issue Sep 30, 2020
QEMU as recently switch its build system to use meson and the
./configure step with meson is more restrictive that the step used to
be, most installation path wants to be within prefix, otherwise we
have this error message:

    ERROR: The value of the 'datadir' option is '/usr/share/qemu-xen' which must be a subdir of the prefix '/usr/lib/xen'.

In order to workaround the limitation, we will set prefix to the same
one as for the rest of Xen installation, and set all the other paths.

For reference, a thread in qemu-devel:
    "configure with datadir outside of --prefix fails with meson"
    https://lore.kernel.org/qemu-devel/20200918133012.GH2024@perard.uk.xensource.com/t/

And an issue in meson:
    "artificial limitation of directories (forced to be in prefix)"
    mesonbuild/meson#2561

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Tested-by: Paul Durrant <paul@xen.org>
Acked-by: Wei Liu <wl@xen.org>
@ghost
Copy link

ghost commented Feb 28, 2021

It's just the usual nonsense, there is absolutely no one in need of this behavior, but a proven number of people who do, but they are still being refused to fix it.
Just fix it, you already got the patch: https://github.com/NixOS/nixpkgs/blob/8bd8c09f98ece814185a0e9b0285ac3c5e51d062/pkgs/development/tools/build-managers/meson/allow-dirs-outside-of-prefix.patch

@Apteryks
Copy link

Apteryks commented Oct 7, 2021

Hello! What is the status of this bug? Has it been resolved or not? If not, can we please reopen this issue, to make it easier for affected users to find it?
Thank you!

Edit: seems the code responsible for this check is now at https://github.com/mesonbuild/meson/blob/master/mesonbuild/coredata.py#L538 (and still enforcing the problematic check).

@nirbheek
Copy link
Member

nirbheek commented Oct 9, 2021

Now that we have join_paths() and the \ operator, build files have a way to always be correct even when, say sbindir, is not a directory relative to prefix. So afaict the only breakage we will get from allowing dirs to be outside of prefix is build files that are doing string concatenation instead of using the path operators.

If we can alleviate the risk of that breakage, this could be changed now.

@nirbheek nirbheek reopened this Oct 9, 2021
@eli-schwartz
Copy link
Member

I suppose one way to "alleviate" that breakage is to say "if you break it you get to keep both pieces and negotiate gluing them back together yourself, with upstream".

It seems like NixOS has been doing that already while maintaining their own meson patches, so... hopefully this should not be a significant real-world problem.

jtojnar added a commit to jtojnar/meson that referenced this issue Jan 29, 2022
This bring us in line with Autotools and CMake and it is useful
for platforms like Nix, which install projects
into multiple independent prefixes.

As a consequence, `get_option` might return absolute paths for some
directory options, if a directory outside of prefix is passed.

This is technically a backwards incompatible change but its effect
should be minimal, thanks to widespread use of `join_paths`/`/` operator
and pkg-config generator module. It should only cause an issue when
a path were constructed by concatenating the value of directory path option.

Fixes: mesonbuild#2561
jtojnar added a commit to jtojnar/meson that referenced this issue Jan 29, 2022
This bring us in line with Autotools and CMake and it is useful
for platforms like Nix, which install projects
into multiple independent prefixes.

As a consequence, `get_option` might return absolute paths for some
directory options, if a directory outside of prefix is passed.

This is technically a backwards incompatible change but its effect
should be minimal, thanks to widespread use of `join_paths`/`/` operator
and pkg-config generator module. It should only cause an issue when
a path were constructed by concatenating the value of directory path option.

Fixes: mesonbuild#2561
jtojnar added a commit to jtojnar/meson that referenced this issue Jan 30, 2022
This bring us in line with Autotools and CMake and it is useful
for platforms like Nix, which install projects
into multiple independent prefixes.

As a consequence, `get_option` might return absolute paths for some
directory options, if a directory outside of prefix is passed.

This is technically a backwards incompatible change but its effect
should be minimal, thanks to widespread use of `join_paths`/`/` operator
and pkg-config generator module. It should only cause an issue when
a path were constructed by concatenating the value of directory path option.

Also remove a comment about commonpath since we do not use that since
<mesonbuild@00f5dad>.

Fixes: mesonbuild#2561
jtojnar added a commit to jtojnar/meson that referenced this issue Feb 4, 2022
This bring us in line with Autotools and CMake and it is useful
for platforms like Nix, which install projects
into multiple independent prefixes.

As a consequence, `get_option` might return absolute paths for some
directory options, if a directory outside of prefix is passed.

This is technically a backwards incompatible change but its effect
should be minimal, thanks to widespread use of `join_paths`/`/` operator
and pkg-config generator module. It should only cause an issue when
a path were constructed by concatenating the value of directory path option.

Also remove a comment about commonpath since we do not use that since
<mesonbuild@00f5dad>.

Fixes: mesonbuild#2561
jtojnar added a commit to jtojnar/meson that referenced this issue Feb 9, 2022
This bring us in line with Autotools and CMake and it is useful
for platforms like Nix, which install projects
into multiple independent prefixes.

As a consequence, `get_option` might return absolute paths for some
directory options, if a directory outside of prefix is passed.

This is technically a backwards incompatible change but its effect
should be minimal, thanks to widespread use of `join_paths`/`/` operator
and pkg-config generator module. It should only cause an issue when
a path were constructed by concatenating the value of directory path option.

Also remove a comment about commonpath since we do not use that since
<mesonbuild@00f5dad>.

Fixes: mesonbuild#2561
eli-schwartz pushed a commit that referenced this issue Feb 9, 2022
This bring us in line with Autotools and CMake and it is useful
for platforms like Nix, which install projects
into multiple independent prefixes.

As a consequence, `get_option` might return absolute paths for some
directory options, if a directory outside of prefix is passed.

This is technically a backwards incompatible change but its effect
should be minimal, thanks to widespread use of `join_paths`/`/` operator
and pkg-config generator module. It should only cause an issue when
a path were constructed by concatenating the value of directory path option.

Also remove a comment about commonpath since we do not use that since
<00f5dad>.

Fixes: #2561
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants