building for f31
[build.git] / spec2make.c
index 77ddec9..60004ef 100644 (file)
@@ -6,7 +6,6 @@
  * 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 },
@@ -34,7 +47,7 @@ static struct poptOption optionsTable[] = {
 };
 
 /* Stolen from rpm/build/spec.c:rpmspecQuery() */
-Spec
+rpmSpec
 rpmspecGet(rpmts ts, const char * arg)
 {
   char * buildRoot = NULL;
@@ -59,42 +72,69 @@ main(int argc, char *argv[])
   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];
@@ -131,7 +171,7 @@ main(int argc, char *argv[])
       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];
@@ -139,7 +179,6 @@ main(int argc, char *argv[])
          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;
        }
       }
@@ -157,6 +196,7 @@ main(int argc, char *argv[])
 
   /* 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) {
@@ -165,27 +205,38 @@ main(int argc, char *argv[])
          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);
       }
     }
   }
 
   /* export some macros to make */
+  /* note : this relies on pl-specific conventions and might be wrong */
   { 
-    char *macros[] = { "release" , "name" , "version" , "subversion" , NULL } ;
+    char *macros[] = { "release" , "name" , "version" , "taglevel" , NULL } ;
     char **nav;
     char *macro=malloc(32);
     for (nav=macros; *nav; nav++) {