3 * Top-level build dispatcher.
8 #include <rpmio_internal.h>
13 static int _build_debug = 0;
15 /*@access StringBuf @*/
16 /*@access urlinfo @*/ /* XXX compared with NULL */
21 static void doRmSource(Spec spec)
22 /*@modifies fileSystem @*/
28 Unlink(spec->specFile);
31 for (p = spec->sources; p != NULL; p = p->next) {
32 if (! (p->flags & RPMBUILD_ISNO)) {
33 const char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
39 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
40 for (p = pkg->icon; p != NULL; p = p->next) {
41 if (! (p->flags & RPMBUILD_ISNO)) {
42 const char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
51 * @todo Single use by %%doc in files.c prevents static.
53 int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
55 const char * rootURL = spec->rootURL;
57 const char *scriptName = NULL;
58 const char * buildDirURL = rpmGenPath(rootURL, "%{_builddir}", "");
59 const char * buildScript;
60 const char * buildCmd = NULL;
61 const char * buildTemplate = NULL;
62 const char * buildPost = NULL;
63 const char * mTemplate = NULL;
64 const char * mPost = NULL;
66 const char **argv = NULL;
80 mTemplate = "%{__spec_prep_template}";
81 mPost = "%{__spec_prep_post}";
86 mTemplate = "%{__spec_build_template}";
87 mPost = "%{__spec_build_post}";
89 case RPMBUILD_INSTALL:
92 mTemplate = "%{__spec_install_template}";
93 mPost = "%{__spec_install_post}";
98 mTemplate = "%{__spec_clean_template}";
99 mPost = "%{__spec_clean_post}";
101 case RPMBUILD_RMBUILD:
103 mTemplate = "%{__spec_clean_template}";
104 mPost = "%{__spec_clean_post}";
106 case RPMBUILD_STRINGBUF:
108 mTemplate = "%{___build_template}";
109 mPost = "%{___build_post}";
113 if ((what != RPMBUILD_RMBUILD) && sb == NULL) {
118 if (makeTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
119 rpmError(RPMERR_SCRIPT, _("Unable to open temp file.\n"));
128 (void)fchmod(Fileno(fd), 0600);
135 if (fdGetFp(fd) == NULL)
136 xfd = Fdopen(fd, "w.fpio");
139 if ((fp = fdGetFp(xfd)) == NULL) {
144 (void) urlPath(rootURL, &rootDir);
145 if (*rootDir == '\0') rootDir = "/";
147 (void) urlPath(scriptName, &buildScript);
149 buildTemplate = rpmExpand(mTemplate, NULL);
150 buildPost = rpmExpand(mPost, NULL);
152 (void) fputs(buildTemplate, fp);
154 if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir)
155 fprintf(fp, "cd %s\n", spec->buildSubdir);
157 if (what == RPMBUILD_RMBUILD) {
158 if (spec->buildSubdir)
159 fprintf(fp, "rm -rf %s\n", spec->buildSubdir);
161 fprintf(fp, "%s", getStringBuf(sb));
163 (void) fputs(buildPost, fp);
173 fprintf(stderr, "*** rootURL %s buildDirURL %s\n", rootURL, buildDirURL);
174 if (buildDirURL && buildDirURL[0] != '/' &&
175 (urlSplit(buildDirURL, &u) != 0)) {
180 switch (u->urltype) {
183 fprintf(stderr, "*** addMacros\n");
184 addMacro(spec->macros, "_remsh", NULL, "%{__remsh}", RMIL_SPEC);
185 addMacro(spec->macros, "_remhost", NULL, u->host, RMIL_SPEC);
186 if (strcmp(rootDir, "/"))
187 addMacro(spec->macros, "_remroot", NULL, rootDir, RMIL_SPEC);
195 buildCmd = rpmExpand("%{___build_cmd}", " ", buildScript, NULL);
196 (void) poptParseArgvString(buildCmd, &argc, &argv);
198 rpmMessage(RPMMESS_NORMAL, _("Executing(%s): %s\n"), name, buildCmd);
199 if (!(child = fork())) {
202 (void) execvp(argv[0], (char *const *)argv);
204 rpmError(RPMERR_SCRIPT, _("Exec of %s failed (%s): %s\n"),
205 scriptName, name, strerror(errno));
210 rc = waitpid(child, &status, 0);
212 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
213 rpmError(RPMERR_SCRIPT, _("Bad exit status from %s (%s)\n"),
222 (void) Unlink(scriptName);
223 scriptName = _free(scriptName);
226 switch (u->urltype) {
230 fprintf(stderr, "*** delMacros\n");
231 delMacro(spec->macros, "_remsh");
232 delMacro(spec->macros, "_remhost");
233 if (strcmp(rootDir, "/"))
234 delMacro(spec->macros, "_remroot");
241 buildCmd = _free(buildCmd);
242 buildTemplate = _free(buildTemplate);
243 buildPost = _free(buildPost);
244 buildDirURL = _free(buildDirURL);
249 int buildSpec(Spec spec, int what, int test)
253 if (!spec->inBuildArchitectures && spec->buildArchitectureCount) {
255 /* When iterating over buildArchitectures, do the source */
256 /* packaging on the first run, and skip RMSOURCE altogether */
257 if (spec->buildArchitectureSpecs != NULL)
258 for (x = 0; x < spec->buildArchitectureCount; x++) {
259 if ((rc = buildSpec(spec->buildArchitectureSpecs[x],
260 (what & ~RPMBUILD_RMSOURCE) |
261 (x ? 0 : (what & RPMBUILD_PACKAGESOURCE)),
267 if ((what & RPMBUILD_PREP) &&
268 (rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test)))
271 if ((what & RPMBUILD_BUILD) &&
272 (rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test)))
275 if ((what & RPMBUILD_INSTALL) &&
276 (rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test)))
279 if ((what & RPMBUILD_PACKAGESOURCE) &&
280 (rc = processSourceFiles(spec)))
283 if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
284 (what & RPMBUILD_FILECHECK)) &&
285 (rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL, test)))
288 if (((what & RPMBUILD_PACKAGESOURCE) && !test) &&
289 (rc = packageSources(spec)))
292 if (((what & RPMBUILD_PACKAGEBINARY) && !test) &&
293 (rc = packageBinaries(spec)))
296 if ((what & RPMBUILD_CLEAN) &&
297 (rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test)))
300 if ((what & RPMBUILD_RMBUILD) &&
301 (rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test)))
305 if (what & RPMBUILD_RMSOURCE)
308 if (what & RPMBUILD_RMSPEC)
309 (void) Unlink(spec->specFile);
312 if (rc && rpmlogGetNrecs() > 0) {
313 rpmMessage(RPMMESS_NORMAL, _("\n\nRPM build errors:\n"));