Main Page Modules Data Structures File List Data Fields Globals Related Pages

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