Add helpers for resolving path to resources in build tree

Add virFileFindResource which will try to locate files
in the local build tree if the calling binary (eg libvirtd or
test suite) is being run from the build tree. The corresponding
virFileActivateDirOverride should be called at startup passing
in argv[0]. This will be examined for evidence of libtool magic
binary prefix / sub-directory in order to activate the override.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2014-04-24 15:05:42 +01:00
parent 18dc77d3b5
commit 63a92e7220
4 changed files with 106 additions and 0 deletions

View File

@ -18,6 +18,7 @@
# old automake does not provide abs_{src,build}dir variables # old automake does not provide abs_{src,build}dir variables
abs_builddir = $(shell pwd) abs_builddir = $(shell pwd)
abs_topbuilddir = $(shell cd .. && pwd)
abs_srcdir = $(shell cd $(srcdir) && pwd) abs_srcdir = $(shell cd $(srcdir) && pwd)
# No libraries with the exception of LIBXML should be listed # No libraries with the exception of LIBXML should be listed
@ -30,6 +31,7 @@ INCLUDES = -I../gnulib/lib \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-I$(top_srcdir)/src/util \ -I$(top_srcdir)/src/util \
-DIN_LIBVIRT \ -DIN_LIBVIRT \
-Dabs_topbuilddir="\"$(abs_topbuilddir)\"" \
$(GETTEXT_CPPFLAGS) $(GETTEXT_CPPFLAGS)
AM_CFLAGS = $(LIBXML_CFLAGS) \ AM_CFLAGS = $(LIBXML_CFLAGS) \

View File

@ -1222,6 +1222,7 @@ virBuildPathInternal;
virDirCreate; virDirCreate;
virFileAbsPath; virFileAbsPath;
virFileAccessibleAs; virFileAccessibleAs;
virFileActivateDirOverride;
virFileBuildPath; virFileBuildPath;
virFileClose; virFileClose;
virFileDeleteTree; virFileDeleteTree;
@ -1230,6 +1231,8 @@ virFileExists;
virFileFclose; virFileFclose;
virFileFdopen; virFileFdopen;
virFileFindMountPoint; virFileFindMountPoint;
virFileFindResource;
virFileFindResourceFull;
virFileGetMountReverseSubtree; virFileGetMountReverseSubtree;
virFileGetMountSubtree; virFileGetMountSubtree;
virFileHasSuffix; virFileHasSuffix;

View File

@ -1542,6 +1542,93 @@ virFindFileInPath(const char *file)
return fullpath; return fullpath;
} }
static bool useDirOverride;
/**
* virFileFindResourceFull:
* @filename: libvirt distributed filename without any path
* @prefix: optional string to prepend to filename
* @suffix: optional string to append to filename
* @builddir: location of the binary in the source tree build tree
* @installdir: location of the installed binary
* @envname: environment variable used to override all dirs
*
* A helper which will return a path to @filename within
* the current build tree, if the calling binary is being
* run from the source tree. Otherwise it will return the
* path in the installed location.
*
* If @envname is non-NULL it will override all other
* directory lookup
*
* Only use this with @filename files that are part of
* the libvirt tree, not 3rd party binaries/files.
*
* Returns the resolved path (caller frees) or NULL on error
*/
char *
virFileFindResourceFull(const char *filename,
const char *prefix,
const char *suffix,
const char *builddir,
const char *installdir,
const char *envname)
{
char *ret = NULL;
const char *envval = envname ? virGetEnvBlockSUID(envname) : NULL;
if (!prefix)
prefix = "";
if (!suffix)
suffix = "";
if (envval) {
if (virAsprintf(&ret, "%s/%s%s%s", envval, prefix, filename, suffix) < 0)
return NULL;
} else if (useDirOverride) {
if (virAsprintf(&ret, "%s/%s/%s%s%s", abs_topbuilddir, builddir, prefix, filename, suffix) < 0)
return NULL;
} else {
if (virAsprintf(&ret, "%s/%s%s%s", installdir, prefix, filename, suffix) < 0)
return NULL;
}
VIR_DEBUG("Resolved '%s' to '%s'", filename, ret);
return ret;
}
char *
virFileFindResource(const char *filename,
const char *builddir,
const char *installdir)
{
return virFileFindResourceFull(filename, NULL, NULL, builddir, installdir, NULL);
}
/**
* virFileActivateDirOverride:
* @argv0: argv[0] of the calling program
*
* Look at @argv0 and try to detect if running from
* a build directory, by looking for a 'lt-' prefix
* on the binary name, or '/.libs/' in the path
*/
void
virFileActivateDirOverride(const char *argv0)
{
char *file = strrchr(argv0, '/');
if (!file || file[1] == '\0')
return;
file++;
if (STRPREFIX(file, "lt-") ||
strstr(argv0, "/.libs/")) {
useDirOverride = true;
VIR_DEBUG("Activating build dir override for %s", argv0);
}
}
bool bool
virFileIsDir(const char *path) virFileIsDir(const char *path)
{ {

View File

@ -160,6 +160,20 @@ int virFileIsLink(const char *linkpath)
char *virFindFileInPath(const char *file); char *virFindFileInPath(const char *file);
char *virFileFindResource(const char *filename,
const char *builddir,
const char *installdir)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
char *virFileFindResourceFull(const char *filename,
const char *prefix,
const char *suffix,
const char *builddir,
const char *installdir,
const char *envname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
void virFileActivateDirOverride(const char *argv0)
ATTRIBUTE_NONNULL(1);
bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1); bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1);
bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1); bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1);
bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1); bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1);