don't erase failing build script (Tim Mooney).
[platform/upstream/rpm.git] / build / build.c
1 #include "system.h"
2
3 #include "rpmbuild.h"
4
5 #ifdef  DYING
6 static void doRmSource(Spec spec);
7 #endif
8
9 static void doRmSource(Spec spec)
10 {
11     struct Source *p;
12     Package pkg;
13     
14     unlink(spec->specFile);
15
16     for (p = spec->sources; p != NULL; p = p->next) {
17         if (! (p->flags & RPMBUILD_ISNO)) {
18             const char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
19             unlink(fn);
20             xfree(fn);
21         }
22     }
23
24     for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
25         for (p = pkg->icon; p != NULL; p = p->next) {
26             if (! (p->flags & RPMBUILD_ISNO)) {
27                 const char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
28                 unlink(fn);
29                 xfree(fn);
30             }
31         }
32     }
33 }
34
35 /*
36  * The _preScript string is expanded to export values to a script environment.
37  */
38
39 static char *_preScriptEnvironment = "%{_preScriptEnvironment}";
40
41 static char *_preScriptChdir = 
42         "umask 022\n"
43         "cd %{_builddir}\n"
44 ;
45
46 int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
47 {
48     FD_t fd;
49     FILE *f;
50     const char *scriptName;
51     int pid;
52     int status;
53     char *buildShell;
54     char buf[BUFSIZ];
55     
56     switch (what) {
57       case RPMBUILD_PREP:
58         name = "%prep";
59         sb = spec->prep;
60         break;
61       case RPMBUILD_BUILD:
62         name = "%build";
63         sb = spec->build;
64         break;
65       case RPMBUILD_INSTALL:
66         name = "%install";
67         sb = spec->install;
68         break;
69       case RPMBUILD_CLEAN:
70         name = "%clean";
71         sb = spec->clean;
72         break;
73       case RPMBUILD_RMBUILD:
74         name = "--clean";
75         break;
76       case RPMBUILD_STRINGBUF:
77         break;
78     }
79     if ((what != RPMBUILD_RMBUILD) && sb == NULL) {
80         return 0;
81     }
82     
83     if (makeTempFile(NULL, &scriptName, &fd)) {
84             fdClose(fd);
85             FREE(scriptName);
86             rpmError(RPMERR_SCRIPT, _("Unable to open temp file"));
87             return RPMERR_SCRIPT;
88     }
89     (void)fchmod(fdFileno(fd), 0600);
90     f = fdFdopen(fd, "w");
91     
92     strcpy(buf, _preScriptEnvironment);
93     expandMacros(spec, spec->macros, buf, sizeof(buf));
94     strcat(buf, "\n");
95     fputs(buf, f);
96
97     fprintf(f, rpmIsVerbose() ? "set -x\n\n" : "exec > /dev/null\n\n");
98
99 /* XXX umask 022; cd %{_builddir} */
100     strcpy(buf, _preScriptChdir);
101     expandMacros(spec, spec->macros, buf, sizeof(buf));
102     fputs(buf, f);
103
104     if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD) {
105         if (spec->buildSubdir) {
106             fprintf(f, "cd %s\n", spec->buildSubdir);
107         }
108     }
109     if (what == RPMBUILD_RMBUILD) {
110         if (spec->buildSubdir) {
111             fprintf(f, "rm -rf %s\n", spec->buildSubdir);
112         }
113     } else {
114         fprintf(f, "%s", getStringBuf(sb));
115     }
116     fprintf(f, "\nexit 0\n");
117     
118     fclose(f);
119
120     if (test) {
121         FREE(scriptName);
122         return 0;
123     }
124     
125     rpmMessage(RPMMESS_NORMAL, _("Executing: %s\n"), name);
126     if (!(pid = fork())) {
127         buildShell = rpmGetVar(RPMVAR_BUILDSHELL);
128         execl(buildShell, buildShell, "-e", scriptName, scriptName, NULL);
129         rpmError(RPMERR_SCRIPT, _("Exec of %s failed (%s)"),
130                  scriptName, name);
131 #if 0   /* XXX don't erase the failing script */
132         unlink(scriptName);
133 #endif
134         FREE(scriptName);
135         return RPMERR_SCRIPT;
136     }
137     (void)wait(&status);
138     if (! WIFEXITED(status) || WEXITSTATUS(status)) {
139         rpmError(RPMERR_SCRIPT, _("Bad exit status from %s (%s)"),
140                  scriptName, name);
141 #if HACK
142         unlink(scriptName);
143 #endif
144         FREE(scriptName);
145         return RPMERR_SCRIPT;
146     }
147     
148     unlink(scriptName);
149     FREE(scriptName);
150
151     return 0;
152 }
153
154 int buildSpec(Spec spec, int what, int test)
155 {
156     int x, rc;
157
158     if (!spec->inBuildArchitectures && spec->buildArchitectureCount) {
159         /* When iterating over buildArchitectures, do the source    */
160         /* packaging on the first run, and skip RMSOURCE altogether */
161         x = 0;
162         while (x < spec->buildArchitectureCount) {
163             if ((rc = buildSpec(spec->buildArchitectureSpecs[x],
164                                 (what & ~RPMBUILD_RMSOURCE) |
165                                 (x ? 0 : (what & RPMBUILD_PACKAGESOURCE)),
166                                 test))) {
167                 return rc;
168             }
169             x++;
170         }
171     } else {
172         if (what & RPMBUILD_PREP) {
173             if ((rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test))) {
174                 return rc;
175             }
176         }
177         if (what & RPMBUILD_BUILD) {
178             if ((rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test))) {
179                 return rc;
180             }
181         }
182         if (what & RPMBUILD_INSTALL) {
183             if ((rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test))) {
184                 return rc;
185             }
186         }
187
188         if (what & RPMBUILD_PACKAGESOURCE) {
189             if ((rc = processSourceFiles(spec))) {
190                 return rc;
191             }
192         }
193
194         if ((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
195             (what & RPMBUILD_FILECHECK)) {
196             if ((rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL,
197                                          test))) {
198                 return rc;
199             }
200         }
201
202         if (what & RPMBUILD_PACKAGESOURCE && !test) {
203             if ((rc = packageSources(spec))) {
204                 return rc;
205             }
206         }
207         if (what & RPMBUILD_PACKAGEBINARY && !test) {
208             if ((rc = packageBinaries(spec))) {
209                 return rc;
210             }
211         }
212         
213         if (what & RPMBUILD_CLEAN) {
214             if ((rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test))) {
215                 return rc;
216             }
217         }
218         if (what & RPMBUILD_RMBUILD) {
219             if ((rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test))) {
220                 return rc;
221             }
222         }
223     }
224
225     if (what & RPMBUILD_RMSOURCE) {
226         doRmSource(spec);
227     }
228
229     return 0;
230 }