common: Support locating components in the build tree.

* common/homedir.c (gnupg_build_directory): New variable.
(gnupg_module_name_called): Likewise.
(gnupg_set_builddir): New function.
(gnupg_set_builddir_from_env): Likewise.
(gnupg_module_name): Support locating components in the build tree.
* common/util.h (gnupg_set_builddir): New prototype.
* tests/openpgp/defs.scm (tools): Drop 'gpg and 'gpg-agent.
(tool): Rename to 'tool-hardcoded.
(gpg-conf): New function, with accessors for the results.
(gpg-components): New variable.
(tool): New function.
* tools/gpgconf.c (enum cmd_and_opt_values): New key.
(opts): New option '--build-prefix'.
(main): Handle new option.
--

This change makes sure that the components from the build tree are
used, and not some older installed version in PATH.  It also lets us
make GPGME use components from the build tree, making it possible to
execute GPGME's test suite with them.

Signed-off-by: Justus Winter <justus@g10code.com>
This commit is contained in:
Justus Winter 2016-12-14 14:18:22 +01:00
parent 55dc81125a
commit ca1e9749bf
4 changed files with 88 additions and 21 deletions

View File

@ -884,15 +884,60 @@ get_default_pinentry_name (int reset)
}
/* If set, 'gnupg_module_name' returns modules from that build
* directory. */
static char *gnupg_build_directory;
/* For sanity checks. */
static int gnupg_module_name_called;
/* Set NEWDIR as the new build directory. This will make
* 'gnupg_module_name' return modules from that build directory. Must
* be called before any invocation of 'gnupg_module_name', and must
* not be called twice. It can be used by test suites to make sure
* the components from the build directory are used instead of
* potentially outdated installed ones. */
void
gnupg_set_builddir (const char *newdir)
{
log_assert (! gnupg_module_name_called);
log_assert (! gnupg_build_directory);
gnupg_build_directory = xtrystrdup (newdir);
}
/* If no build directory has been configured, try to set it from the
* environment. We only do this in development builds to avoid
* increasing the set of influential environment variables and hence
* the attack surface of production builds. */
static void
gnupg_set_builddir_from_env (void)
{
#ifdef IS_DEVELOPMENT_VERSION
if (gnupg_build_directory)
return;
gnupg_build_directory = getenv ("GNUPG_BUILDDIR");
#endif
}
/* Return the file name of a helper tool. WHICH is one of the
GNUPG_MODULE_NAME_foo constants. */
const char *
gnupg_module_name (int which)
{
#define X(a,b) do { \
gnupg_set_builddir_from_env ();
gnupg_module_name_called = 1;
#define X(a,b,c) do { \
static char *name; \
if (!name) \
name = xstrconcat (gnupg_ ## a (), DIRSEP_S b EXEEXT_S, NULL); \
name = gnupg_build_directory \
? xstrconcat (gnupg_build_directory, \
DIRSEP_S b DIRSEP_S c EXEEXT_S, NULL) \
: xstrconcat (gnupg_ ## a (), DIRSEP_S c EXEEXT_S, NULL); \
return name; \
} while (0)
@ -902,7 +947,7 @@ gnupg_module_name (int which)
#ifdef GNUPG_DEFAULT_AGENT
return GNUPG_DEFAULT_AGENT;
#else
X(bindir, "gpg-agent");
X(bindir, "agent", "gpg-agent");
#endif
case GNUPG_MODULE_NAME_PINENTRY:
@ -916,55 +961,57 @@ gnupg_module_name (int which)
#ifdef GNUPG_DEFAULT_SCDAEMON
return GNUPG_DEFAULT_SCDAEMON;
#else
X(libexecdir, "scdaemon");
X(libexecdir, "scd", "scdaemon");
#endif
case GNUPG_MODULE_NAME_DIRMNGR:
#ifdef GNUPG_DEFAULT_DIRMNGR
return GNUPG_DEFAULT_DIRMNGR;
#else
X(bindir, DIRMNGR_NAME);
X(bindir, "dirmngr", DIRMNGR_NAME);
#endif
case GNUPG_MODULE_NAME_PROTECT_TOOL:
#ifdef GNUPG_DEFAULT_PROTECT_TOOL
return GNUPG_DEFAULT_PROTECT_TOOL;
#else
X(libexecdir, "gpg-protect-tool");
X(libexecdir, "agent", "gpg-protect-tool");
#endif
case GNUPG_MODULE_NAME_DIRMNGR_LDAP:
#ifdef GNUPG_DEFAULT_DIRMNGR_LDAP
return GNUPG_DEFAULT_DIRMNGR_LDAP;
#else
X(libexecdir, "dirmngr_ldap");
X(libexecdir, "dirmngr", "dirmngr_ldap");
#endif
case GNUPG_MODULE_NAME_CHECK_PATTERN:
X(libexecdir, "gpg-check-pattern");
X(libexecdir, "tools", "gpg-check-pattern");
case GNUPG_MODULE_NAME_GPGSM:
X(bindir, "gpgsm");
X(bindir, "sm", "gpgsm");
case GNUPG_MODULE_NAME_GPG:
#if USE_GPG2_HACK
X(bindir, GPG_NAME "2");
#else
X(bindir, GPG_NAME);
if (! gnupg_build_directory)
X(bindir, "g10", GPG_NAME "2");
else
#endif
X(bindir, "g10", GPG_NAME);
case GNUPG_MODULE_NAME_GPGV:
#if USE_GPG2_HACK
X(bindir, GPG_NAME "v2");
#else
X(bindir, GPG_NAME "v");
if (! gnupg_build_directory)
X(bindir, "g10", GPG_NAME "v2");
else
#endif
X(bindir, "g10", GPG_NAME "v");
case GNUPG_MODULE_NAME_CONNECT_AGENT:
X(bindir, "gpg-connect-agent");
X(bindir, "tools", "gpg-connect-agent");
case GNUPG_MODULE_NAME_GPGCONF:
X(bindir, "gpgconf");
X(bindir, "tools", "gpgconf");
default:
BUG ();

View File

@ -263,6 +263,7 @@ char *_gnupg_socketdir_internal (int skip_checks, unsigned *r_info);
#define GNUPG_MODULE_NAME_GPGV 12
const char *gnupg_module_name (int which);
void gnupg_module_name_flush_some (void);
void gnupg_set_builddir (const char *newdir);

View File

@ -56,9 +56,7 @@
value)))
(define tools
'((gpg "GPG" "g10/gpg")
(gpgv "GPGV" "g10/gpgv")
(gpg-agent "GPG_AGENT" "agent/gpg-agent")
'((gpgv "GPGV" "g10/gpgv")
(gpg-connect-agent "GPG_CONNECT_AGENT" "tools/gpg-connect-agent")
(gpgconf "GPGCONF" "tools/gpgconf")
(gpg-preset-passphrase "GPG_PRESET_PASSPHRASE"
@ -67,7 +65,7 @@
(gpg-zip "GPGZIP" "tools/gpg-zip")
(pinentry "PINENTRY" "tests/openpgp/fake-pinentry")))
(define (tool which)
(define (tool-hardcoded which)
(let ((t (assoc which tools))
(prefix (getenv "BIN_PREFIX")))
(getenv' (cadr t)
@ -75,6 +73,24 @@
(string-append (getenv "objdir") "/" (caddr t))
(string-append prefix "/" (basename (caddr t))))))))
(define (gpg-conf . args)
(let ((s (call-popen `(,(tool-hardcoded 'gpgconf) ,@args) "")))
(map (lambda (line) (string-split line #\:))
(string-split-newlines s))))
(define :gc:c:name car)
(define :gc:c:description cadr)
(define :gc:c:pgmname caddr)
(setenv "GNUPG_BUILDDIR" (getenv "objdir") #t)
(define gpg-components (gpg-conf '--build-prefix (getenv "objdir")
'--list-components))
(define (tool which)
(case which
((gpg gpg-agent scdaemon gpgsm dirmngr)
(:gc:c:pgmname (assoc (symbol->string which) gpg-components)))
(else
(tool-hardcoded which))))
(define (gpg-has-option? option)
(string-contains? (call-popen `(,(tool 'gpg) --dump-options) "")

View File

@ -44,6 +44,7 @@ enum cmd_and_opt_values
oNull = '0',
oNoVerbose = 500,
oHomedir,
oBuilddir,
aListComponents,
aCheckPrograms,
@ -98,6 +99,7 @@ static ARGPARSE_OPTS opts[] =
{ oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") },
/* hidden options */
{ oHomedir, "homedir", 2, "@" },
{ oBuilddir, "build-prefix", 2, "@" },
{ oNull, "null", 0, "@" },
{ oNoVerbose, "no-verbose", 0, "@"},
{0}
@ -483,6 +485,7 @@ main (int argc, char **argv)
case oVerbose: opt.verbose++; break;
case oNoVerbose: opt.verbose = 0; break;
case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oBuilddir: gnupg_set_builddir (pargs.r.ret_str); break;
case oNull: opt.null = 1; break;
case aListDirs: