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