# build/build.c

Go to the documentation of this file.

    00001
    00006 #include "system.h"
    00007
    00008 #include <rpmio_internal.h>
    00009 #include <rpmbuild.h>
    00010
    00011 #include "debug.h"
    00012
    00013 /*@unchecked@*/
    00014 static int _build_debug = 0;
    00015
    00016 /*@access StringBuf @*/
    00017 /*@access urlinfo @*/           /* XXX compared with NULL */
    00018 /*@access FD_t @*/
    00019
    00022 static void doRmSource(Spec spec)
    00023         /*@globals rpmGlobalMacroContext,
    00024                 fileSystem@*/
    00025         /*@modifies rpmGlobalMacroContext, fileSystem @*/
    00026 {
    00027     struct Source *p;
    00028     Package pkg;
    00029     int rc;
    00030
    00031 #if 0
    00032     rc = Unlink(spec->specFile);
    00033 #endif
    00034
    00035     for (p = spec->sources; p != NULL; p = p->next) {
    00036         if (! (p->flags & RPMBUILD_ISNO)) {
    00037             const char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
    00038             rc = Unlink(fn);
    00039             fn = _free(fn);
    00040         }
    00041     }
    00042
    00043     for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
    00044         for (p = pkg->icon; p != NULL; p = p->next) {
    00045             if (! (p->flags & RPMBUILD_ISNO)) {
    00046                 const char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
    00047                 rc = Unlink(fn);
    00048                 fn = _free(fn);
    00049             }
    00050         }
    00051     }
    00052 }
    00053
    00054 /*
    00055  * @todo Single use by %%doc in files.c prevents static.
    00056  */
    00057 int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
    00058 {
    00059     const char * rootURL = spec->rootURL;
    00060     const char * rootDir;
    00061     const char *scriptName = NULL;
    00062     const char * buildDirURL = rpmGenPath(rootURL, "%{_builddir}", "");
    00063     const char * buildScript;
    00064     const char * buildCmd = NULL;
    00065     const char * buildTemplate = NULL;
    00066     const char * buildPost = NULL;
    00067     const char * mTemplate = NULL;
    00068     const char * mPost = NULL;
    00069     int argc = 0;
    00070     const char **argv = NULL;
    00071     FILE * fp = NULL;
    00072     urlinfo u = NULL;
    00073
    00074     FD_t fd;
    00075     FD_t xfd;
    00076     int child;
    00077     int status;
    00078     int rc;
    00079
    00080     /*@-branchstate@*/
    00081     switch (what) {
    00082     case RPMBUILD_PREP:
    00083         name = "%prep";
    00084         sb = spec->prep;
    00085         mTemplate = "%{__spec_prep_template}";
    00086         mPost = "%{__spec_prep_post}";
    00087         break;
    00088     case RPMBUILD_BUILD:
    00089         name = "%build";
    00090         sb = spec->build;
    00091         mTemplate = "%{__spec_build_template}";
    00092         mPost = "%{__spec_build_post}";
    00093         break;
    00094     case RPMBUILD_INSTALL:
    00095         name = "%install";
    00096         sb = spec->install;
    00097         mTemplate = "%{__spec_install_template}";
    00098         mPost = "%{__spec_install_post}";
    00099         break;
    00100     case RPMBUILD_CLEAN:
    00101         name = "%clean";
    00102         sb = spec->clean;
    00103         mTemplate = "%{__spec_clean_template}";
    00104         mPost = "%{__spec_clean_post}";
    00105         break;
    00106     case RPMBUILD_RMBUILD:
    00107         name = "--clean";
    00108         mTemplate = "%{__spec_clean_template}";
    00109         mPost = "%{__spec_clean_post}";
    00110         break;
    00111     case RPMBUILD_STRINGBUF:
    00112     default:
    00113         mTemplate = "%{___build_template}";
    00114         mPost = "%{___build_post}";
    00115         break;
    00116     }
    00117     /*@=branchstate@*/
    00118
    00119     if ((what != RPMBUILD_RMBUILD) && sb == NULL) {
    00120         rc = 0;
    00121         goto exit;
    00122     }
    00123
    00124     if (makeTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
    00125         rpmError(RPMERR_SCRIPT, _("Unable to open temp file.\n"));
    00126         rc = RPMERR_SCRIPT;
    00127         goto exit;
    00128     }
    00129
    00130 #ifdef HAVE_FCHMOD
    00131     switch (rootut) {
    00132     case URL_IS_PATH:
    00133     case URL_IS_UNKNOWN:
    00134         (void)fchmod(Fileno(fd), 0600);
    00135         break;
    00136     default:
    00137         break;
    00138     }
    00139 #endif
    00140
    00141     /*@-branchstate@*/
    00142     if (fdGetFp(fd) == NULL)
    00143         xfd = Fdopen(fd, "w.fpio");
    00144     else
    00145         xfd = fd;
    00146     /*@=branchstate@*/
    00147
    00148     /*@-type@*/ /* FIX: cast? */
    00149     if ((fp = fdGetFp(xfd)) == NULL) {
    00150         rc = RPMERR_SCRIPT;
    00151         goto exit;
    00152     }
    00153     /*@=type@*/
    00154
    00155     (void) urlPath(rootURL, &rootDir);
    00156     /*@-branchstate@*/
    00157     if (*rootDir == '\0') rootDir = "/";
    00158     /*@=branchstate@*/
    00159
    00160     (void) urlPath(scriptName, &buildScript);
    00161
    00162     buildTemplate = rpmExpand(mTemplate, NULL);
    00163     buildPost = rpmExpand(mPost, NULL);
    00164
    00165     (void) fputs(buildTemplate, fp);
    00166
    00167     if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir)
    00168         fprintf(fp, "cd %s\n", spec->buildSubdir);
    00169
    00170     if (what == RPMBUILD_RMBUILD) {
    00171         if (spec->buildSubdir)
    00172             fprintf(fp, "rm -rf %s\n", spec->buildSubdir);
    00173     } else
    00174         fprintf(fp, "%s", getStringBuf(sb));
    00175
    00176     (void) fputs(buildPost, fp);
    00177
    00178     (void) Fclose(xfd);
    00179
    00180     if (test) {
    00181         rc = 0;
    00182         goto exit;
    00183     }
    00184
    00185 if (_build_debug)
    00186 fprintf(stderr, "*** rootURL %s buildDirURL %s\n", rootURL, buildDirURL);
    00187     if (buildDirURL && buildDirURL[0] != '/' &&
    00188         (urlSplit(buildDirURL, &u) != 0)) {
    00189         rc = RPMERR_SCRIPT;
    00190         goto exit;
    00191     }
    00192     if (u != NULL) {
    00193         switch (u->urltype) {
    00194         case URL_IS_FTP:
    00195 if (_build_debug)
    00196 fprintf(stderr, "*** addMacros\n");
    00197             addMacro(spec->macros, "_remsh", NULL, "%{__remsh}", RMIL_SPEC);
    00198             addMacro(spec->macros, "_remhost", NULL, u->host, RMIL_SPEC);
    00199             if (strcmp(rootDir, "/"))
    00200                 addMacro(spec->macros, "_remroot", NULL, rootDir, RMIL_SPEC);
    00201             break;
    00202         case URL_IS_HTTP:
    00203         default:
    00204             break;
    00205         }
    00206     }
    00207
    00208     buildCmd = rpmExpand("%{___build_cmd}", " ", buildScript, NULL);
    00209     (void) poptParseArgvString(buildCmd, &argc, &argv);
    00210
    00211     rpmMessage(RPMMESS_NORMAL, _("Executing(%s): %s\n"), name, buildCmd);
    00212     if (!(child = fork())) {
    00213
    00214         /*@-mods@*/
    00215         errno = 0;
    00216         /*@=mods@*/
    00217         (void) execvp(argv[0], (char *const *)argv);
    00218
    00219         rpmError(RPMERR_SCRIPT, _("Exec of %s failed (%s): %s\n"),
    00220                 scriptName, name, strerror(errno));
    00221
    00222         _exit(-1);
    00223     }
    00224
    00225     rc = waitpid(child, &status, 0);
    00226
    00227     if (!WIFEXITED(status) || WEXITSTATUS(status)) {
    00228         rpmError(RPMERR_SCRIPT, _("Bad exit status from %s (%s)\n"),
    00229                  scriptName, name);
    00230         rc = RPMERR_SCRIPT;
    00231     } else
    00232         rc = 0;
    00233
    00234 exit:
    00235     if (scriptName) {
    00236         if (!rc)
    00237             (void) Unlink(scriptName);
    00238         scriptName = _free(scriptName);
    00239     }
    00240     if (u != NULL) {
    00241         switch (u->urltype) {
    00242         case URL_IS_FTP:
    00243         case URL_IS_HTTP:
    00244 if (_build_debug)
    00245 fprintf(stderr, "*** delMacros\n");
    00246             delMacro(spec->macros, "_remsh");
    00247             delMacro(spec->macros, "_remhost");
    00248             if (strcmp(rootDir, "/"))
    00249                 delMacro(spec->macros, "_remroot");
    00250             break;
    00251         default:
    00252             break;
    00253         }
    00254     }
    00255     argv = _free(argv);
    00256     buildCmd = _free(buildCmd);
    00257     buildTemplate = _free(buildTemplate);
    00258     buildPost = _free(buildPost);
    00259     buildDirURL = _free(buildDirURL);
    00260
    00261     return rc;
    00262 }
    00263
    00264 int buildSpec(Spec spec, int what, int test)
    00265 {
    00266     int rc = 0;
    00267
    00268     if (!spec->recursing && spec->BACount) {
    00269         int x;
    00270         /* When iterating over BANames, do the source    */
    00271         /* packaging on the first run, and skip RMSOURCE altogether */
    00272         if (spec->BASpecs != NULL)
    00273         for (x = 0; x < spec->BACount; x++) {
    00274             if ((rc = buildSpec(spec->BASpecs[x],
    00275                                 (what & ~RPMBUILD_RMSOURCE) |
    00276                                 (x ? 0 : (what & RPMBUILD_PACKAGESOURCE)),
    00277                                 test))) {
    00278                 goto exit;
    00279             }
    00280         }
    00281     } else {
    00282         if ((what & RPMBUILD_PREP) &&
    00283             (rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test)))
    00284                 goto exit;
    00285
    00286         if ((what & RPMBUILD_BUILD) &&
    00287             (rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test)))
    00288                 goto exit;
    00289
    00290         if ((what & RPMBUILD_INSTALL) &&
    00291             (rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test)))
    00292                 goto exit;
    00293
    00294         if ((what & RPMBUILD_PACKAGESOURCE) &&
    00295             (rc = processSourceFiles(spec)))
    00296                 goto exit;
    00297
    00298         if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
    00299             (what & RPMBUILD_FILECHECK)) &&
    00300             (rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL, test)))
    00301                 goto exit;
    00302
    00303         if (((what & RPMBUILD_PACKAGESOURCE) && !test) &&
    00304             (rc = packageSources(spec)))
    00305                 return rc;
    00306
    00307         if (((what & RPMBUILD_PACKAGEBINARY) && !test) &&
    00308             (rc = packageBinaries(spec)))
    00309                 goto exit;
    00310
    00311         if ((what & RPMBUILD_CLEAN) &&
    00312             (rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test)))
    00313                 goto exit;
    00314
    00315         if ((what & RPMBUILD_RMBUILD) &&
    00316             (rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test)))
    00317                 goto exit;
    00318     }
    00319
    00320     if (what & RPMBUILD_RMSOURCE)
    00321         doRmSource(spec);
    00322
    00323     if (what & RPMBUILD_RMSPEC)
    00324         (void) Unlink(spec->specFile);
    00325
    00326 exit:
    00327     if (rc && rpmlogGetNrecs() > 0) {
    00328         rpmMessage(RPMMESS_NORMAL, _("\n\nRPM build errors:\n"));
    00329         rpmlogPrint(NULL);
    00330     }
    00331
    00332     return rc;
    00333 }