* Mark Huang <mlhuang@cs.princeton.edu>
* Copyright (C) 2006 The Trustees of Princeton University
*
- * $Id$
*/
#include <stdio.h>
#include <rpm/rpmbuild.h>
#include <rpm/rpmspec.h>
+/* from f10 and up, Spec is renamed rpmSpec */
+#ifndef _RPMTYPES_H
+#define rpmSpec Spec
+#endif
+
+#define MAX_WHITELIST_SIZE 16
+
+#ifndef PATH_MAX
+#include <linux/limits.h>
+#endif
extern size_t strnlen(const char *s, size_t maxlen);
/* the structure describing the options we take and the defaults */
static struct poptOption optionsTable[] = {
+ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmBuildPoptTable, 0,
+ "Build options with [ <specfile> | <tarball> | <source package> ]:",
+ NULL },
+
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
"Common options for all rpm modes and executables:",
NULL },
};
/* Stolen from rpm/build/spec.c:rpmspecQuery() */
-Spec
+rpmSpec
rpmspecGet(rpmts ts, const char * arg)
{
char * buildRoot = NULL;
poptContext context;
rpmts ts = NULL;
int ec = 0;
- Spec spec;
+ rpmSpec spec;
struct Source *source;
Package pkg;
const char *name, *version, *release, *arch, *unused;
const char *package_name;
+ char **package_whitelist;
+
/* BEGIN: support to pull out --target from the args list */
int alen, i;
char *target = NULL;
int args = 1;
- int tlen = strlen("--target");
+ int whitelist_size=0;
+ package_whitelist = (char **) malloc(MAX_WHITELIST_SIZE * sizeof(char *));
+ if (!package_whitelist) {
+ perror("Could not allocate package whitelist\n");
+ exit(1);
+ }
- /* walk argv list looking for --target */
+ /* walk argv list looking for options */
while ((args+1)<argc) {
- if(strncmp(argv[args],"--target",tlen)==0){
- char **dash;
+ /* whitelist-rpms are packages that need to be considered even if the parsing logic of spec2make (second half of this file) concludes otherwise */
+ if (strcmp(argv[args],"--whitelist-rpms")==0) {
+ /* Split "whitelist-rpms" which is a comma-separated list, remove --whitelist-rpms <option> from argv */
- /* get arch component of the --target option */
- dash = (char**)strchr(argv[args+1],'-');
- if (dash != NULL) *dash=NULL;
+ int option_offset = 1;
+ char *whitelist_str = argv[args+1];
+ if (whitelist_str != NULL) {
+ char *saveptr = NULL, *str;
+ option_offset = 2;
+ for (str = whitelist_str; ; str = NULL) {
+ char *token;
+ token = strtok_r(str, "," , &saveptr);
+ if (token == NULL) break;
+ package_whitelist[whitelist_size++] = token;
+ }
+ }
+ for (i=args;i<argc-2+option_offset;i++) argv[i]=argv[i+option_offset];
+ argc-=option_offset;
- /* copy arch component of --target option to target */
- alen = strnlen(argv[args+1],32);
- target = (char*)malloc(alen+1);
- if (target == NULL) return errno;
- strncpy(target,argv[args+1],alen);
- target[alen]='\0';
+ } else if (strcmp(argv[args],"--target")==0) {
+ char **dash;
- /* change argc, argv to take out the "--target xxx" */
- for (i=args;i<argc;i++) argv[i]=argv[i+2];
- argc-=2;
+ /* get arch component of the --target option */
+ dash = (char**)strchr(argv[args+1],'-');
+ if (dash != NULL) *dash=NULL;
- break;
- }
- args++;
+ /* copy arch component of --target option to target */
+ alen = strnlen(argv[args+1],32);
+ target = (char*)malloc(alen+1);
+ if (target == NULL) return errno;
+ strncpy(target,argv[args+1],alen);
+ target[alen]='\0';
+
+ /* change argc, argv to take out the "--target xxx" */
+ for (i=args;i<argc;i++) argv[i]=argv[i+2];
+ argc-=2;
+
+ break;
+ }
+ else
+ args++;
}
argv[1]=argv[argc-2];
argv[2]=argv[argc-1];
char *suffix_index;
for (suffix=suffixes ; *suffix ; suffix++) {
- printf("# trying %s\n",*suffix);
+ /*printf("# trying %s\n",*suffix);*/
suffix_index=strstr(fullSource,*suffix);
if (suffix_index) {
char sourcename[PATH_MAX];
strncpy(sourcename,fullSource,len);
sourcename[len]='\0';
printf ("%s.source := SOURCES/%s\n",package_name,basename(sourcename));
- printf ("%s.codebase := CODEBASES/%s\n",package_name,package_name);
break;
}
}
/* Print non-empty packages */
for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
+ int force = 0;
name = version = release = arch = NULL;
(void) headerNEVRA(pkg->header, &name, &unused, &version, &release, &arch);
if (name && version && release && arch) {
arch=target;
}
}
- /* skip empty packages */
- if (pkg->fileList) {
- /* attach (add) rpm path to package */
- printf("%s.rpms += RPMS/%s/%s-%s-%s.%s.rpm\n",
- package_name, arch, name, version, release, arch);
- /* convenience */
- printf("%s.rpmnames += %s\n",
- package_name, name);
- /* attach path to rpm name */
- printf("%s.rpm-path := RPMS/%s/%s-%s-%s.%s.rpm\n",
- name,arch, name, version, release, arch);
- /* attach package to rpm name for backward resolution - should be unique */
- printf("%s.package := %s\n",
- name,package_name);
+ /* skip empty packages
+ *
+ * Unfortunately, f8 + the RHEL kernel break this bit of cleverness. The following
+ * line returns false for the kernel-devel package even though it is not empty thereby breaking the build.
+ * Rather than unfolding the kernel package macros in the current specfile,
+ * this hack should work till f8 dies its natural death.
+ * To add rpms that are exempted in this way, add a "<package>-WHITELIST-RPMS" tag in the tags file.
+ */
+
+ for (i=0;i<whitelist_size;i++) if (strncmp(package_whitelist[i], name, strlen(name)) == 0) force = 1;
+
+ if (pkg->fileList || force) {
+ /* attach (add) rpm path to package */
+ printf("%s.rpms += RPMS/%s/%s-%s-%s.%s.rpm\n",
+ package_name, arch, name, version, release, arch);
+ /* convenience */
+ printf("%s.rpmnames += %s\n",
+ package_name, name);
+ /* attach path to rpm name */
+ printf("%s.rpm-path := RPMS/%s/%s-%s-%s.%s.rpm\n",
+ name,arch, name, version, release, arch);
+ /* attach package to rpm name for backward resolution - should be unique */
+ printf("%s.package := %s\n",
+ name,package_name);
}
}
}