3 * Top-level build dispatcher.
11 #include <rpm/rpmlog.h>
12 #include <rpm/rpmfileutil.h>
13 #include "build/rpmbuild_internal.h"
14 #include "build/rpmbuild_misc.h"
15 #include "lib/rpmug.h"
21 static rpmRC doRmSource(rpmSpec spec)
27 for (p = spec->sources; p != NULL; p = p->next) {
28 if (! (p->flags & RPMBUILD_ISNO)) {
29 char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
36 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
37 for (p = pkg->icon; p != NULL; p = p->next) {
38 if (! (p->flags & RPMBUILD_ISNO)) {
39 char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
47 return !rc ? RPMRC_OK : RPMRC_FAIL;
51 * @todo Single use by %%doc in files.c prevents static.
53 rpmRC doScript(rpmSpec spec, rpmBuildFlags what, const char *name,
54 const char *sb, int test)
56 char *scriptName = NULL;
57 char * buildDir = rpmGenPath(spec->rootDir, "%{_builddir}", "");
58 char * buildCmd = NULL;
59 char * buildTemplate = NULL;
60 char * buildPost = NULL;
61 const char * mTemplate = NULL;
62 const char * mCmd = NULL;
63 const char * mPost = NULL;
65 const char **argv = NULL;
76 mTemplate = "%{__spec_prep_template}";
77 mPost = "%{__spec_prep_post}";
78 mCmd = "%{__spec_prep_cmd}";
81 mTemplate = "%{__spec_build_template}";
82 mPost = "%{__spec_build_post}";
83 mCmd = "%{__spec_build_cmd}";
85 case RPMBUILD_INSTALL:
86 mTemplate = "%{__spec_install_template}";
87 mPost = "%{__spec_install_post}";
88 mCmd = "%{__spec_install_cmd}";
91 mTemplate = "%{__spec_check_template}";
92 mPost = "%{__spec_check_post}";
93 mCmd = "%{__spec_check_cmd}";
96 mTemplate = "%{__spec_clean_template}";
97 mPost = "%{__spec_clean_post}";
98 mCmd = "%{__spec_clean_cmd}";
100 case RPMBUILD_RMBUILD:
101 mTemplate = "%{__spec_clean_template}";
102 mPost = "%{__spec_clean_post}";
103 mCmd = "%{__spec_clean_cmd}";
105 case RPMBUILD_STRINGBUF:
107 mTemplate = "%{___build_template}";
108 mPost = "%{___build_post}";
109 mCmd = "%{___build_cmd}";
113 if ((what != RPMBUILD_RMBUILD) && sb == NULL) {
118 fd = rpmMkTempFile(spec->rootDir, &scriptName);
120 rpmlog(RPMLOG_ERR, _("Unable to open temp file: %s\n"), Fstrerror(fd));
125 if ((fp = fdopen(Fileno(fd), "w")) == NULL) {
126 rpmlog(RPMLOG_ERR, _("Unable to open stream: %s\n"), strerror(errno));
131 buildTemplate = rpmExpand(mTemplate, NULL);
132 buildPost = rpmExpand(mPost, NULL);
134 (void) fputs(buildTemplate, fp);
136 if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir)
137 fprintf(fp, "cd '%s'\n", spec->buildSubdir);
139 if (what == RPMBUILD_RMBUILD) {
140 if (spec->buildSubdir)
141 fprintf(fp, "rm -rf '%s'\n", spec->buildSubdir);
142 } else if (sb != NULL)
143 fprintf(fp, "%s", sb);
145 (void) fputs(buildPost, fp);
153 if (buildDir && buildDir[0] != '/') {
158 buildCmd = rpmExpand(mCmd, " ", scriptName, NULL);
159 (void) poptParseArgvString(buildCmd, &argc, &argv);
161 rpmlog(RPMLOG_NOTICE, _("Executing(%s): %s\n"), name, buildCmd);
162 if (!(child = fork())) {
163 /* NSPR messes with SIGPIPE, reset to default for the kids */
164 signal(SIGPIPE, SIG_DFL);
166 (void) execvp(argv[0], (char *const *)argv);
168 rpmlog(RPMLOG_ERR, _("Exec of %s failed (%s): %s\n"),
169 scriptName, name, strerror(errno));
171 _exit(127); /* exit 127 for compatibility with bash(1) */
174 pid = waitpid(child, &status, 0);
177 rpmlog(RPMLOG_ERR, _("Error executing scriptlet %s (%s)\n"),
183 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
184 rpmlog(RPMLOG_ERR, _("Bad exit status from %s (%s)\n"),
194 (void) unlink(scriptName);
206 static rpmRC buildSpec(BTA_t buildArgs, rpmSpec spec, int what)
209 int test = (what & RPMBUILD_NOBUILD);
210 char *cookie = buildArgs->cookie ? xstrdup(buildArgs->cookie) : NULL;
212 /* XXX TODO: rootDir is only relevant during build, eliminate from spec */
213 spec->rootDir = buildArgs->rootdir;
214 if (!spec->recursing && spec->BACount) {
216 /* When iterating over BANames, do the source */
217 /* packaging on the first run, and skip RMSOURCE altogether */
218 if (spec->BASpecs != NULL)
219 for (x = 0; x < spec->BACount; x++) {
220 if ((rc = buildSpec(buildArgs, spec->BASpecs[x],
221 (what & ~RPMBUILD_RMSOURCE) |
222 (x ? 0 : (what & RPMBUILD_PACKAGESOURCE))))) {
227 int didBuild = (what & (RPMBUILD_PREP|RPMBUILD_BUILD|RPMBUILD_INSTALL));
229 if ((what & RPMBUILD_PREP) &&
230 (rc = doScript(spec, RPMBUILD_PREP, "%prep",
231 getStringBuf(spec->prep), test)))
234 if ((what & RPMBUILD_BUILD) &&
235 (rc = doScript(spec, RPMBUILD_BUILD, "%build",
236 getStringBuf(spec->build), test)))
239 if ((what & RPMBUILD_INSTALL) &&
240 (rc = doScript(spec, RPMBUILD_INSTALL, "%install",
241 getStringBuf(spec->install), test)))
244 if ((what & RPMBUILD_CHECK) &&
245 (rc = doScript(spec, RPMBUILD_CHECK, "%check",
246 getStringBuf(spec->check), test)))
249 if ((what & RPMBUILD_PACKAGESOURCE) &&
250 (rc = processSourceFiles(spec, buildArgs->pkgFlags)))
253 if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
254 (what & RPMBUILD_FILECHECK)) &&
255 (rc = processBinaryFiles(spec, buildArgs->pkgFlags,
256 what & RPMBUILD_INSTALL, test)))
259 if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY)) &&
260 (rc = processBinaryPolicies(spec, test)))
263 if (((what & RPMBUILD_PACKAGESOURCE) && !test) &&
264 (rc = packageSources(spec, &cookie)))
267 if (((what & RPMBUILD_PACKAGEBINARY) && !test) &&
268 (rc = packageBinaries(spec, cookie, (didBuild == 0))))
271 if ((what & RPMBUILD_CLEAN) &&
272 (rc = doScript(spec, RPMBUILD_CLEAN, "%clean",
273 getStringBuf(spec->clean), test)))
276 if ((what & RPMBUILD_RMBUILD) &&
277 (rc = doScript(spec, RPMBUILD_RMBUILD, "--clean", NULL, test)))
281 if (what & RPMBUILD_RMSOURCE)
284 if (what & RPMBUILD_RMSPEC)
285 (void) unlink(spec->specFile);
289 spec->rootDir = NULL;
290 if (rc != RPMRC_OK && rpmlogGetNrecs() > 0) {
291 rpmlog(RPMLOG_NOTICE, _("\n\nRPM build errors:\n"));
299 rpmRC rpmSpecBuild(rpmSpec spec, BTA_t buildArgs)
301 /* buildSpec() can recurse with different buildAmount, pass it separately */
302 return buildSpec(buildArgs, spec, buildArgs->buildAmount);