Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for declarative buildsystem #2774

Merged
merged 5 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions build/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,18 +251,19 @@ rpmRC doScript(rpmSpec spec, rpmBuildFlags what, const char *name,
static int doBuildRequires(rpmSpec spec, int test)
{
StringBuf sb_stdout = NULL;
const char *buildrequires = rpmSpecGetSection(spec, RPMBUILD_BUILDREQUIRES);
int outc;
ARGV_t output = NULL;

int rc = 1; /* assume failure */

if (!spec->buildrequires) {
if (!buildrequires) {
rc = RPMRC_OK;
goto exit;
}

if ((rc = doScript(spec, RPMBUILD_BUILDREQUIRES, "%generate_buildrequires",
getStringBuf(spec->buildrequires), test, &sb_stdout)))
buildrequires, test, &sb_stdout)))
goto exit;

/* add results to requires of the srpm */
Expand Down Expand Up @@ -368,7 +369,7 @@ static rpmRC buildSpec(rpmts ts, BTA_t buildArgs, rpmSpec spec, int what)
int sourceOnly = ((what & RPMBUILD_PACKAGESOURCE) &&
!(what & (RPMBUILD_CONF|RPMBUILD_BUILD|RPMBUILD_INSTALL|RPMBUILD_PACKAGEBINARY)));

if (!spec->buildrequires && sourceOnly) {
if (!rpmSpecGetSection(spec, RPMBUILD_BUILDREQUIRES) && sourceOnly) {
/* don't run prep if not needed for source build */
/* with(out) dynamic build requires*/
what &= ~(RPMBUILD_PREP);
Expand All @@ -380,7 +381,8 @@ static rpmRC buildSpec(rpmts ts, BTA_t buildArgs, rpmSpec spec, int what)

if ((what & RPMBUILD_PREP) &&
(rc = doScript(spec, RPMBUILD_PREP, "%prep",
getStringBuf(spec->prep), test, sbp)))
rpmSpecGetSection(spec, RPMBUILD_PREP),
test, sbp)))
goto exit;

if (what & RPMBUILD_BUILDREQUIRES)
Expand Down Expand Up @@ -409,17 +411,20 @@ static rpmRC buildSpec(rpmts ts, BTA_t buildArgs, rpmSpec spec, int what)

if ((what & RPMBUILD_CONF) &&
(rc = doScript(spec, RPMBUILD_BUILD, "%conf",
getStringBuf(spec->conf), test, sbp)))
rpmSpecGetSection(spec, RPMBUILD_CONF),
test, sbp)))
goto exit;

if ((what & RPMBUILD_BUILD) &&
(rc = doScript(spec, RPMBUILD_BUILD, "%build",
getStringBuf(spec->build), test, sbp)))
rpmSpecGetSection(spec, RPMBUILD_BUILD),
test, sbp)))
goto exit;

if ((what & RPMBUILD_INSTALL) &&
(rc = doScript(spec, RPMBUILD_INSTALL, "%install",
getStringBuf(spec->install), test, sbp)))
rpmSpecGetSection(spec, RPMBUILD_INSTALL),
test, sbp)))
goto exit;

if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY)) &&
Expand All @@ -428,7 +433,8 @@ static rpmRC buildSpec(rpmts ts, BTA_t buildArgs, rpmSpec spec, int what)

if ((what & RPMBUILD_CHECK) &&
(rc = doScript(spec, RPMBUILD_CHECK, "%check",
getStringBuf(spec->check), test, sbp)))
rpmSpecGetSection(spec, RPMBUILD_CHECK),
test, sbp)))
goto exit;

if ((what & RPMBUILD_PACKAGESOURCE) &&
Expand All @@ -455,7 +461,8 @@ static rpmRC buildSpec(rpmts ts, BTA_t buildArgs, rpmSpec spec, int what)

if ((what & RPMBUILD_CLEAN) &&
(rc = doScript(spec, RPMBUILD_CLEAN, "%clean",
getStringBuf(spec->clean), test, sbp)))
rpmSpecGetSection(spec, RPMBUILD_CLEAN),
test, sbp)))
goto exit;

if ((what & RPMBUILD_RMBUILD) &&
Expand Down
5 changes: 3 additions & 2 deletions build/pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -805,9 +805,10 @@ rpmRC packageSources(rpmSpec spec, char **cookie)
headerPutUint32(sourcePkg->header, RPMTAG_SOURCEPACKAGE, &one, 1);

/* Include spec in parsed and expanded form */
headerPutString(sourcePkg->header, RPMTAG_SPEC, getStringBuf(spec->parsed));
headerPutString(sourcePkg->header, RPMTAG_SPEC,
rpmSpecGetSection(spec, RPMBUILD_NONE));

if (spec->buildrequires) {
if (rpmSpecGetSection(spec, RPMBUILD_BUILDREQUIRES)) {
(void) rpmlibNeedsFeature(sourcePkg, "DynamicBuildRequires", "4.15.0-1");
}

Expand Down
28 changes: 28 additions & 0 deletions build/parsePreamble.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,20 @@ int addLangTag(rpmSpec spec, Header h, rpmTagVal tag,
return 0;
}

static int addBuildOption(rpmSpec spec, const char *sect, const char *opt)
{
rpmRC rc = RPMRC_FAIL;
if (*sect == '\0')
sect = "conf";

int sn = getSection(sect);
if (sn >= 0) {
argvAdd(&(spec->buildopts[sn]), opt);
rc = RPMRC_OK;
}
return rc;
}

static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
const char *macro, const char *lang)
{
Expand Down Expand Up @@ -820,6 +834,18 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
multiToken = 1;

switch (tag) {
case RPMTAG_BUILDSYSTEM:
SINGLE_TOKEN_ONLY;
if (rpmCharCheck(spec, field,
ALLOWED_CHARS_NAME, ALLOWED_FIRSTCHARS_NAME))
{
goto exit;
}
break;
case RPMTAG_BUILDOPTION:
if (addBuildOption(spec, lang, field))
goto exit;
break;
case RPMTAG_NAME:
SINGLE_TOKEN_ONLY;
if (rpmCharCheck(spec, field,
Expand Down Expand Up @@ -1077,8 +1103,10 @@ static struct PreambleRec_s const preambleList[] = {
{RPMTAG_BUILDARCHS, 0, 0, 0, LEN_AND_STR("buildarchitectures")},
{RPMTAG_BUILDARCHS, 0, 0, 0, LEN_AND_STR("buildarch")},
{RPMTAG_BUILDCONFLICTS, 0, 0, 0, LEN_AND_STR("buildconflicts")},
{RPMTAG_BUILDOPTION, 2, 0, 0, LEN_AND_STR("buildoption")},
{RPMTAG_BUILDPREREQ, 0, 1, 0, LEN_AND_STR("buildprereq")},
{RPMTAG_BUILDREQUIRES, 0, 0, 0, LEN_AND_STR("buildrequires")},
{RPMTAG_BUILDSYSTEM, 0, 0, 1, LEN_AND_STR("buildsystem")},
{RPMTAG_AUTOREQPROV, 0, 0, 0, LEN_AND_STR("autoreqprov")},
{RPMTAG_AUTOREQ, 0, 0, 0, LEN_AND_STR("autoreq")},
{RPMTAG_AUTOPROV, 0, 0, 0, LEN_AND_STR("autoprov")},
Expand Down
132 changes: 120 additions & 12 deletions build/parseSpec.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#define ISMACRO(s,m,len) (rstreqn((s), (m), len) && !risalpha((s)[len]))
#define ISMACROWITHARG(s,m,len) (rstreqn((s), (m), len) && (risblank((s)[len]) || !(s)[len]))

static rpmRC parseSpecParts(rpmSpec spec, const char *pattern);

typedef struct OpenFileInfo {
char * fileName;
FILE *fp;
Expand Down Expand Up @@ -596,7 +598,7 @@ int parseLines(rpmSpec spec, int strip, ARGV_t *avp, StringBuf *sbp)

while (! (nextPart = isPart(spec->line))) {
/* HACK: Emit a legible error on the obsolete %patchN form for now */
if (sbp == &(spec->prep)) {
if (sbp == &(spec->sections[SECT_PREP])) {
size_t slen = strlen(spec->line);
if (slen >= 7 && risdigit(spec->line[6]) &&
rstreqn(spec->line, "%patch", 6))
Expand Down Expand Up @@ -894,6 +896,103 @@ static int parseEmpty(rpmSpec spec, int prevParsePart)
return res;
}

struct sectname_s {
const char *name;
int section;
};

struct sectname_s sectList[] = {
{ "prep", SECT_PREP },
{ "conf", SECT_CONF },
{ "generate_buildrequires", SECT_BUILDREQUIRES },
{ "build", SECT_BUILD },
{ "install", SECT_INSTALL },
{ "check", SECT_CHECK },
{ "clean", SECT_CLEAN },
{ NULL, -1 }
};

int getSection(const char *name)
{
int sn = -1;
for (struct sectname_s *sc = sectList; sc->name; sc++) {
if (rstreq(name, sc->name)) {
sn = sc->section;
break;
}
}
return sn;
}

static rpmRC parseBuildsysSect(rpmSpec spec, const char *prefix,
struct sectname_s *sc, FD_t fd)
{
rpmRC rc = RPMRC_OK;

if (spec->sections[sc->section] == NULL) {
char *mn = rstrscat(NULL, "buildsystem_", prefix, "_", sc->name, NULL);
if (rpmMacroIsParametric(NULL, mn)) {
char *args = NULL;
if (spec->buildopts[sc->section]) {
ARGV_t av = NULL;
argvAdd(&av, "--");
argvAppend(&av, spec->buildopts[sc->section]);
args = argvJoin(av, " ");
free(av);
}
char *buf = rstrscat(NULL, "%", sc->name, "\n",
"%", mn, " ",
args ? args : "",
"\n", NULL);
size_t blen = strlen(buf);
if (Fwrite(buf, blen, 1, fd) < blen) {
rc = RPMRC_FAIL;
rpmlog(RPMLOG_ERR,
_("failed to write buildsystem %s %%%s: %s\n"),
prefix, sc->name, strerror(errno));
}
free(buf);
free(args);
}
free(mn);
}
return rc;
}

static rpmRC parseBuildsystem(rpmSpec spec)
{
rpmRC rc = RPMRC_OK;
char *buildsystem = rpmExpand("%{?buildsystem}", NULL);
if (*buildsystem) {
char *path = NULL;

FD_t fd = rpmMkTempFile(NULL, &path);
if (fd == NULL) {
rpmlog(RPMLOG_ERR,
_("failed to create temp file for buildsystem: %s\n"),
strerror(errno));
rc = RPMRC_FAIL;
goto exit;
}

for (struct sectname_s *sc = sectList; !rc && sc->name; sc++) {
rc = parseBuildsysSect(spec, buildsystem, sc, fd);
if (!rc && spec->sections[sc->section] == NULL)
rc = parseBuildsysSect(spec, "default", sc, fd);
}

if (!rc)
rc = parseSpecParts(spec, path);
if (!rc)
unlink(path);
Fclose(fd);
}

exit:
free(buildsystem);
return rc;
}

static rpmSpec parseSpec(const char *specFile, rpmSpecFlags flags,
const char *buildRoot, int recursing);

Expand Down Expand Up @@ -933,28 +1032,34 @@ static rpmRC parseSpecSection(rpmSpec *specptr, int secondary)
case PART_PREP:
rpmPushMacroAux(NULL, "setup", "-", doSetupMacro, spec, -1, 0, 0);
rpmPushMacroAux(NULL, "patch", "-", doPatchMacro, spec, -1, 0, 0);
parsePart = parseSimpleScript(spec, "%prep", &(spec->prep));
parsePart = parseSimpleScript(spec, "%prep",
&(spec->sections[SECT_PREP]));
rpmPopMacro(NULL, "patch");
rpmPopMacro(NULL, "setup");
break;
case PART_CONF:
parsePart = parseSimpleScript(spec, "%conf", &(spec->conf));
parsePart = parseSimpleScript(spec, "%conf",
&(spec->sections[SECT_CONF]));
break;
case PART_BUILDREQUIRES:
parsePart = parseSimpleScript(spec, "%generate_buildrequires",
&(spec->buildrequires));
&(spec->sections[SECT_BUILDREQUIRES]));
break;
case PART_BUILD:
parsePart = parseSimpleScript(spec, "%build", &(spec->build));
parsePart = parseSimpleScript(spec, "%build",
&(spec->sections[SECT_BUILD]));
break;
case PART_INSTALL:
parsePart = parseSimpleScript(spec, "%install", &(spec->install));
parsePart = parseSimpleScript(spec, "%install",
&(spec->sections[SECT_INSTALL]));
break;
case PART_CHECK:
parsePart = parseSimpleScript(spec, "%check", &(spec->check));
parsePart = parseSimpleScript(spec, "%check",
&(spec->sections[SECT_CHECK]));
break;
case PART_CLEAN:
parsePart = parseSimpleScript(spec, "%clean", &(spec->clean));
parsePart = parseSimpleScript(spec, "%clean",
&(spec->sections[SECT_CLEAN]));
break;
case PART_CHANGELOG:
parsePart = parseChangelog(spec);
Expand Down Expand Up @@ -1055,6 +1160,9 @@ static rpmRC parseSpecSection(rpmSpec *specptr, int secondary)
}
}

if (!secondary && parseBuildsystem(spec))
goto errxit;

/* Add arch for each package */
addArch(spec);

Expand Down Expand Up @@ -1105,10 +1213,10 @@ static rpmSpec parseSpec(const char *specFile, rpmSpecFlags flags,
if (parseSpecSection(&spec, 0) != RPMRC_OK)
goto errxit;

if (spec->clean == NULL) {
char *body = rpmExpand("%{?buildroot: %{__rm} -rf %{buildroot}}", NULL);
spec->clean = newStringBuf();
appendLineStringBuf(spec->clean, body);
if (spec->sections[SECT_CLEAN] == NULL) {
char *body = rpmExpand("%{buildsystem_default_clean}", NULL);
spec->sections[SECT_CLEAN] = newStringBuf();
appendLineStringBuf(spec->sections[SECT_CLEAN], body);
free(body);
}

Expand Down
25 changes: 18 additions & 7 deletions build/rpmbuild_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@
#define ALLOWED_CHARS_EVR ALLOWED_CHARS_VERREL "-:"
#define LEN_AND_STR(_tag) (sizeof(_tag)-1), (_tag)


enum sections_e {
SECT_PREP = 0,
SECT_CONF = 1,
SECT_BUILDREQUIRES = 2,
SECT_BUILD = 3,
SECT_INSTALL = 4,
SECT_CHECK = 5,
SECT_CLEAN = 6,
};
#define NR_SECT 7

struct TriggerFileEntry {
int index;
char * fileName;
Expand Down Expand Up @@ -137,13 +149,8 @@ struct rpmSpec_s {
rpmMacroContext macros;
rpmstrPool pool;

StringBuf prep; /*!< %prep scriptlet. */
StringBuf conf; /*!< %conf scriptlet. */
StringBuf buildrequires; /*!< %buildrequires scriptlet. */
StringBuf build; /*!< %build scriptlet. */
StringBuf install; /*!< %install scriptlet. */
StringBuf check; /*!< %check scriptlet. */
StringBuf clean; /*!< %clean scriptlet. */
StringBuf sections[NR_SECT]; /*!< spec sections (%prep etc) */
ARGV_t buildopts[NR_SECT]; /*!< per-section buildsystem options */

StringBuf parsed; /*!< parsed spec contents */

Expand Down Expand Up @@ -634,6 +641,10 @@ void doSetupMacro(rpmMacroBuf mb, rpmMacroEntry me, ARGV_t margs, size_t *parsed
RPM_GNUC_INTERNAL
void doPatchMacro(rpmMacroBuf mb, rpmMacroEntry me, ARGV_t margs, size_t *parsed);

/* Return section number, -1 on error */
RPM_GNUC_INTERNAL
int getSection(const char *name);

#ifdef __cplusplus
}
#endif
Expand Down
Loading