Add support for macro-only dependency generators
In some cases generators are remarkably simple, such as just echoing back the basename of the file in some namespace such as foo(lib.so), and forking out a shell to perform such a mundane task is both hideously slow and plain dumb, when we have quite some string processing facilities and even a full-blown programming language embedded in rpm itself. This adds support for using macro functions as generators: if the generator macro is a parametric macro, then we call that macro with the file name as the first argument instead of shelling out, and the expansion of the macro is used as the output. Multiple lines in output are allowed, and generator styles can be mixed freely (eg shell out for provides but use macro function for requires etc). Constructing the expand call with "proper" macro arguments runs into all sorts of trouble with special character escaping, work around that by defining the file name as literal macro %1 prior to calling the generator. Which is a bit dirty but works...
This commit is contained in:
parent
9b37c4b349
commit
bc4339071c
|
@ -514,6 +514,27 @@ static ARGV_t runCmd(const char *cmd,
|
|||
return output;
|
||||
}
|
||||
|
||||
static ARGV_t runCall(const char *cmd,
|
||||
const char *buildRoot, const char *fn)
|
||||
{
|
||||
ARGV_t output = NULL;
|
||||
char *path = rstrscat(NULL, buildRoot ? buildRoot : "", "/", fn, NULL);
|
||||
|
||||
if (_rpmfc_debug)
|
||||
rpmlog(RPMLOG_DEBUG, "Calling %s() on %s\n", cmd, path);
|
||||
|
||||
/* Hack to pass in the path as what looks like a macro argument */
|
||||
rpmPushMacroFlags(NULL, "1", NULL, path, 1, RPMMACRO_LITERAL);
|
||||
char *exp = rpmExpand(cmd, NULL);
|
||||
rpmPopMacro(NULL, "1");
|
||||
if (*exp)
|
||||
argvSplit(&output, exp, "\n\r");
|
||||
free(exp);
|
||||
|
||||
free(path);
|
||||
return output;
|
||||
}
|
||||
|
||||
struct addReqProvDataFc {
|
||||
rpmfc fc;
|
||||
const char *namespace;
|
||||
|
@ -560,7 +581,7 @@ static void exclFini(struct exclreg_s *excl)
|
|||
|
||||
static int rpmfcHelper(rpmfc fc, int ix, const struct exclreg_s *excl,
|
||||
rpmsenseFlags dsContext, rpmTagVal tagN,
|
||||
const char *namespace, const char *cmd)
|
||||
const char *namespace, const char *cmd, int callable)
|
||||
{
|
||||
ARGV_t pav = NULL;
|
||||
const char * fn = fc->fn[ix];
|
||||
|
@ -574,7 +595,12 @@ static int rpmfcHelper(rpmfc fc, int ix, const struct exclreg_s *excl,
|
|||
if (regMatch(excl->global_exclude_from, fn+fc->brlen))
|
||||
goto exit;
|
||||
|
||||
pav = runCmd(cmd, fc->buildRoot, fn);
|
||||
if (callable) {
|
||||
pav = runCall(cmd, fc->buildRoot, fn);
|
||||
} else {
|
||||
pav = runCmd(cmd, fc->buildRoot, fn);
|
||||
}
|
||||
|
||||
if (pav == NULL)
|
||||
goto exit;
|
||||
|
||||
|
@ -976,12 +1002,22 @@ static int applyAttr(rpmfc fc, int aix, const char *aname,
|
|||
|
||||
if (fattrHashGetEntry(fc->fahash, aix, &ixs, &n, NULL)) {
|
||||
char *mname = rstrscat(NULL, "__", aname, "_", dep->name, NULL);
|
||||
char *cmd = rpmExpand("%{?", mname, ":%{", mname, "} %{?",
|
||||
char *cmd;
|
||||
int callable = rpmMacroIsParametric(NULL, mname);
|
||||
|
||||
if (callable) {
|
||||
cmd = rstrscat(NULL, "%{", mname,
|
||||
" %{?", mname, "_opts}", "}", NULL);
|
||||
} else {
|
||||
cmd = rpmExpand("%{?", mname, ":%{", mname, "} %{?",
|
||||
mname, "_opts}}", NULL);
|
||||
}
|
||||
|
||||
if (!rstreq(cmd, "")) {
|
||||
char *ns = rpmfcAttrMacro(aname, "namespace", NULL);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (rpmfcHelper(fc, ixs[i], excl, dep->type, dep->tag, ns, cmd))
|
||||
if (rpmfcHelper(fc, ixs[i], excl, dep->type, dep->tag,
|
||||
ns, cmd, callable))
|
||||
rc = 1;
|
||||
}
|
||||
free(ns);
|
||||
|
|
|
@ -508,6 +508,21 @@ runroot rpmbuild -bb --quiet \
|
|||
])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([Dependency generation 4])
|
||||
AT_KEYWORDS([build])
|
||||
AT_CHECK([
|
||||
|
||||
runroot rpmbuild -bb --quiet \
|
||||
--define '__script_requires() foo(%{basename:%{1}})' \
|
||||
/data/SPECS/shebang.spec
|
||||
runroot rpm -qp --requires /build/RPMS/noarch/shebang-0.1-1.noarch.rpm|grep -v ^rpmlib
|
||||
],
|
||||
[0],
|
||||
[foo(shebang)
|
||||
],
|
||||
[])
|
||||
AT_CLEANUP
|
||||
|
||||
# ------------------------------
|
||||
# Test spec query functionality
|
||||
AT_SETUP([rpmspec query 1])
|
||||
|
|
Loading…
Reference in New Issue