Modify eu-strip option to perform strip in post script of rpm package & add option...
[platform/upstream/rpm.git] / rpmbuild.c
index cd9db7c..4fb4289 100644 (file)
@@ -14,11 +14,193 @@ const char *__progname;
 #include <rpm/rpmps.h>
 #include <rpm/rpmts.h>
 #include "lib/signature.h"
-#include "build/rpmbuild_misc.h"       /* XXX freeNames() */
 #include "cliutils.h"
 
 #include "debug.h"
 
+static struct rpmBuildArguments_s rpmBTArgs;
+
+#define        POPT_NOLANG             -1012
+#define        POPT_RMSOURCE           -1013
+#define        POPT_RMBUILD            -1014
+#define        POPT_BUILDROOT          -1015
+#define        POPT_TARGETPLATFORM     -1016
+#define        POPT_NOBUILD            -1017
+#define        POPT_RMSPEC             -1019
+#define POPT_NODIRTOKENS       -1020
+
+#define        POPT_REBUILD            0x4220
+#define        POPT_RECOMPILE          0x4320
+#define        POPT_BA                 0x6261
+#define        POPT_BB                 0x6262
+#define        POPT_BC                 0x6263
+#define        POPT_BI                 0x6269
+#define        POPT_BL                 0x626c
+#define        POPT_BP                 0x6270
+#define        POPT_BS                 0x6273
+#define        POPT_TA                 0x7461
+#define        POPT_TB                 0x7462
+#define        POPT_TC                 0x7463
+#define        POPT_TI                 0x7469
+#define        POPT_TL                 0x746c
+#define        POPT_TP                 0x7470
+#define        POPT_TS                 0x7473
+
+extern int _fsm_debug;
+
+static rpmSpecFlags spec_flags = 0;    /*!< Bit(s) to control spec parsing. */
+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 void buildArgCallback( poptContext con,
+       enum poptCallbackReason reason,
+       const struct poptOption * opt, const char * arg,
+       const void * data)
+{
+    BTA_t rba = &rpmBTArgs;
+
+    switch (opt->val) {
+    case POPT_REBUILD:
+    case POPT_RECOMPILE:
+    case POPT_BA:
+    case POPT_BB:
+    case POPT_BC:
+    case POPT_BI:
+    case POPT_BL:
+    case POPT_BP:
+    case POPT_BS:
+    case POPT_TA:
+    case POPT_TB:
+    case POPT_TC:
+    case POPT_TI:
+    case POPT_TL:
+    case POPT_TP:
+    case POPT_TS:
+       if (opt->val == POPT_BS || opt->val == POPT_TS)
+           noDeps = 1;
+       if (buildMode == '\0' && buildChar == '\0') {
+           buildMode = (((unsigned)opt->val) >> 8) & 0xff;
+           buildChar = (opt->val     ) & 0xff;
+       }
+       break;
+
+    case POPT_NODIRTOKENS: rba->pkgFlags |= RPMBUILD_PKG_NODIRTOKENS; break;
+    case POPT_NOBUILD: rba->buildAmount |= RPMBUILD_NOBUILD; break;
+    case POPT_NOLANG: spec_flags |= RPMSPEC_NOLANG; break;
+    case POPT_RMSOURCE: rba->buildAmount |= RPMBUILD_RMSOURCE; break;
+    case POPT_RMSPEC: rba->buildAmount |= RPMBUILD_RMSPEC; break;
+    case POPT_RMBUILD: rba->buildAmount |= RPMBUILD_RMBUILD; break;
+    case POPT_BUILDROOT:
+       if (rba->buildRootOverride) {
+           rpmlog(RPMLOG_ERR, _("buildroot already specified, ignoring %s\n"), arg);
+           break;
+       }
+       rba->buildRootOverride = xstrdup(arg);
+       break;
+    case POPT_TARGETPLATFORM:
+       argvSplit(&build_targets, arg, ",");
+       break;
+
+    case RPMCLI_POPT_FORCE:
+       spec_flags |= RPMSPEC_FORCE;
+       break;
+
+    }
+}
+
+static struct poptOption rpmBuildPoptTable[] = {
+ { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
+       buildArgCallback, 0, NULL, NULL },
+
+ { "bp", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BP,
+       N_("build through %prep (unpack sources and apply patches) from <specfile>"),
+       N_("<specfile>") },
+ { "bc", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BC,
+       N_("build through %build (%prep, then compile) from <specfile>"),
+       N_("<specfile>") },
+ { "bi", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BI,
+       N_("build through %install (%prep, %build, then install) from <specfile>"),
+       N_("<specfile>") },
+ { "bl", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BL,
+       N_("verify %files section from <specfile>"),
+       N_("<specfile>") },
+ { "ba", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BA,
+       N_("build source and binary packages from <specfile>"),
+       N_("<specfile>") },
+ { "bb", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BB,
+       N_("build binary package only from <specfile>"),
+       N_("<specfile>") },
+ { "bs", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BS,
+       N_("build source package only from <specfile>"),
+       N_("<specfile>") },
+
+ { "tp", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TP,
+       N_("build through %prep (unpack sources and apply patches) from <tarball>"),
+       N_("<tarball>") },
+ { "tc", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TC,
+       N_("build through %build (%prep, then compile) from <tarball>"),
+       N_("<tarball>") },
+ { "ti", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TI,
+       N_("build through %install (%prep, %build, then install) from <tarball>"),
+       N_("<tarball>") },
+ { "tl", 0, POPT_ARGFLAG_ONEDASH|POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_TL,
+       N_("verify %files section from <tarball>"),
+       N_("<tarball>") },
+ { "ta", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TA,
+       N_("build source and binary packages from <tarball>"),
+       N_("<tarball>") },
+ { "tb", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TB,
+       N_("build binary package only from <tarball>"),
+       N_("<tarball>") },
+ { "ts", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TS,
+       N_("build source package only from <tarball>"),
+       N_("<tarball>") },
+
+ { "rebuild", '\0', 0, 0, POPT_REBUILD,
+       N_("build binary package from <source package>"),
+       N_("<source package>") },
+ { "recompile", '\0', 0, 0, POPT_RECOMPILE,
+       N_("build through %install (%prep, %build, then install) from <source package>"),
+       N_("<source package>") },
+
+ { "buildroot", '\0', POPT_ARG_STRING, 0,  POPT_BUILDROOT,
+       N_("override build root"), "DIRECTORY" },
+ { "clean", '\0', 0, 0, POPT_RMBUILD,
+       N_("remove build tree when done"), NULL},
+ { "force", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, RPMCLI_POPT_FORCE,
+        N_("ignore ExcludeArch: directives from spec file"), NULL},
+ { "fsmdebug", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN), &_fsm_debug, -1,
+       N_("debug file state machine"), NULL},
+ { "nobuild", '\0', 0, 0,  POPT_NOBUILD,
+       N_("do not execute any stages of the build"), NULL },
+ { "nodeps", '\0', POPT_ARG_VAL, &noDeps, 1,
+       N_("do not verify build dependencies"), NULL },
+ { "nodirtokens", '\0', 0, 0, POPT_NODIRTOKENS,
+       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 },
+ { "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,
+       N_("remove sources when done"), NULL},
+ { "rmspec", '\0', 0, 0, POPT_RMSPEC,
+       N_("remove specfile when done"), NULL},
+ { "short-circuit", '\0', POPT_ARG_VAL, &shortCircuit,  1,
+       N_("skip straight to specified stage (only for c,i)"), NULL },
+ { "target", '\0', POPT_ARG_STRING, 0,  POPT_TARGETPLATFORM,
+       N_("override target platform"), "CPU-VENDOR-OS" },
+   POPT_TABLEEND
+};
+
 enum modes {
     MODE_BUILD         = (1 <<  4),
     MODE_REBUILD       = (1 <<  5),
@@ -46,30 +228,17 @@ static struct poptOption optionsTable[] = {
    POPT_TABLEEND
 };
 
-static int checkSpec(rpmts ts, Header h)
+static int checkSpec(rpmts ts, rpmSpec spec)
 {
-    rpmps ps;
     int rc;
+    rpmps ps = rpmSpecCheckDeps(ts, spec);
 
-    if (!headerIsEntry(h, RPMTAG_REQUIRENAME)
-     && !headerIsEntry(h, RPMTAG_CONFLICTNAME))
-       return 0;
-
-    rc = rpmtsAddInstallElement(ts, h, NULL, 0, NULL);
-
-    rc = rpmtsCheck(ts);
-
-    ps = rpmtsProblems(ts);
-    if (rc == 0 && rpmpsNumProblems(ps) > 0) {
+    if (ps) {
        rpmlog(RPMLOG_ERR, _("Failed build dependencies:\n"));
        rpmpsPrint(NULL, ps);
-       rc = 1;
     }
-    ps = rpmpsFree(ps);
-
-    /* XXX nuke the added package. */
-    rpmtsClean(ts);
-
+    rc = (ps != NULL);
+    rpmpsFree(ps);
     return rc;
 }
 
@@ -82,7 +251,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;
@@ -126,7 +295,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 };
@@ -136,12 +305,12 @@ 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;
 
        cmd = rpmExpand("%{uncompress: ", arg, "} | ",
-                       "%{__tar} xOvf - --wildcards ", *try,
+                       "%{__tar} xOvf - --wildcards ", *spec,
                        " 2>&1 > ", tmpSpecFile, NULL);
 
        if (!(fp = popen(cmd, "r"))) {
@@ -196,17 +365,13 @@ exit:
 
 static int buildForTarget(rpmts ts, const char * arg, BTA_t ba)
 {
-    const char * cookie = ba->cookie;
     int buildAmount = ba->buildAmount;
     char * buildRootURL = NULL;
     char * specFile = NULL;
     rpmSpec spec = NULL;
     int rc = 1; /* assume failure */
     int justRm = ((buildAmount & ~(RPMBUILD_RMSOURCE|RPMBUILD_RMSPEC)) == 0);
-
-#ifndef        DYING
-    rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS);
-#endif
+    rpmSpecFlags specFlags = spec_flags;
 
     if (ba->buildRootOverride)
        buildRootURL = rpmGenPath(NULL, ba->buildRootOverride, NULL);
@@ -218,7 +383,7 @@ static int buildForTarget(rpmts ts, const char * arg, BTA_t ba)
        goto exit;
     }
 
-    if (ba->buildMode == 't') {
+    if (buildMode == 't') {
        char *srcdir = NULL, *dir;
 
        specFile = getTarSpec(arg);
@@ -243,7 +408,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;
@@ -275,55 +440,53 @@ static int buildForTarget(rpmts ts, const char * arg, BTA_t ba)
     /* Parse the spec file */
 #define        _anyarch(_f)    \
 (((_f)&(RPMBUILD_PREP|RPMBUILD_BUILD|RPMBUILD_INSTALL|RPMBUILD_PACKAGEBINARY)) == 0)
-    if (parseSpec(ts, specFile, ba->rootdir, buildRootURL, 0, NULL,
-               cookie, _anyarch(buildAmount), ba->force))
-    {
-       goto exit;
-    }
+    if (_anyarch(buildAmount))
+       specFlags |= RPMSPEC_ANYARCH;
 #undef _anyarch
-    if ((spec = rpmtsSetSpec(ts, NULL)) == NULL) {
+    
+    spec = rpmSpecParse(specFile, specFlags, buildRootURL);
+    if (spec == NULL) {
        goto exit;
     }
 
     /* Check build prerequisites if necessary, unless disabled */
-    if (!justRm && !ba->noDeps && checkSpec(ts, spec->sourceHeader)) {
+    if (!justRm && !noDeps && checkSpec(ts, spec)) {
        goto exit;
     }
 
-    if (rpmSpecBuild(ba, spec)) {
+    if (rpmSpecBuild(spec, ba)) {
        goto exit;
     }
     
-    if (ba->buildMode == 't')
+    if (buildMode == 't')
        (void) unlink(specFile);
     rc = 0;
 
 exit:
     free(specFile);
-    freeSpec(spec);
+    rpmSpecFree(spec);
     free(buildRootURL);
     return rc;
 }
 
 static int build(rpmts ts, const char * arg, BTA_t ba, const char * rcfile)
 {
-    char *t, *te;
     int rc = 0;
-    char * targets = ba->targets;
+    char * targets = argvJoin(build_targets, ",");
 #define        buildCleanMask  (RPMBUILD_RMSOURCE|RPMBUILD_RMSPEC)
     int cleanFlags = ba->buildAmount & buildCleanMask;
     rpmVSFlags vsflags, ovsflags;
 
     vsflags = rpmExpandNumeric("%{_vsflags_build}");
-    if (ba->qva_flags & VERIFY_DIGEST)
+    if (rpmcliQueryFlags & VERIFY_DIGEST)
        vsflags |= _RPMVSF_NODIGESTS;
-    if (ba->qva_flags & VERIFY_SIGNATURE)
+    if (rpmcliQueryFlags & VERIFY_SIGNATURE)
        vsflags |= _RPMVSF_NOSIGNATURES;
-    if (ba->qva_flags & VERIFY_HDRCHK)
+    if (rpmcliQueryFlags & VERIFY_HDRCHK)
        vsflags |= RPMVSF_NOHDRCHK;
     ovsflags = rpmtsSetVSFlags(ts, vsflags);
 
-    if (targets == NULL) {
+    if (build_targets == NULL) {
        rc =  buildForTarget(ts, arg, ba);
        goto exit;
     }
@@ -333,36 +496,29 @@ static int build(rpmts ts, const char * arg, BTA_t ba, const char * rcfile)
     printf(_("Building target platforms: %s\n"), targets);
 
     ba->buildAmount &= ~buildCleanMask;
-    for (t = targets; *t != '\0'; t = te) {
-       char *target;
-       if ((te = strchr(t, ',')) == NULL)
-           te = t + strlen(t);
-       target = xmalloc(te-t+1);
-       strncpy(target, t, (te-t));
-       target[te-t] = '\0';
-       if (*te != '\0')
-           te++;
-       else    /* XXX Perform clean-up after last target build. */
+    for (ARGV_const_t target = build_targets; target && *target; target++) {
+       /* Perform clean-up after last target build. */
+       if (*(target + 1) == NULL)
            ba->buildAmount |= cleanFlags;
 
-       printf(_("Building for target %s\n"), target);
+       printf(_("Building for target %s\n"), *target);
 
        /* Read in configuration for target. */
        rpmFreeMacros(NULL);
        rpmFreeRpmrc();
-       (void) rpmReadConfigFiles(rcfile, target);
-       free(target);
+       (void) rpmReadConfigFiles(rcfile, *target);
        rc = buildForTarget(ts, arg, ba);
        if (rc)
            break;
     }
 
 exit:
-    vsflags = rpmtsSetVSFlags(ts, ovsflags);
+    rpmtsSetVSFlags(ts, ovsflags);
     /* Restore original configuration. */
     rpmFreeMacros(NULL);
     rpmFreeRpmrc();
     (void) rpmReadConfigFiles(rcfile, NULL);
+    free(targets);
 
     return rc;
 }
@@ -382,7 +538,7 @@ int main(int argc, char *argv[])
        exit(EXIT_FAILURE);
     }
 
-    switch (ba->buildMode) {
+    switch (buildMode) {
     case 'b':  bigMode = MODE_BUILD;           break;
     case 't':  bigMode = MODE_TARBUILD;        break;
     case 'B':  bigMode = MODE_REBUILD;         break;
@@ -413,6 +569,7 @@ int main(int argc, char *argv[])
            ba->buildAmount |= RPMBUILD_CLEAN;
            ba->buildAmount |= RPMBUILD_RMBUILD;
        }
+       ba->buildAmount &= ~(nobuildAmount);
 
        while ((pkg = poptGetArg(optCon))) {
            char * specFile = NULL;
@@ -432,22 +589,22 @@ int main(int argc, char *argv[])
        break;
     case MODE_BUILD:
     case MODE_TARBUILD:
-       switch (ba->buildChar) {
+       switch (buildChar) {
        case 'a':
            ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
        case 'b':
            ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
            ba->buildAmount |= RPMBUILD_CLEAN;
-           if ((ba->buildChar == 'b') && ba->shortCircuit)
+           if ((buildChar == 'b') && shortCircuit)
                break;
        case 'i':
            ba->buildAmount |= RPMBUILD_INSTALL;
            ba->buildAmount |= RPMBUILD_CHECK;
-           if ((ba->buildChar == 'i') && ba->shortCircuit)
+           if ((buildChar == 'i') && shortCircuit)
                break;
        case 'c':
            ba->buildAmount |= RPMBUILD_BUILD;
-           if ((ba->buildChar == 'c') && ba->shortCircuit)
+           if ((buildChar == 'c') && shortCircuit)
                break;
        case 'p':
            ba->buildAmount |= RPMBUILD_PREP;
@@ -460,6 +617,7 @@ int main(int argc, char *argv[])
            ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
            break;
        }
+       ba->buildAmount &= ~(nobuildAmount);
 
        while ((pkg = poptGetArg(optCon))) {
            ba->rootdir = rpmcliRootDir;
@@ -473,11 +631,11 @@ int main(int argc, char *argv[])
        break;
     }
 
-    ts = rpmtsFree(ts);
-    finishPipe();
-    freeNames();
-    ba->buildRootOverride = _free(ba->buildRootOverride);
-    ba->targets = _free(ba->targets);
+    rpmtsFree(ts);
+    if (finishPipe())
+       ec = EXIT_FAILURE;
+    free(ba->buildRootOverride);
+    argvFree(build_targets);
 
     rpmcliFini(optCon);