commit
5c535171a5
|
@ -73,6 +73,7 @@ core
|
|||
/tests/provides
|
||||
/tests/regress
|
||||
/tests/requires
|
||||
/tests/symlink
|
||||
/tests/sysroot
|
||||
/tests/test_env.sh
|
||||
/tests/version
|
||||
|
|
|
@ -107,6 +107,7 @@ EXTRA_DIST = pkg.m4 \
|
|||
tests/lib1/tuple-quoting.pc \
|
||||
tests/lib1/empty-tuple.pc \
|
||||
tests/lib1/orphaned-requires-private.pc \
|
||||
tests/lib1/pcfiledir.pc \
|
||||
tests/lib1/sysroot-dir-2.pc \
|
||||
tests/lib1/sysroot-dir-3.pc \
|
||||
tests/lib1/sysroot-dir-4.pc \
|
||||
|
@ -137,6 +138,7 @@ test_scripts= tests/meson.build \
|
|||
tests/provides.sh \
|
||||
tests/regress.sh \
|
||||
tests/requires.sh \
|
||||
tests/symlink.sh \
|
||||
tests/sysroot.sh \
|
||||
tests/version.sh
|
||||
|
||||
|
|
|
@ -17,6 +17,15 @@
|
|||
#include <libpkgconf/stdinc.h>
|
||||
#include <libpkgconf/libpkgconf.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <fcntl.h> // open
|
||||
#include <libgen.h> // basename/dirname
|
||||
#include <sys/stat.h> // lstat, S_ISLNK
|
||||
#include <unistd.h> // close, readlinkat
|
||||
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
|
@ -63,6 +72,65 @@ pkg_get_parent_dir(pkgconf_pkg_t *pkg)
|
|||
char buf[PKGCONF_ITEM_SIZE], *pathbuf;
|
||||
|
||||
pkgconf_strlcpy(buf, pkg->filename, sizeof buf);
|
||||
#ifndef _WIN32
|
||||
/*
|
||||
* We want to resolve symlinks, since ${pcfiledir} should point to the
|
||||
* parent of the file symlinked to.
|
||||
*/
|
||||
struct stat path_stat;
|
||||
while (!lstat(buf, &path_stat) && S_ISLNK(path_stat.st_mode))
|
||||
{
|
||||
/*
|
||||
* Have to split the path into the dir + file components,
|
||||
* in order to extract the directory file descriptor.
|
||||
*
|
||||
* The nomenclature here uses the
|
||||
*
|
||||
* ln <source> <target>
|
||||
*
|
||||
* model.
|
||||
*/
|
||||
char basenamebuf[PKGCONF_ITEM_SIZE];
|
||||
pkgconf_strlcpy(basenamebuf, buf, sizeof(basenamebuf));
|
||||
const char* targetfilename = basename(basenamebuf);
|
||||
|
||||
char dirnamebuf[PKGCONF_ITEM_SIZE];
|
||||
pkgconf_strlcpy(dirnamebuf, buf, sizeof(dirnamebuf));
|
||||
const char* targetdir = dirname(dirnamebuf);
|
||||
|
||||
const int dirfd = open(targetdir, O_DIRECTORY);
|
||||
if (dirfd == -1)
|
||||
break;
|
||||
|
||||
char sourcebuf[PKGCONF_ITEM_SIZE];
|
||||
ssize_t len = readlinkat(dirfd, targetfilename, sourcebuf, sizeof(sourcebuf) - 1);
|
||||
close(dirfd);
|
||||
|
||||
if (len == -1)
|
||||
break;
|
||||
sourcebuf[len] = '\0';
|
||||
|
||||
memset(buf, '\0', sizeof buf);
|
||||
/*
|
||||
* The logic here can be a bit tricky, so here's a table:
|
||||
*
|
||||
* <source> | <target> | result
|
||||
* -----------------------------------------------------------------------
|
||||
* /bar (absolute) | foo/link (relative) | /bar (absolute)
|
||||
* ../bar (relative) | foo/link (relative) | foo/../bar (relative)
|
||||
* /bar (absolute) | /foo/link (absolute) | /bar (absolute)
|
||||
* ../bar (relative) | /foo/link (absolute) | /foo/../bar (relative)
|
||||
*/
|
||||
if ((sourcebuf[0] != '/') /* absolute path in <source> wins */
|
||||
&& (strcmp(targetdir, "."))) /* do not prepend "." */
|
||||
{
|
||||
pkgconf_strlcat(buf, targetdir, sizeof buf);
|
||||
pkgconf_strlcat(buf, "/", sizeof buf);
|
||||
}
|
||||
pkgconf_strlcat(buf, sourcebuf, sizeof buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
pathbuf = strrchr(buf, PKG_DIR_SEP_S);
|
||||
if (pathbuf == NULL)
|
||||
pathbuf = strrchr(buf, '/');
|
||||
|
|
|
@ -11,3 +11,4 @@ atf_test_program{name='conflicts'}
|
|||
atf_test_program{name='version'}
|
||||
atf_test_program{name='framework'}
|
||||
atf_test_program{name='provides'}
|
||||
atf_test_program{name='symlink'}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
prefix=${pcfiledir}
|
||||
exec_prefix=${prefix}
|
||||
libdir=${prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: foo
|
||||
Description: A testing pkg-config file with a ${pcfiledir}
|
||||
Version: 1.2.3
|
|
@ -11,8 +11,9 @@ tests = [
|
|||
'provides',
|
||||
'regress',
|
||||
'requires',
|
||||
'symlink',
|
||||
'sysroot',
|
||||
'version'
|
||||
'version',
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
#!/usr/bin/env atf-sh
|
||||
|
||||
. $(atf_get_srcdir)/test_env.sh
|
||||
|
||||
tests_init \
|
||||
pcfiledir_symlink_absolute \
|
||||
pcfiledir_symlink_relative
|
||||
|
||||
# - We need to create a temporary subtree, since symlinks are not preserved
|
||||
# in "make dist".
|
||||
# - ${srcdir} is relative and since we need to compare paths, we would have
|
||||
# to portably canonicalize it again, which is hard. Instead, just keep
|
||||
# the whole thing nested.
|
||||
pcfiledir_symlink_absolute_body()
|
||||
{
|
||||
mkdir -p tmp/child
|
||||
cp -f "${selfdir}/lib1/pcfiledir.pc" tmp/child/
|
||||
ln -f -s "${PWD}/tmp/child/pcfiledir.pc" tmp/pcfiledir.pc # absolute
|
||||
ln -f -s tmp/pcfiledir.pc pcfiledir.pc
|
||||
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir.pc
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix tmp/pcfiledir.pc
|
||||
atf_check \
|
||||
-o inline:"tmp/child\n" \
|
||||
pkgconf --variable=prefix tmp/child/pcfiledir.pc
|
||||
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix "${PWD}/pcfiledir.pc"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix "${PWD}/tmp/pcfiledir.pc"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix "${PWD}/tmp/child/pcfiledir.pc"
|
||||
|
||||
export PKG_CONFIG_PATH="."
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
export PKG_CONFIG_PATH="${PWD}"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
|
||||
export PKG_CONFIG_PATH="tmp"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
export PKG_CONFIG_PATH="${PWD}/tmp"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
|
||||
export PKG_CONFIG_PATH="tmp/child"
|
||||
atf_check \
|
||||
-o inline:"tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
export PKG_CONFIG_PATH="${PWD}/tmp/child"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
}
|
||||
|
||||
pcfiledir_symlink_relative_body()
|
||||
{
|
||||
mkdir -p tmp/child
|
||||
cp -f "${selfdir}/lib1/pcfiledir.pc" tmp/child/
|
||||
ln -f -s child/pcfiledir.pc tmp/pcfiledir.pc # relative
|
||||
ln -f -s tmp/pcfiledir.pc pcfiledir.pc
|
||||
|
||||
atf_check \
|
||||
-o inline:"tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir.pc
|
||||
atf_check \
|
||||
-o inline:"tmp/child\n" \
|
||||
pkgconf --variable=prefix tmp/pcfiledir.pc
|
||||
atf_check \
|
||||
-o inline:"tmp/child\n" \
|
||||
pkgconf --variable=prefix tmp/child/pcfiledir.pc
|
||||
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix "${PWD}/pcfiledir.pc"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix "${PWD}/tmp/pcfiledir.pc"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix "${PWD}/tmp/child/pcfiledir.pc"
|
||||
|
||||
export PKG_CONFIG_PATH="."
|
||||
atf_check \
|
||||
-o inline:"tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
export PKG_CONFIG_PATH="${PWD}"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
|
||||
export PKG_CONFIG_PATH="tmp"
|
||||
atf_check \
|
||||
-o inline:"tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
export PKG_CONFIG_PATH="${PWD}/tmp"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
|
||||
export PKG_CONFIG_PATH="tmp/child"
|
||||
atf_check \
|
||||
-o inline:"tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
export PKG_CONFIG_PATH="${PWD}/tmp/child"
|
||||
atf_check \
|
||||
-o inline:"${PWD}/tmp/child\n" \
|
||||
pkgconf --variable=prefix pcfiledir
|
||||
}
|
Loading…
Reference in New Issue