why is realpath needed? #110

Closed
opened 2017-01-29 17:04:56 +00:00 by jhgit · 5 comments
jhgit commented 2017-01-29 17:04:56 +00:00 (Migrated from github.com)

If I have a package that is installed via a symbolic link, now after realpath was added to path relocation, paths are now expanded which is not necessarily desirable.

Let's say a foo.pc file has:

prefix=/net/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
Libs: -L${libdir} -Wl,-rpath,${libdir} -lfoo

And say /net/usr is a network mount that may point to different underlying path when on different machines, but /net is the common path that is accessible on all machines.

Now that paths are expanded with realpath, you might get:

% pkgconf --libs foo
-L/local/mirror/lib -Wl,-rpath,/local/mirror/lib -lfoo

or

% pkgconf --libs foo
-L/automnt/lib -Wl,-rpath,/automnt/lib -lfoo

depending on the underlying mount point for a particular host.

instead of having paths relative to the actual prefix specified in the .pc file:

% pkgconf --libs foo
-L/net/usr/lib -Wl,-rpath,/net/usr/lib -lfoo

Then if you build a library or executable using the --libs, it would now have an RPATH that points to a path that is not valid for a particular machine on the network.

Before I consider workarounds for this issue, I'm wondering why support for realpath expansion was added. My first thought is to make relocation optional (off by default?), but I'd like to understand the background for adding realpath expansion.

If I have a package that is installed via a symbolic link, now after realpath was added to path relocation, paths are now expanded which is not necessarily desirable. Let's say a foo.pc file has: prefix=/net/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib Libs: -L${libdir} -Wl,-rpath,${libdir} -lfoo And say /net/usr is a network mount that may point to different underlying path when on different machines, but /net is the common path that is accessible on all machines. Now that paths are expanded with realpath, you might get: % pkgconf --libs foo -L/local/mirror/lib -Wl,-rpath,/local/mirror/lib -lfoo or % pkgconf --libs foo -L/automnt/lib -Wl,-rpath,/automnt/lib -lfoo depending on the underlying mount point for a particular host. instead of having paths relative to the actual prefix specified in the .pc file: % pkgconf --libs foo -L/net/usr/lib -Wl,-rpath,/net/usr/lib -lfoo Then if you build a library or executable using the --libs, it would now have an RPATH that points to a path that is not valid for a particular machine on the network. Before I consider workarounds for this issue, I'm wondering why support for realpath expansion was added. My first thought is to make relocation optional (off by default?), but I'd like to understand the background for adding realpath expansion.

In some cases it was possible to have paths like /usr//include that were not filtered out as system paths, causing build problems. We use realpath() to relocate those paths to /usr/include and similar. We want to use realpath() to avoid situations where one uses a symlink to /usr/include (or some other system toolchain path) and have it not be filtered.

We will add a runtime environment variable to disable path relocation.

In some cases it was possible to have paths like `/usr//include` that were not filtered out as system paths, causing build problems. We use realpath() to relocate those paths to `/usr/include` and similar. We want to use realpath() to avoid situations where one uses a symlink to `/usr/include` (or some other system toolchain path) and have it not be filtered. We will add a runtime environment variable to disable path relocation.

pkgconf 1.2.2 will have the PKG_CONFIG_DONT_RELOCATE_PATHS environment variable. If set (for example in ~/.profile), this feature will be disabled.

pkgconf 1.2.2 will have the `PKG_CONFIG_DONT_RELOCATE_PATHS` environment variable. If set (for example in `~/.profile`), this feature will be disabled.
jhgit commented 2017-02-04 02:26:34 +00:00 (Migrated from github.com)

Thanks for that change.

I'm wondering two things:

(1) what the default should be: to realpath or not to realpath?

(2) Should this function use something like python's normpath() instead of realpath(3)?

python -c 'import os; print os.path.normpath("/usr//include")'
/usr/include

Seems like normalizing the pathname is really what's wanted for pkgconf.

One advantage of normalizing the pathname is that it needn't necessarily be an actual pathname that is accessible at the moment pkgconf is run - realpath(3) will fail if the target path doesn't exist at that moment - or if part of the path is not readable by the user who ran pkgconf.

Maybe support both "relocating" and "normalizing" pathnames? And perhaps default to just the latter?

Thanks for that change. I'm wondering two things: (1) what the default should be: to realpath or not to realpath? (2) Should this function use something like python's normpath() instead of realpath(3)? python -c 'import os; print os.path.normpath("/usr//include")' /usr/include Seems like normalizing the pathname is really what's wanted for pkgconf. One advantage of normalizing the pathname is that it needn't necessarily be an actual pathname that is accessible at the moment pkgconf is run - realpath(3) will fail if the target path doesn't exist at that moment - or if part of the path is not readable by the user who ran pkgconf. Maybe support both "relocating" and "normalizing" pathnames? And perhaps default to just the latter?
jhgit commented 2017-02-04 04:31:59 +00:00 (Migrated from github.com)

Here's a path normalization function in C (MIT license)...

https://github.com/clibs/clib/blob/master/deps/path-normalize/path-normalize.c

It's not the same as python's path.normpath() - it doesn't remove extra ".." levels (and it doesn't handle windows paths). I'll try to work up a patch to consider.

Here's a path normalization function in C (MIT license)... https://github.com/clibs/clib/blob/master/deps/path-normalize/path-normalize.c It's not the same as python's path.normpath() - it doesn't remove extra ".." levels (and it doesn't handle windows paths). I'll try to work up a patch to consider.

In most cases on windows, we would be in MSYS environment where cygwin_conv_path() handles what we want there.

In most cases on windows, we would be in MSYS environment where cygwin_conv_path() handles what we want there.
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: ariadne/pkgconf#110
There is no content yet.