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

Move checks and package initialization after build #2646

Merged
merged 7 commits into from
Oct 12, 2023
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
80 changes: 46 additions & 34 deletions build/parsePreamble.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ static const rpmTagVal copyTagsDuringParse[] = {
0
};

/**
*/
static const rpmTagVal requiredTagsForBuild[] = {
RPMTAG_NAME,
RPMTAG_VERSION,
RPMTAG_RELEASE,
0
};

/**
*/
static const rpmTagVal requiredTags[] = {
Expand Down Expand Up @@ -415,7 +424,7 @@ static inline char * findLastChar(char * s)

/**
*/
static int isMemberInEntry(Header h, const char *name, rpmTagVal tag)
int isMemberInEntry(Header h, const char *name, rpmTagVal tag)
{
struct rpmtd_s td;
int found = 0;
Expand All @@ -437,7 +446,7 @@ static int isMemberInEntry(Header h, const char *name, rpmTagVal tag)

/**
*/
static rpmRC checkForValidArchitectures(rpmSpec spec)
rpmRC checkForValidArchitectures(rpmSpec spec)
{
char *arch = rpmExpand("%{_target_cpu}", NULL);
char *os = rpmExpand("%{_target_os}", NULL);
Expand Down Expand Up @@ -483,7 +492,7 @@ static rpmRC checkForValidArchitectures(rpmSpec spec)
* @param NVR package name-version-release
* @return RPMRC_OK if OK
*/
static int checkForRequired(Header h, const char * NVR)
int checkForRequired(Header h)
{
int res = RPMRC_OK;
const rpmTagVal * p;
Expand All @@ -492,7 +501,30 @@ static int checkForRequired(Header h, const char * NVR)
if (!headerIsEntry(h, *p)) {
rpmlog(RPMLOG_ERR,
_("%s field must be present in package: %s\n"),
rpmTagGetName(*p), NVR);
rpmTagGetName(*p), headerGetString(h, RPMTAG_NAME));
res = RPMRC_FAIL;
}
}

return res;
}

/**
* Check that required tags are present in header.
* @param h header
* @param NVR package name-version-release
* @return RPMRC_OK if OK
*/
static int checkForRequiredForBuild(Header h)
{
int res = RPMRC_OK;
const rpmTagVal * p;

for (p = requiredTagsForBuild; *p != 0; p++) {
if (!headerIsEntry(h, *p)) {
rpmlog(RPMLOG_ERR,
_("%s field must be present before build in package: %s\n"),
rpmTagGetName(*p), headerGetString(h, RPMTAG_NAME));
res = RPMRC_FAIL;
}
}
Expand All @@ -506,7 +538,7 @@ static int checkForRequired(Header h, const char * NVR)
* @param NVR package name-version-release
* @return RPMRC_OK if OK
*/
static int checkForDuplicates(Header h, const char * NVR)
int checkForDuplicates(Header h)
{
int res = RPMRC_OK;
rpmTagVal tag, lastTag = RPMTAG_NOT_FOUND;
Expand All @@ -515,7 +547,7 @@ static int checkForDuplicates(Header h, const char * NVR)
while ((tag = headerNextTag(hi)) != RPMTAG_NOT_FOUND) {
if (tag == lastTag) {
rpmlog(RPMLOG_ERR, _("Duplicate %s entries in package: %s\n"),
rpmTagGetName(tag), NVR);
rpmTagGetName(tag), headerGetString(h, RPMTAG_NAME));
res = RPMRC_FAIL;
}
lastTag = tag;
Expand Down Expand Up @@ -545,7 +577,7 @@ static struct optionalTag {

/**
*/
static void fillOutMainPackage(Header h)
void fillOutMainPackage(Header h)
{
const struct optionalTag *ot;

Expand Down Expand Up @@ -1153,11 +1185,13 @@ int parsePreamble(rpmSpec spec, int initialPackage)
NVR = xstrdup(name);
pkg = newPackage(NVR, spec->pool, &spec->packages);
headerPutString(pkg->header, RPMTAG_NAME, NVR);
} else if (spec->sourcePackage) {
NVR = xstrdup("(main package)");
pkg = spec->packages;
} else {
NVR = xstrdup("(main package)");
pkg = newPackage(NULL, spec->pool, &spec->packages);
spec->sourcePackage = newPackage(NULL, spec->pool, NULL);

}

if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) {
Expand Down Expand Up @@ -1212,6 +1246,10 @@ int parsePreamble(rpmSpec spec, int initialPackage)
* can't be messed with by anything spec does beyond this point.
*/
if (initialPackage) {
if (checkForRequiredForBuild(pkg->header)) {
goto exit;
}

char *buildRoot = rpmGetPath(spec->buildRoot, NULL);
free(spec->buildRoot);
spec->buildRoot = buildRoot;
Expand All @@ -1226,32 +1264,6 @@ int parsePreamble(rpmSpec spec, int initialPackage)
}
}

/* XXX Skip valid arch check if not building binary package */
if (!(spec->flags & RPMSPEC_ANYARCH) && checkForValidArchitectures(spec)) {
goto exit;
}

/* It is the main package */
if (pkg == spec->packages) {
fillOutMainPackage(pkg->header);
/* Define group tag to something when group is undefined in main package*/
if (!headerIsEntry(pkg->header, RPMTAG_GROUP)) {
headerPutString(pkg->header, RPMTAG_GROUP, "Unspecified");
}
}

if (checkForDuplicates(pkg->header, NVR)) {
goto exit;
}

if (pkg != spec->packages) {
copyInheritedTags(pkg->header, spec->packages->header);
}

if (checkForRequired(pkg->header, NVR)) {
goto exit;
}

/* if we get down here nextPart has been set to non-error */
res = nextPart;

Expand Down
127 changes: 86 additions & 41 deletions build/parseSpec.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,10 @@ static void initSourceHeader(rpmSpec spec)
if (headerIsEntry(sourcePkg->header, RPMTAG_NAME))
return;

char *os = rpmExpand("%{_target_os}", NULL);
headerPutString(sourcePkg->header, RPMTAG_OS, os);
free(os);

/* Only specific tags are added to the source package header */
headerCopyTags(spec->packages->header, sourcePkg->header, sourceTags);

Expand Down Expand Up @@ -694,11 +698,17 @@ static void initSourceHeader(rpmSpec spec)
}
}
}
}

static void finalizeSourceHeader(rpmSpec spec)
{
/* Only specific tags are added to the source package header */
headerCopyTags(spec->packages->header, spec->sourcePackage->header, sourceTags);

/* Provide all package NEVRs that would be built */
for (Package p = spec->packages; p != NULL; p = p->next) {
if (p->fileList) {
Header h = sourcePkg->header;
Header h = spec->sourcePackage->header;
uint32_t dsflags = rpmdsFlags(p->ds);
headerPutString(h, RPMTAG_PROVIDENAME, rpmdsN(p->ds));
headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &dsflags, 1);
Expand Down Expand Up @@ -733,37 +743,17 @@ void addPackageProvides(Package pkg)
free(evr);
}

static void addTargets(Package Pkgs)
static void addArch(rpmSpec spec)
{
char *platform = rpmExpand("%{_target_platform}", NULL);
char *arch = rpmExpand("%{_target_cpu}", NULL);
char *os = rpmExpand("%{_target_os}", NULL);
char *optflags = rpmExpand("%{optflags}", NULL);

for (Package pkg = Pkgs; pkg != NULL; pkg = pkg->next) {
if (headerIsEntry(pkg->header, RPMTAG_OS)) {
continue;
}
headerPutString(pkg->header, RPMTAG_OS, os);
for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
/* noarch subpackages already have arch set here, leave it alone */
if (!headerIsEntry(pkg->header, RPMTAG_ARCH)) {
headerPutString(pkg->header, RPMTAG_ARCH, arch);
}
headerPutString(pkg->header, RPMTAG_PLATFORM, platform);
headerPutString(pkg->header, RPMTAG_OPTFLAGS, optflags);

/* Add manual dependencies early for rpmspec etc to look at */
addPackageProvides(pkg);
for (int i=0; i<PACKAGE_NUM_DEPS; i++) {
rpmdsPutToHeader(pkg->dependencies[i], pkg->header);
}

pkg->ds = rpmdsThis(pkg->header, RPMTAG_REQUIRENAME, RPMSENSE_EQUAL);
}
free(platform);
free(arch);
free(os);
free(optflags);
}

rpmRC checkForEncoding(Header h, int addtag)
Expand Down Expand Up @@ -901,12 +891,6 @@ static rpmRC parseSpecSection(rpmSpec *specptr, int secondary)
int storedParsePart;
int initialPackage = 1;

if (secondary) {
initialPackage = 0;
parsePart = PART_EMPTY;
prevParsePart = PART_NONE;
}

/* All the parse*() functions expect to have a line pre-read */
/* in the spec's line buffer. Except for parsePreamble(), */
/* which handles the initial entry into a spec file. */
Expand Down Expand Up @@ -1053,17 +1037,8 @@ static rpmRC parseSpecSection(rpmSpec *specptr, int secondary)
}
}

/* Check for description in each package */
for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
if (!headerIsEntry(pkg->header, RPMTAG_DESCRIPTION)) {
rpmlog(RPMLOG_ERR, _("Package has no %%description: %s\n"),
headerGetString(pkg->header, RPMTAG_NAME));
goto errxit;
}
}

/* Add arch, os and platform, self-provides etc for each package */
addTargets(spec->packages);
/* Add arch for each package */
addArch(spec);

/* Check for encoding in each package unless disabled */
if (!(spec->flags & RPMSPEC_NOUTF8)) {
Expand Down Expand Up @@ -1128,10 +1103,74 @@ static rpmSpec parseSpec(const char *specFile, rpmSpecFlags flags,
return NULL;
}

static rpmRC finalizeSpec(rpmSpec spec)
{
rpmRC rc = RPMRC_FAIL;

char *platform = rpmExpand("%{_target_platform}", NULL);
char *os = rpmExpand("%{_target_os}", NULL);
char *optflags = rpmExpand("%{optflags}", NULL);

/* XXX Skip valid arch check if not building binary package */
if (!(spec->flags & RPMSPEC_ANYARCH) && checkForValidArchitectures(spec)) {
goto exit;
}

fillOutMainPackage(spec->packages->header);
/* Define group tag to something when group is undefined in main package*/
if (!headerIsEntry(spec->packages->header, RPMTAG_GROUP)) {
headerPutString(spec->packages->header, RPMTAG_GROUP, "Unspecified");
}

for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
headerPutString(pkg->header, RPMTAG_OS, os);
headerPutString(pkg->header, RPMTAG_PLATFORM, platform);
headerPutString(pkg->header, RPMTAG_OPTFLAGS, optflags);

if (pkg != spec->packages) {
copyInheritedTags(pkg->header, spec->packages->header);
}

/* Add manual dependencies early for rpmspec etc to look at */
addPackageProvides(pkg);

for (int i=0; i<PACKAGE_NUM_DEPS; i++) {
rpmdsPutToHeader(pkg->dependencies[i], pkg->header);
}

pkg->ds = rpmdsThis(pkg->header, RPMTAG_REQUIRENAME, RPMSENSE_EQUAL);

if (checkForRequired(pkg->header)) {
goto exit;
}
if (!headerIsEntry(pkg->header, RPMTAG_DESCRIPTION)) {
rpmlog(RPMLOG_ERR, _("Package has no %%description: %s\n"),
headerGetString(pkg->header, RPMTAG_NAME));
goto exit;
}
if (checkForDuplicates(pkg->header)) {
goto exit;
}
}

finalizeSourceHeader(spec);

rc = RPMRC_OK;
exit:
free(platform);
free(os);
free(optflags);
return rc;
}

rpmSpec rpmSpecParse(const char *specFile, rpmSpecFlags flags,
const char *buildRoot)
{
return parseSpec(specFile, flags, buildRoot, 0);
rpmSpec spec = parseSpec(specFile, flags, buildRoot, 0);
if (spec && !(flags & RPMSPEC_NOFINALIZE)) {
finalizeSpec(spec);
}
return spec;
}

rpmRC parseGeneratedSpecs(rpmSpec spec)
Expand All @@ -1158,5 +1197,11 @@ rpmRC parseGeneratedSpecs(rpmSpec spec)
argvFree(argv);
}
free(specPattern);
if (!rc) {
rc = finalizeSpec(spec);
if (rc != RPMRC_OK) {
rpmlog(RPMLOG_ERR, "parsing failed\n");
}
}
return rc;
}
19 changes: 19 additions & 0 deletions build/rpmbuild_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,25 @@ void * specLuaFini(rpmSpec spec);

RPM_GNUC_INTERNAL
void addLuaSource(const struct Source *p);

RPM_GNUC_INTERNAL
int isMemberInEntry(Header h, const char *name, rpmTagVal tag);

RPM_GNUC_INTERNAL
rpmRC checkForValidArchitectures(rpmSpec spec);

RPM_GNUC_INTERNAL
int checkForRequired(Header h);

RPM_GNUC_INTERNAL
int checkForDuplicates(Header h);

RPM_GNUC_INTERNAL
void fillOutMainPackage(Header h);

RPM_GNUC_INTERNAL
void copyInheritedTags(Header h, Header fromh);

#ifdef __cplusplus
}
#endif
Expand Down
1 change: 1 addition & 0 deletions include/rpm/rpmspec.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ enum rpmSpecFlags_e {
RPMSPEC_FORCE = (1 << 1),
RPMSPEC_NOLANG = (1 << 2),
RPMSPEC_NOUTF8 = (1 << 3),
RPMSPEC_NOFINALIZE = (1 << 4),
};

typedef rpmFlags rpmSpecFlags;
Expand Down
Loading