rpm: rpmbuild.c Source File

rpm 4.10.0

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

rpmbuild.c
Go to the documentation of this file.

    00001 #include "system.h"
    00002 const char *__progname;
    00003
    00004 #include <errno.h>
    00005 #include <libgen.h>
    00006 #include <ctype.h>
    00007
    00008 #include <rpm/rpmcli.h>
    00009 #include <rpm/rpmlib.h>                 /* RPMSIGTAG, rpmReadPackageFile .. */
    00010 #include <rpm/rpmbuild.h>
    00011 #include <rpm/rpmlog.h>
    00012 #include <rpm/rpmfileutil.h>
    00013 #include <rpm/rpmdb.h>
    00014 #include <rpm/rpmps.h>
    00015 #include <rpm/rpmts.h>
    00016 #include "lib/signature.h"
    00017 #include "cliutils.h"
    00018
    00019 #include "debug.h"
    00020
    00021 static struct rpmBuildArguments_s rpmBTArgs;
    00022
    00023 #define POPT_NOLANG             -1012
    00024 #define POPT_RMSOURCE           -1013
    00025 #define POPT_RMBUILD            -1014
    00026 #define POPT_BUILDROOT          -1015
    00027 #define POPT_TARGETPLATFORM     -1016
    00028 #define POPT_NOBUILD            -1017
    00029 #define POPT_RMSPEC             -1019
    00030 #define POPT_NODIRTOKENS        -1020
    00031
    00032 #define POPT_REBUILD            0x4220
    00033 #define POPT_RECOMPILE          0x4320
    00034 #define POPT_BA                 0x6261
    00035 #define POPT_BB                 0x6262
    00036 #define POPT_BC                 0x6263
    00037 #define POPT_BI                 0x6269
    00038 #define POPT_BL                 0x626c
    00039 #define POPT_BP                 0x6270
    00040 #define POPT_BS                 0x6273
    00041 #define POPT_TA                 0x7461
    00042 #define POPT_TB                 0x7462
    00043 #define POPT_TC                 0x7463
    00044 #define POPT_TI                 0x7469
    00045 #define POPT_TL                 0x746c
    00046 #define POPT_TP                 0x7470
    00047 #define POPT_TS                 0x7473
    00048
    00049 extern int _fsm_debug;
    00050
    00051 static rpmSpecFlags spec_flags = 0;
    00052 static int noDeps = 0;
    00053 static int shortCircuit = 0;
    00054 static char buildMode = 0;
    00055 static char buildChar = 0;
    00056 static rpmBuildFlags nobuildAmount = 0;
    00057 static ARGV_t build_targets = NULL;
    00059 static void buildArgCallback( poptContext con,
    00060         enum poptCallbackReason reason,
    00061         const struct poptOption * opt, const char * arg,
    00062         const void * data)
    00063 {
    00064     BTA_t rba = &rpmBTArgs;
    00065
    00066     switch (opt->val) {
    00067     case POPT_REBUILD:
    00068     case POPT_RECOMPILE:
    00069     case POPT_BA:
    00070     case POPT_BB:
    00071     case POPT_BC:
    00072     case POPT_BI:
    00073     case POPT_BL:
    00074     case POPT_BP:
    00075     case POPT_BS:
    00076     case POPT_TA:
    00077     case POPT_TB:
    00078     case POPT_TC:
    00079     case POPT_TI:
    00080     case POPT_TL:
    00081     case POPT_TP:
    00082     case POPT_TS:
    00083         if (opt->val == POPT_BS || opt->val == POPT_TS)
    00084             noDeps = 1;
    00085         if (buildMode == '\0' && buildChar == '\0') {
    00086             buildMode = (((unsigned)opt->val) >> 8) & 0xff;
    00087             buildChar = (opt->val     ) & 0xff;
    00088         }
    00089         break;
    00090
    00091     case POPT_NODIRTOKENS: rba->pkgFlags |= RPMBUILD_PKG_NODIRTOKENS; break;
    00092     case POPT_NOBUILD: rba->buildAmount |= RPMBUILD_NOBUILD; break;
    00093     case POPT_NOLANG: spec_flags |= RPMSPEC_NOLANG; break;
    00094     case POPT_RMSOURCE: rba->buildAmount |= RPMBUILD_RMSOURCE; break;
    00095     case POPT_RMSPEC: rba->buildAmount |= RPMBUILD_RMSPEC; break;
    00096     case POPT_RMBUILD: rba->buildAmount |= RPMBUILD_RMBUILD; break;
    00097     case POPT_BUILDROOT:
    00098         if (rba->buildRootOverride) {
    00099             rpmlog(RPMLOG_ERR, _("buildroot already specified, ignoring %s\n"), arg);
    00100             break;
    00101         }
    00102         rba->buildRootOverride = xstrdup(arg);
    00103         break;
    00104     case POPT_TARGETPLATFORM:
    00105         argvSplit(&build_targets, arg, ",");
    00106         break;
    00107
    00108     case RPMCLI_POPT_FORCE:
    00109         spec_flags |= RPMSPEC_FORCE;
    00110         break;
    00111
    00112     }
    00113 }
    00114
    00115 static struct poptOption rpmBuildPoptTable[] = {
    00116  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
    00117         buildArgCallback, 0, NULL, NULL },
    00118
    00119  { "bp", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BP,
    00120         N_("build through %prep (unpack sources and apply patches) from <specfile>"),
    00121         N_("<specfile>") },
    00122  { "bc", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BC,
    00123         N_("build through %build (%prep, then compile) from <specfile>"),
    00124         N_("<specfile>") },
    00125  { "bi", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BI,
    00126         N_("build through %install (%prep, %build, then install) from <specfile>"),
    00127         N_("<specfile>") },
    00128  { "bl", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BL,
    00129         N_("verify %files section from <specfile>"),
    00130         N_("<specfile>") },
    00131  { "ba", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BA,
    00132         N_("build source and binary packages from <specfile>"),
    00133         N_("<specfile>") },
    00134  { "bb", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BB,
    00135         N_("build binary package only from <specfile>"),
    00136         N_("<specfile>") },
    00137  { "bs", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BS,
    00138         N_("build source package only from <specfile>"),
    00139         N_("<specfile>") },
    00140
    00141  { "tp", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TP,
    00142         N_("build through %prep (unpack sources and apply patches) from <tarball>"),
    00143         N_("<tarball>") },
    00144  { "tc", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TC,
    00145         N_("build through %build (%prep, then compile) from <tarball>"),
    00146         N_("<tarball>") },
    00147  { "ti", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TI,
    00148         N_("build through %install (%prep, %build, then install) from <tarball>"),
    00149         N_("<tarball>") },
    00150  { "tl", 0, POPT_ARGFLAG_ONEDASH|POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_TL,
    00151         N_("verify %files section from <tarball>"),
    00152         N_("<tarball>") },
    00153  { "ta", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TA,
    00154         N_("build source and binary packages from <tarball>"),
    00155         N_("<tarball>") },
    00156  { "tb", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TB,
    00157         N_("build binary package only from <tarball>"),
    00158         N_("<tarball>") },
    00159  { "ts", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TS,
    00160         N_("build source package only from <tarball>"),
    00161         N_("<tarball>") },
    00162
    00163  { "rebuild", '\0', 0, 0, POPT_REBUILD,
    00164         N_("build binary package from <source package>"),
    00165         N_("<source package>") },
    00166  { "recompile", '\0', 0, 0, POPT_RECOMPILE,
    00167         N_("build through %install (%prep, %build, then install) from <source package>"),
    00168         N_("<source package>") },
    00169
    00170  { "buildroot", '\0', POPT_ARG_STRING, 0,  POPT_BUILDROOT,
    00171         N_("override build root"), "DIRECTORY" },
    00172  { "clean", '\0', 0, 0, POPT_RMBUILD,
    00173         N_("remove build tree when done"), NULL},
    00174  { "force", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, RPMCLI_POPT_FORCE,
    00175         N_("ignore ExcludeArch: directives from spec file"), NULL},
    00176  { "fsmdebug", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN), &_fsm_debug, -1,
    00177         N_("debug file state machine"), NULL},
    00178  { "nobuild", '\0', 0, 0,  POPT_NOBUILD,
    00179         N_("do not execute any stages of the build"), NULL },
    00180  { "nodeps", '\0', POPT_ARG_VAL, &noDeps, 1,
    00181         N_("do not verify build dependencies"), NULL },
    00182  { "nodirtokens", '\0', 0, 0, POPT_NODIRTOKENS,
    00183         N_("generate package header(s) compatible with (legacy) rpm v3 packaging"),
    00184         NULL},
    00185
    00186  { "noclean", '\0', POPT_BIT_SET, &nobuildAmount, RPMBUILD_CLEAN,
    00187         N_("do not execute %clean stage of the build"), NULL },
    00188  { "nocheck", '\0', POPT_BIT_SET, &nobuildAmount, RPMBUILD_CHECK,
    00189         N_("do not execute %check stage of the build"), NULL },
    00190
    00191  { "nolang", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_NOLANG,
    00192         N_("do not accept i18N msgstr's from specfile"), NULL},
    00193  { "rmsource", '\0', 0, 0, POPT_RMSOURCE,
    00194         N_("remove sources when done"), NULL},
    00195  { "rmspec", '\0', 0, 0, POPT_RMSPEC,
    00196         N_("remove specfile when done"), NULL},
    00197  { "short-circuit", '\0', POPT_ARG_VAL, &shortCircuit,  1,
    00198         N_("skip straight to specified stage (only for c,i)"), NULL },
    00199  { "target", '\0', POPT_ARG_STRING, 0,  POPT_TARGETPLATFORM,
    00200         N_("override target platform"), "CPU-VENDOR-OS" },
    00201    POPT_TABLEEND
    00202 };
    00203
    00204 enum modes {
    00205     MODE_BUILD          = (1 <<  4),
    00206     MODE_REBUILD        = (1 <<  5),
    00207     MODE_RECOMPILE      = (1 <<  8),
    00208     MODE_TARBUILD       = (1 << 11),
    00209 };
    00210
    00211 static int quiet;
    00212
    00213 /* the structure describing the options we take and the defaults */
    00214 static struct poptOption optionsTable[] = {
    00215
    00216  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmBuildPoptTable, 0,
    00217         N_("Build options with [ <specfile> | <tarball> | <source package> ]:"),
    00218         NULL },
    00219
    00220  { "quiet", '\0', POPT_ARGFLAG_DOC_HIDDEN, &quiet, 0, NULL, NULL},
    00221
    00222  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
    00223         N_("Common options for all rpm modes and executables:"),
    00224         NULL },
    00225
    00226    POPT_AUTOALIAS
    00227    POPT_AUTOHELP
    00228    POPT_TABLEEND
    00229 };
    00230
    00231 static int checkSpec(rpmts ts, rpmSpec spec)
    00232 {
    00233     int rc;
    00234     rpmps ps = rpmSpecCheckDeps(ts, spec);
    00235
    00236     if (ps) {
    00237         rpmlog(RPMLOG_ERR, _("Failed build dependencies:\n"));
    00238         rpmpsPrint(NULL, ps);
    00239     }
    00240     rc = (ps != NULL);
    00241     rpmpsFree(ps);
    00242     return rc;
    00243 }
    00244
    00245 static int isSpecFile(const char * specfile)
    00246 {
    00247     char buf[256];
    00248     const char * s;
    00249     FILE * f;
    00250     int count;
    00251     int checking;
    00252
    00253     f = fopen(specfile, "r");
    00254     if (f == NULL) {
    00255         rpmlog(RPMLOG_ERR, _("Unable to open spec file %s: %s\n"),
    00256                 specfile, strerror(errno));
    00257         return 0;
    00258     }
    00259     count = fread(buf, sizeof(buf[0]), sizeof(buf), f);
    00260     (void) fclose(f);
    00261
    00262     if (count == 0)
    00263         return 0;
    00264
    00265     checking = 1;
    00266     for (s = buf; count--; s++) {
    00267         switch (*s) {
    00268         case '\r':
    00269         case '\n':
    00270             checking = 1;
    00271             break;
    00272         case ':':
    00273             checking = 0;
    00274             break;
    00275         default:
    00276 #if 0
    00277             if (checking && !(isprint(*s) || isspace(*s))) return 0;
    00278             break;
    00279 #else
    00280             if (checking && !(isprint(*s) || isspace(*s)) && *(unsigned char *)s < 32) return 0;
    00281             break;
    00282 #endif
    00283         }
    00284     }
    00285     return 1;
    00286 }
    00287
    00288 /*
    00289  * Try to find a spec from a tarball pointed to by arg.
    00290  * Return absolute path to spec name on success, otherwise NULL.
    00291  */
    00292 static char * getTarSpec(const char *arg)
    00293 {
    00294     char *specFile = NULL;
    00295     char *specDir;
    00296     char *specBase;
    00297     char *tmpSpecFile;
    00298     const char **spec;
    00299     char tarbuf[BUFSIZ];
    00300     int gotspec = 0, res;
    00301     static const char *tryspec[] = { "Specfile", "\\*.spec", NULL };
    00302
    00303     specDir = rpmGetPath("%{_specdir}", NULL);
    00304     tmpSpecFile = rpmGetPath("%{_specdir}/", "rpm-spec.XXXXXX", NULL);
    00305
    00306     (void) close(mkstemp(tmpSpecFile));
    00307
    00308     for (spec = tryspec; *spec != NULL; spec++) {
    00309         FILE *fp;
    00310         char *cmd;
    00311
    00312         cmd = rpmExpand("%{uncompress: ", arg, "} | ",
    00313                         "%{__tar} xOvf - --wildcards ", *spec,
    00314                         " 2>&1 > ", tmpSpecFile, NULL);
    00315
    00316         if (!(fp = popen(cmd, "r"))) {
    00317             rpmlog(RPMLOG_ERR, _("Failed to open tar pipe: %m\n"));
    00318         } else {
    00319             char *fok;
    00320             for (;;) {
    00321                 fok = fgets(tarbuf, sizeof(tarbuf) - 1, fp);
    00322                 /* tar sometimes prints "tar: Record size = 16" messages */
    00323                 if (!fok || strncmp(fok, "tar: ", 5) != 0)
    00324                     break;
    00325             }
    00326             pclose(fp);
    00327             gotspec = (fok != NULL) && isSpecFile(tmpSpecFile);
    00328         }
    00329
    00330         if (!gotspec)
    00331             unlink(tmpSpecFile);
    00332         free(cmd);
    00333     }
    00334
    00335     if (!gotspec) {
    00336         rpmlog(RPMLOG_ERR, _("Failed to read spec file from %s\n"), arg);
    00337         goto exit;
    00338     }
    00339
    00340     specBase = basename(tarbuf);
    00341     /* remove trailing \n */
    00342     specBase[strlen(specBase)-1] = '\0';
    00343
    00344     rasprintf(&specFile, "%s/%s", specDir, specBase);
    00345     res = rename(tmpSpecFile, specFile);
    00346
    00347     if (res) {
    00348         rpmlog(RPMLOG_ERR, _("Failed to rename %s to %s: %m\n"),
    00349                 tmpSpecFile, specFile);
    00350         free(specFile);
    00351         specFile = NULL;
    00352     } else {
    00353         /* mkstemp() can give unnecessarily strict permissions, fixup */
    00354         mode_t mask;
    00355         umask(mask = umask(0));
    00356         (void) chmod(specFile, 0666 & ~mask);
    00357     }
    00358
    00359 exit:
    00360     (void) unlink(tmpSpecFile);
    00361     free(tmpSpecFile);
    00362     free(specDir);
    00363     return specFile;
    00364 }
    00365
    00366 static int buildForTarget(rpmts ts, const char * arg, BTA_t ba)
    00367 {
    00368     int buildAmount = ba->buildAmount;
    00369     char * buildRootURL = NULL;
    00370     char * specFile = NULL;
    00371     rpmSpec spec = NULL;
    00372     int rc = 1; /* assume failure */
    00373     int justRm = ((buildAmount & ~(RPMBUILD_RMSOURCE|RPMBUILD_RMSPEC)) == 0);
    00374     rpmSpecFlags specFlags = spec_flags;
    00375
    00376     if (ba->buildRootOverride)
    00377         buildRootURL = rpmGenPath(NULL, ba->buildRootOverride, NULL);
    00378
    00379     /* Create build tree if necessary */
    00380     const char * buildtree = "%{_topdir}:%{_specdir}:%{_sourcedir}:%{_builddir}:%{_rpmdir}:%{_srcrpmdir}:%{_buildrootdir}";
    00381     const char * rootdir = rpmtsRootDir(ts);
    00382     if (rpmMkdirs(!rstreq(rootdir, "/") ? rootdir : NULL , buildtree)) {
    00383         goto exit;
    00384     }
    00385
    00386     if (buildMode == 't') {
    00387         char *srcdir = NULL, *dir;
    00388
    00389         specFile = getTarSpec(arg);
    00390         if (!specFile)
    00391             goto exit;
    00392
    00393         /* Make the directory of the tarball %_sourcedir for this run */
    00394         /* dirname() may modify contents so extra hoops needed. */
    00395         if (*arg != '/') {
    00396             dir = rpmGetCwd();
    00397             rstrscat(&dir, "/", arg, NULL);
    00398         } else {
    00399             dir = xstrdup(arg);
    00400         }
    00401         srcdir = dirname(dir);
    00402         addMacro(NULL, "_sourcedir", NULL, srcdir, RMIL_TARBALL);
    00403         free(dir);
    00404     } else {
    00405         specFile = xstrdup(arg);
    00406     }
    00407
    00408     if (*specFile != '/') {
    00409         char *cwd = rpmGetCwd();
    00410         char *s = NULL;
    00411         rasprintf(&s, "%s/%s", cwd, specFile);
    00412         free(cwd);
    00413         free(specFile);
    00414         specFile = s;
    00415     }
    00416
    00417     struct stat st;
    00418     if (stat(specFile, &st) < 0) {
    00419         rpmlog(RPMLOG_ERR, _("failed to stat %s: %m\n"), specFile);
    00420         goto exit;
    00421     }
    00422     if (! S_ISREG(st.st_mode)) {
    00423         rpmlog(RPMLOG_ERR, _("File %s is not a regular file.\n"), specFile);
    00424         goto exit;
    00425     }
    00426
    00427     /* Try to verify that the file is actually a specfile */
    00428     if (!isSpecFile(specFile)) {
    00429         rpmlog(RPMLOG_ERR,
    00430                 _("File %s does not appear to be a specfile.\n"), specFile);
    00431         goto exit;
    00432     }
    00433
    00434     /* Don't parse spec if only its removal is requested */
    00435     if (ba->buildAmount == RPMBUILD_RMSPEC) {
    00436         rc = unlink(specFile);
    00437         goto exit;
    00438     }
    00439
    00440     /* Parse the spec file */
    00441 #define _anyarch(_f)    \
    00442 (((_f)&(RPMBUILD_PREP|RPMBUILD_BUILD|RPMBUILD_INSTALL|RPMBUILD_PACKAGEBINARY)) == 0)
    00443     if (_anyarch(buildAmount))
    00444         specFlags |= RPMSPEC_ANYARCH;
    00445 #undef  _anyarch
    00446
    00447     spec = rpmSpecParse(specFile, specFlags, buildRootURL);
    00448     if (spec == NULL) {
    00449         goto exit;
    00450     }
    00451
    00452     /* Check build prerequisites if necessary, unless disabled */
    00453     if (!justRm && !noDeps && checkSpec(ts, spec)) {
    00454         goto exit;
    00455     }
    00456
    00457     if (rpmSpecBuild(spec, ba)) {
    00458         goto exit;
    00459     }
    00460
    00461     if (buildMode == 't')
    00462         (void) unlink(specFile);
    00463     rc = 0;
    00464
    00465 exit:
    00466     free(specFile);
    00467     rpmSpecFree(spec);
    00468     free(buildRootURL);
    00469     return rc;
    00470 }
    00471
    00472 static int build(rpmts ts, const char * arg, BTA_t ba, const char * rcfile)
    00473 {
    00474     int rc = 0;
    00475     char * targets = argvJoin(build_targets, ",");
    00476 #define buildCleanMask  (RPMBUILD_RMSOURCE|RPMBUILD_RMSPEC)
    00477     int cleanFlags = ba->buildAmount & buildCleanMask;
    00478     rpmVSFlags vsflags, ovsflags;
    00479
    00480     vsflags = rpmExpandNumeric("%{_vsflags_build}");
    00481     if (rpmcliQueryFlags & VERIFY_DIGEST)
    00482         vsflags |= _RPMVSF_NODIGESTS;
    00483     if (rpmcliQueryFlags & VERIFY_SIGNATURE)
    00484         vsflags |= _RPMVSF_NOSIGNATURES;
    00485     if (rpmcliQueryFlags & VERIFY_HDRCHK)
    00486         vsflags |= RPMVSF_NOHDRCHK;
    00487     ovsflags = rpmtsSetVSFlags(ts, vsflags);
    00488
    00489     if (build_targets == NULL) {
    00490         rc =  buildForTarget(ts, arg, ba);
    00491         goto exit;
    00492     }
    00493
    00494     /* parse up the build operators */
    00495
    00496     printf(_("Building target platforms: %s\n"), targets);
    00497
    00498     ba->buildAmount &= ~buildCleanMask;
    00499     for (ARGV_const_t target = build_targets; target && *target; target++) {
    00500         /* Perform clean-up after last target build. */
    00501         if (*(target + 1) == NULL)
    00502             ba->buildAmount |= cleanFlags;
    00503
    00504         printf(_("Building for target %s\n"), *target);
    00505
    00506         /* Read in configuration for target. */
    00507         rpmFreeMacros(NULL);
    00508         rpmFreeRpmrc();
    00509         (void) rpmReadConfigFiles(rcfile, *target);
    00510         rc = buildForTarget(ts, arg, ba);
    00511         if (rc)
    00512             break;
    00513     }
    00514
    00515 exit:
    00516     rpmtsSetVSFlags(ts, ovsflags);
    00517     /* Restore original configuration. */
    00518     rpmFreeMacros(NULL);
    00519     rpmFreeRpmrc();
    00520     (void) rpmReadConfigFiles(rcfile, NULL);
    00521     free(targets);
    00522
    00523     return rc;
    00524 }
    00525
    00526 int main(int argc, char *argv[])
    00527 {
    00528     rpmts ts = NULL;
    00529     enum modes bigMode = MODE_BUILD;
    00530     BTA_t ba = &rpmBTArgs;
    00531
    00532     const char *pkg = NULL;
    00533     int ec = 0;
    00534     poptContext optCon = rpmcliInit(argc, argv, optionsTable);
    00535
    00536     if (argc <= 1 || poptPeekArg(optCon) == NULL) {
    00537         printUsage(optCon, stderr, 0);
    00538         exit(EXIT_FAILURE);
    00539     }
    00540
    00541     switch (buildMode) {
    00542     case 'b':   bigMode = MODE_BUILD;           break;
    00543     case 't':   bigMode = MODE_TARBUILD;        break;
    00544     case 'B':   bigMode = MODE_REBUILD;         break;
    00545     case 'C':   bigMode = MODE_RECOMPILE;       break;
    00546     }
    00547
    00548     if (rpmcliRootDir && rpmcliRootDir[0] != '/') {
    00549         argerror(_("arguments to --root (-r) must begin with a /"));
    00550     }
    00551
    00552     /* rpmbuild is rather chatty by default */
    00553     rpmSetVerbosity(quiet ? RPMLOG_WARNING : RPMLOG_INFO);
    00554
    00555     if (rpmcliPipeOutput && initPipe())
    00556         exit(EXIT_FAILURE);
    00557
    00558     ts = rpmtsCreate();
    00559     (void) rpmtsSetRootDir(ts, rpmcliRootDir);
    00560     switch (bigMode) {
    00561     case MODE_REBUILD:
    00562     case MODE_RECOMPILE:
    00563         ba->buildAmount =
    00564             RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK;
    00565         if (bigMode == MODE_REBUILD) {
    00566             ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
    00567             ba->buildAmount |= RPMBUILD_RMSOURCE;
    00568             ba->buildAmount |= RPMBUILD_RMSPEC;
    00569             ba->buildAmount |= RPMBUILD_CLEAN;
    00570             ba->buildAmount |= RPMBUILD_RMBUILD;
    00571         }
    00572         ba->buildAmount &= ~(nobuildAmount);
    00573
    00574         while ((pkg = poptGetArg(optCon))) {
    00575             char * specFile = NULL;
    00576
    00577             ba->cookie = NULL;
    00578             ec = rpmInstallSource(ts, pkg, &specFile, &ba->cookie);
    00579             if (ec == 0) {
    00580                 ba->rootdir = rpmcliRootDir;
    00581                 ec = build(ts, specFile, ba, rpmcliRcfile);
    00582             }
    00583             ba->cookie = _free(ba->cookie);
    00584             specFile = _free(specFile);
    00585
    00586             if (ec)
    00587                 break;
    00588         }
    00589         break;
    00590     case MODE_BUILD:
    00591     case MODE_TARBUILD:
    00592         switch (buildChar) {
    00593         case 'a':
    00594             ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
    00595         case 'b':
    00596             ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
    00597             ba->buildAmount |= RPMBUILD_CLEAN;
    00598             if ((buildChar == 'b') && shortCircuit)
    00599                 break;
    00600         case 'i':
    00601             ba->buildAmount |= RPMBUILD_INSTALL;
    00602             ba->buildAmount |= RPMBUILD_CHECK;
    00603             if ((buildChar == 'i') && shortCircuit)
    00604                 break;
    00605         case 'c':
    00606             ba->buildAmount |= RPMBUILD_BUILD;
    00607             if ((buildChar == 'c') && shortCircuit)
    00608                 break;
    00609         case 'p':
    00610             ba->buildAmount |= RPMBUILD_PREP;
    00611             break;
    00612
    00613         case 'l':
    00614             ba->buildAmount |= RPMBUILD_FILECHECK;
    00615             break;
    00616         case 's':
    00617             ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
    00618             break;
    00619         }
    00620         ba->buildAmount &= ~(nobuildAmount);
    00621
    00622         while ((pkg = poptGetArg(optCon))) {
    00623             ba->rootdir = rpmcliRootDir;
    00624             ba->cookie = NULL;
    00625             ec = build(ts, pkg, ba, rpmcliRcfile);
    00626             if (ec)
    00627                 break;
    00628             rpmFreeMacros(NULL);
    00629             (void) rpmReadConfigFiles(rpmcliRcfile, NULL);
    00630         }
    00631         break;
    00632     }
    00633
    00634     rpmtsFree(ts);
    00635     if (finishPipe())
    00636         ec = EXIT_FAILURE;
    00637     free(ba->buildRootOverride);
    00638     argvFree(build_targets);
    00639
    00640     rpmcliFini(optCon);
    00641
    00642     return RETVAL(ec);
    00643 }