Add macro %isu_package to generate ISU Package
[platform/upstream/rpm.git] / rpmbuild.c
index 975364e..893a559 100644 (file)
@@ -1,5 +1,4 @@
 #include "system.h"
-const char *__progname;
 
 #include <errno.h>
 #include <libgen.h>
@@ -28,9 +27,10 @@ static struct rpmBuildArguments_s rpmBTArgs;
 #define        POPT_NOBUILD            -1017
 #define        POPT_RMSPEC             -1019
 #define POPT_NODIRTOKENS       -1020
+#define POPT_BUILDINPLACE      -1021
 
-#define        POPT_REBUILD            0x4220
-#define        POPT_RECOMPILE          0x4320
+#define        POPT_REBUILD            0x4262 /* Bb */
+#define        POPT_RECOMPILE          0x4369 /* Ci */
 #define        POPT_BA                 0x6261
 #define        POPT_BB                 0x6262
 #define        POPT_BC                 0x6263
@@ -38,6 +38,13 @@ static struct rpmBuildArguments_s rpmBTArgs;
 #define        POPT_BL                 0x626c
 #define        POPT_BP                 0x6270
 #define        POPT_BS                 0x6273
+#define        POPT_RA                 0x4261
+#define        POPT_RB                 0x4262
+#define        POPT_RC                 0x4263
+#define        POPT_RI                 0x4269
+#define        POPT_RL                 0x426c
+#define        POPT_RP                 0x4270
+#define        POPT_RS                 0x4273
 #define        POPT_TA                 0x7461
 #define        POPT_TB                 0x7462
 #define        POPT_TC                 0x7463
@@ -53,7 +60,9 @@ static int noDeps = 0;                        /*!< from --nodeps */
 static int shortCircuit = 0;           /*!< from --short-circuit */
 static char buildMode = 0;             /*!< Build mode (one of "btBC") */
 static char buildChar = 0;             /*!< Build stage (one of "abcilps ") */
+static rpmBuildFlags nobuildAmount = 0;        /*!< Build stage disablers */
 static ARGV_t build_targets = NULL;    /*!< Target platform(s) */
+static int buildInPlace = 0;           /*!< from --build-in-place */
 
 static void buildArgCallback( poptContext con,
        enum poptCallbackReason reason,
@@ -72,6 +81,13 @@ static void buildArgCallback( poptContext con,
     case POPT_BL:
     case POPT_BP:
     case POPT_BS:
+    case POPT_RA:
+    /* case POPT_RB: same value as POPT_REBUILD */
+    case POPT_RC:
+    case POPT_RI:
+    case POPT_RL:
+    case POPT_RP:
+    case POPT_RS:
     case POPT_TA:
     case POPT_TB:
     case POPT_TC:
@@ -108,6 +124,10 @@ static void buildArgCallback( poptContext con,
        spec_flags |= RPMSPEC_FORCE;
        break;
 
+    case POPT_BUILDINPLACE:
+       rpmDefineMacro(NULL, "_build_in_place 1", 0);
+       buildInPlace = 1;
+       break;
     }
 }
 
@@ -137,6 +157,28 @@ static struct poptOption rpmBuildPoptTable[] = {
        N_("build source package only from <specfile>"),
        N_("<specfile>") },
 
+ { "rp", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_RP,
+       N_("build through %prep (unpack sources and apply patches) from <source package>"),
+       N_("<source package>") },
+ { "rc", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_RC,
+       N_("build through %build (%prep, then compile) from <source package>"),
+       N_("<source package>") },
+ { "ri", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_RI,
+       N_("build through %install (%prep, %build, then install) from <source package>"),
+       N_("<source package>") },
+ { "rl", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_RL,
+       N_("verify %files section from <source package>"),
+       N_("<source package>") },
+ { "ra", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_RA,
+       N_("build source and binary packages from <source package>"),
+       N_("<source package>") },
+ { "rb", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_RB,
+       N_("build binary package only from <source package>"),
+       N_("<source package>") },
+ { "rs", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_RS,
+       N_("build source package only from <source package>"),
+       N_("<source package>") },
+
  { "tp", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TP,
        N_("build through %prep (unpack sources and apply patches) from <tarball>"),
        N_("<tarball>") },
@@ -168,6 +210,8 @@ static struct poptOption rpmBuildPoptTable[] = {
 
  { "buildroot", '\0', POPT_ARG_STRING, 0,  POPT_BUILDROOT,
        N_("override build root"), "DIRECTORY" },
+ { "build-in-place", '\0', 0, 0, POPT_BUILDINPLACE,
+       N_("run build in current directory"), NULL },
  { "clean", '\0', 0, 0, POPT_RMBUILD,
        N_("remove build tree when done"), NULL},
  { "force", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, RPMCLI_POPT_FORCE,
@@ -182,6 +226,13 @@ static struct poptOption rpmBuildPoptTable[] = {
        N_("generate package header(s) compatible with (legacy) rpm v3 packaging"),
        NULL},
 
+ { "noclean", '\0', POPT_BIT_SET, &nobuildAmount, RPMBUILD_CLEAN,
+       N_("do not execute %clean stage of the build"), NULL },
+ { "noprep", '\0', POPT_BIT_SET, &nobuildAmount, RPMBUILD_PREP,
+       N_("do not execute %prep stage of the build"), NULL },
+ { "nocheck", '\0', POPT_BIT_SET, &nobuildAmount, RPMBUILD_CHECK,
+       N_("do not execute %check stage of the build"), NULL },
+
  { "nolang", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_NOLANG,
        N_("do not accept i18N msgstr's from specfile"), NULL},
  { "rmsource", '\0', 0, 0, POPT_RMSOURCE,
@@ -232,7 +283,7 @@ static int checkSpec(rpmts ts, rpmSpec spec)
        rpmpsPrint(NULL, ps);
     }
     rc = (ps != NULL);
-    ps = rpmpsFree(ps);
+    rpmpsFree(ps);
     return rc;
 }
 
@@ -245,7 +296,7 @@ static int isSpecFile(const char * specfile)
     int checking;
 
     f = fopen(specfile, "r");
-    if (f == NULL || ferror(f)) {
+    if (f == NULL) {
        rpmlog(RPMLOG_ERR, _("Unable to open spec file %s: %s\n"),
                specfile, strerror(errno));
        return 0;
@@ -289,7 +340,7 @@ static char * getTarSpec(const char *arg)
     char *specDir;
     char *specBase;
     char *tmpSpecFile;
-    const char **try;
+    const char **spec;
     char tarbuf[BUFSIZ];
     int gotspec = 0, res;
     static const char *tryspec[] = { "Specfile", "\\*.spec", NULL };
@@ -299,12 +350,13 @@ static char * getTarSpec(const char *arg)
 
     (void) close(mkstemp(tmpSpecFile));
 
-    for (try = tryspec; *try != NULL; try++) {
+    for (spec = tryspec; *spec != NULL; spec++) {
        FILE *fp;
        char *cmd;
+       int specfiles = 0;
 
        cmd = rpmExpand("%{uncompress: ", arg, "} | ",
-                       "%{__tar} xOvf - --wildcards ", *try,
+                       "%{__tar} xOvof - --wildcards ", *spec,
                        " 2>&1 > ", tmpSpecFile, NULL);
 
        if (!(fp = popen(cmd, "r"))) {
@@ -313,12 +365,19 @@ static char * getTarSpec(const char *arg)
            char *fok;
            for (;;) {
                fok = fgets(tarbuf, sizeof(tarbuf) - 1, fp);
+               if (!fok) break;
                /* tar sometimes prints "tar: Record size = 16" messages */
-               if (!fok || strncmp(fok, "tar: ", 5) != 0)
-                   break;
+               if (strstr(fok, "tar: ")) {
+                   continue;
+               }
+               specfiles++;
            }
            pclose(fp);
-           gotspec = (fok != NULL) && isSpecFile(tmpSpecFile);
+           gotspec = (specfiles == 1) && isSpecFile(tmpSpecFile);
+           if (specfiles > 1) {
+               rpmlog(RPMLOG_ERR, _("Found more than one spec file in %s\n"), arg);
+               goto exit;
+           }
        }
 
        if (!gotspec) 
@@ -367,9 +426,12 @@ static int buildForTarget(rpmts ts, const char * arg, BTA_t ba)
     int justRm = ((buildAmount & ~(RPMBUILD_RMSOURCE|RPMBUILD_RMSPEC)) == 0);
     rpmSpecFlags specFlags = spec_flags;
 
-#ifndef        DYING
-    rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS);
-#endif
+    /* Override default BUILD value for _builddir */
+    if (buildInPlace) {
+       char *cwd = rpmGetCwd();
+       rpmPushMacro(NULL, "_builddir", NULL, cwd, 0);
+       free(cwd);
+    }
 
     if (ba->buildRootOverride)
        buildRootURL = rpmGenPath(NULL, ba->buildRootOverride, NULL);
@@ -397,7 +459,7 @@ static int buildForTarget(rpmts ts, const char * arg, BTA_t ba)
            dir = xstrdup(arg);
        }
        srcdir = dirname(dir);
-       addMacro(NULL, "_sourcedir", NULL, srcdir, RMIL_TARBALL);
+       rpmPushMacro(NULL, "_sourcedir", NULL, srcdir, RMIL_TARBALL);
        free(dir);
     } else {
        specFile = xstrdup(arg);
@@ -406,7 +468,7 @@ static int buildForTarget(rpmts ts, const char * arg, BTA_t ba)
     if (*specFile != '/') {
        char *cwd = rpmGetCwd();
        char *s = NULL;
-       rasprintf(&s, "%s/%s", cwd, arg);
+       rasprintf(&s, "%s/%s", cwd, specFile);
        free(cwd);
        free(specFile);
        specFile = s;
@@ -503,6 +565,10 @@ static int build(rpmts ts, const char * arg, BTA_t ba, const char * rcfile)
 
        /* Read in configuration for target. */
        rpmFreeMacros(NULL);
+       if (buildInPlace) {
+               /* Need to redefine this after freeing all the macros */
+               rpmDefineMacro(NULL, "_build_in_place 1", 0);
+       }
        rpmFreeRpmrc();
        (void) rpmReadConfigFiles(rcfile, *target);
        rc = buildForTarget(ts, arg, ba);
@@ -511,7 +577,7 @@ static int build(rpmts ts, const char * arg, BTA_t ba, const char * rcfile)
     }
 
 exit:
-    vsflags = rpmtsSetVSFlags(ts, ovsflags);
+    rpmtsSetVSFlags(ts, ovsflags);
     /* Restore original configuration. */
     rpmFreeMacros(NULL);
     rpmFreeRpmrc();
@@ -529,9 +595,15 @@ int main(int argc, char *argv[])
 
     const char *pkg = NULL;
     int ec = 0;
-    poptContext optCon = rpmcliInit(argc, argv, optionsTable);
 
-    if (argc <= 1 || poptPeekArg(optCon) == NULL) {
+    poptContext optCon = NULL;
+
+    xsetprogname(argv[0]); /* Portability call -- see system.h */
+
+    optCon = rpmcliInit(argc, argv, optionsTable);
+
+    /* Args required only when building, let lone --eval etc through */
+    if (ba->buildAmount && poptPeekArg(optCon) == NULL) {
        printUsage(optCon, stderr, 0);
        exit(EXIT_FAILURE);
     }
@@ -547,26 +619,62 @@ int main(int argc, char *argv[])
        argerror(_("arguments to --root (-r) must begin with a /"));
     }
 
-    /* rpmbuild is rather chatty by default */
-    rpmSetVerbosity(quiet ? RPMLOG_WARNING : RPMLOG_INFO);
+    /* rpmbuild runs in verbose mode by default */
+    if (rpmlogSetMask(0) < RPMLOG_MASK(RPMLOG_INFO))
+       rpmSetVerbosity(RPMLOG_INFO);
+
+    if (quiet)
+       rpmSetVerbosity(RPMLOG_WARNING);
 
     if (rpmcliPipeOutput && initPipe())
        exit(EXIT_FAILURE);
        
     ts = rpmtsCreate();
     (void) rpmtsSetRootDir(ts, rpmcliRootDir);
+    rpmtsSetFlags(ts, rpmtsFlags(ts) | RPMTRANS_FLAG_NOPLUGINS);
+
+    switch (buildChar) {
+    case 'a':
+       ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
+    case 'b':
+       ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
+       ba->buildAmount |= RPMBUILD_CLEAN;
+       if ((buildChar == 'b') && shortCircuit)
+           break;
+    case 'i':
+       ba->buildAmount |= RPMBUILD_INSTALL;
+       ba->buildAmount |= RPMBUILD_CHECK;
+       if ((buildChar == 'i') && shortCircuit)
+           break;
+    case 'c':
+       ba->buildAmount |= RPMBUILD_BUILD;
+       if ((buildChar == 'c') && shortCircuit)
+           break;
+    case 'p':
+       ba->buildAmount |= RPMBUILD_PREP;
+       break;
+    case 'l':
+       ba->buildAmount |= RPMBUILD_FILECHECK;
+       break;
+    case 's':
+       ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
+       break;
+    }
+    ba->buildAmount &= ~(nobuildAmount);
+
     switch (bigMode) {
     case MODE_REBUILD:
     case MODE_RECOMPILE:
-       ba->buildAmount =
-           RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK;
-       if (bigMode == MODE_REBUILD) {
-           ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
+       if (bigMode == MODE_REBUILD &&
+           buildChar != 'p' &&
+           buildChar != 'c' &&
+           buildChar != 'i' &&
+           buildChar != 'l') {
            ba->buildAmount |= RPMBUILD_RMSOURCE;
            ba->buildAmount |= RPMBUILD_RMSPEC;
-           ba->buildAmount |= RPMBUILD_CLEAN;
            ba->buildAmount |= RPMBUILD_RMBUILD;
        }
+       ba->buildAmount &= ~(nobuildAmount);
 
        while ((pkg = poptGetArg(optCon))) {
            char * specFile = NULL;
@@ -586,34 +694,6 @@ int main(int argc, char *argv[])
        break;
     case MODE_BUILD:
     case MODE_TARBUILD:
-       switch (buildChar) {
-       case 'a':
-           ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
-       case 'b':
-           ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
-           ba->buildAmount |= RPMBUILD_CLEAN;
-           if ((buildChar == 'b') && shortCircuit)
-               break;
-       case 'i':
-           ba->buildAmount |= RPMBUILD_INSTALL;
-           ba->buildAmount |= RPMBUILD_CHECK;
-           if ((buildChar == 'i') && shortCircuit)
-               break;
-       case 'c':
-           ba->buildAmount |= RPMBUILD_BUILD;
-           if ((buildChar == 'c') && shortCircuit)
-               break;
-       case 'p':
-           ba->buildAmount |= RPMBUILD_PREP;
-           break;
-           
-       case 'l':
-           ba->buildAmount |= RPMBUILD_FILECHECK;
-           break;
-       case 's':
-           ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
-           break;
-       }
 
        while ((pkg = poptGetArg(optCon))) {
            ba->rootdir = rpmcliRootDir;
@@ -627,10 +707,11 @@ int main(int argc, char *argv[])
        break;
     }
 
-    ts = rpmtsFree(ts);
-    finishPipe();
-    ba->buildRootOverride = _free(ba->buildRootOverride);
-    build_targets = argvFree(build_targets);
+    rpmtsFree(ts);
+    if (finishPipe())
+       ec = EXIT_FAILURE;
+    free(ba->buildRootOverride);
+    argvFree(build_targets);
 
     rpmcliFini(optCon);