Remove dead and unused, ifdef'ed HAVE_FCHMOD block of code.
[platform/upstream/rpm.git] / build / build.c
1 /** \ingroup rpmbuild
2  * \file build/build.c
3  *  Top-level build dispatcher.
4  */
5
6 #include "system.h"
7
8 #include <rpmio_internal.h>
9 #include <rpmbuild.h>
10 #include "rpmerr.h"
11 #include "misc.h"       /* XXX for makeTempFile */
12
13 #include "debug.h"
14
15 static int _build_debug = 0;
16
17 /**
18  */
19 static void doRmSource(rpmSpec spec)
20 {
21     struct Source *p;
22     Package pkg;
23     int rc;
24     
25 #if 0
26     rc = Unlink(spec->specFile);
27 #endif
28
29     for (p = spec->sources; p != NULL; p = p->next) {
30         if (! (p->flags & RPMBUILD_ISNO)) {
31             const char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
32             rc = Unlink(fn);
33             fn = _free(fn);
34         }
35     }
36
37     for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
38         for (p = pkg->icon; p != NULL; p = p->next) {
39             if (! (p->flags & RPMBUILD_ISNO)) {
40                 const char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
41                 rc = Unlink(fn);
42                 fn = _free(fn);
43             }
44         }
45     }
46 }
47
48 /*
49  * @todo Single use by %%doc in files.c prevents static.
50  */
51 int doScript(rpmSpec spec, rpmBuildFlags what, const char *name, StringBuf sb, int test)
52 {
53     const char * rootURL = spec->rootURL;
54     const char * rootDir;
55     const char *scriptName = NULL;
56     const char * buildDirURL = rpmGenPath(rootURL, "%{_builddir}", "");
57     const char * buildScript;
58     const char * buildCmd = NULL;
59     const char * buildTemplate = NULL;
60     const char * buildPost = NULL;
61     const char * mTemplate = NULL;
62     const char * mCmd = NULL;
63     const char * mPost = NULL;
64     int argc = 0;
65     const char **argv = NULL;
66     FILE * fp = NULL;
67     urlinfo u = NULL;
68
69     FD_t fd;
70     FD_t xfd;
71     int child;
72     int status;
73     int rc;
74     
75     switch (what) {
76     case RPMBUILD_PREP:
77         name = "%prep";
78         sb = spec->prep;
79         mTemplate = "%{__spec_prep_template}";
80         mPost = "%{__spec_prep_post}";
81         mCmd = "%{__spec_prep_cmd}";
82         break;
83     case RPMBUILD_BUILD:
84         name = "%build";
85         sb = spec->build;
86         mTemplate = "%{__spec_build_template}";
87         mPost = "%{__spec_build_post}";
88         mCmd = "%{__spec_build_cmd}";
89         break;
90     case RPMBUILD_INSTALL:
91         name = "%install";
92         sb = spec->install;
93         mTemplate = "%{__spec_install_template}";
94         mPost = "%{__spec_install_post}";
95         mCmd = "%{__spec_install_cmd}";
96         break;
97     case RPMBUILD_CHECK:
98         name = "%check";
99         sb = spec->check;
100         mTemplate = "%{__spec_check_template}";
101         mPost = "%{__spec_check_post}";
102         mCmd = "%{__spec_check_cmd}";
103         break;
104     case RPMBUILD_CLEAN:
105         name = "%clean";
106         sb = spec->clean;
107         mTemplate = "%{__spec_clean_template}";
108         mPost = "%{__spec_clean_post}";
109         mCmd = "%{__spec_clean_cmd}";
110         break;
111     case RPMBUILD_RMBUILD:
112         name = "--clean";
113         mTemplate = "%{__spec_clean_template}";
114         mPost = "%{__spec_clean_post}";
115         mCmd = "%{__spec_clean_cmd}";
116         break;
117     case RPMBUILD_STRINGBUF:
118     default:
119         mTemplate = "%{___build_template}";
120         mPost = "%{___build_post}";
121         mCmd = "%{___build_cmd}";
122         break;
123     }
124     if (name == NULL)   /* XXX shouldn't happen */
125         name = "???";
126
127     if ((what != RPMBUILD_RMBUILD) && sb == NULL) {
128         rc = 0;
129         goto exit;
130     }
131     
132     if (makeTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
133         rpmlog(RPMERR_SCRIPT, _("Unable to open temp file.\n"));
134         rc = RPMERR_SCRIPT;
135         goto exit;
136     }
137
138     if (fdGetFp(fd) == NULL)
139         xfd = Fdopen(fd, "w.fpio");
140     else
141         xfd = fd;
142
143     /* FIX: cast? */
144     if ((fp = fdGetFp(xfd)) == NULL) {
145         rc = RPMERR_SCRIPT;
146         goto exit;
147     }
148     
149     (void) urlPath(rootURL, &rootDir);
150     if (*rootDir == '\0') rootDir = "/";
151
152     (void) urlPath(scriptName, &buildScript);
153
154     buildTemplate = rpmExpand(mTemplate, NULL);
155     buildPost = rpmExpand(mPost, NULL);
156
157     (void) fputs(buildTemplate, fp);
158
159     if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir)
160         fprintf(fp, "cd '%s'\n", spec->buildSubdir);
161
162     if (what == RPMBUILD_RMBUILD) {
163         if (spec->buildSubdir)
164             fprintf(fp, "rm -rf '%s'\n", spec->buildSubdir);
165     } else if (sb != NULL)
166         fprintf(fp, "%s", getStringBuf(sb));
167
168     (void) fputs(buildPost, fp);
169     
170     (void) Fclose(xfd);
171
172     if (test) {
173         rc = 0;
174         goto exit;
175     }
176     
177 if (_build_debug)
178 fprintf(stderr, "*** rootURL %s buildDirURL %s\n", rootURL, buildDirURL);
179     if (buildDirURL && buildDirURL[0] != '/' &&
180         (urlSplit(buildDirURL, &u) != 0)) {
181         rc = RPMERR_SCRIPT;
182         goto exit;
183     }
184     if (u != NULL) {
185         switch (u->urltype) {
186         case URL_IS_HTTPS:
187         case URL_IS_HTTP:
188         case URL_IS_FTP:
189 if (_build_debug)
190 fprintf(stderr, "*** addMacros\n");
191             addMacro(spec->macros, "_remsh", NULL, "%{__remsh}", RMIL_SPEC);
192             addMacro(spec->macros, "_remhost", NULL, u->host, RMIL_SPEC);
193             if (strcmp(rootDir, "/"))
194                 addMacro(spec->macros, "_remroot", NULL, rootDir, RMIL_SPEC);
195             break;
196         case URL_IS_UNKNOWN:
197         case URL_IS_DASH:
198         case URL_IS_PATH:
199         case URL_IS_HKP:
200         default:
201             break;
202         }
203     }
204
205     buildCmd = rpmExpand(mCmd, " ", buildScript, NULL);
206     (void) poptParseArgvString(buildCmd, &argc, &argv);
207
208     rpmlog(RPMLOG_NOTICE, _("Executing(%s): %s\n"), name, buildCmd);
209     if (!(child = fork())) {
210
211         errno = 0;
212         (void) execvp(argv[0], (char *const *)argv);
213
214         rpmlog(RPMERR_SCRIPT, _("Exec of %s failed (%s): %s\n"),
215                 scriptName, name, strerror(errno));
216
217         _exit(-1);
218     }
219
220     rc = waitpid(child, &status, 0);
221
222     if (!WIFEXITED(status) || WEXITSTATUS(status)) {
223         rpmlog(RPMERR_SCRIPT, _("Bad exit status from %s (%s)\n"),
224                  scriptName, name);
225         rc = RPMERR_SCRIPT;
226     } else
227         rc = 0;
228     
229 exit:
230     if (scriptName) {
231         if (!rc)
232             (void) Unlink(scriptName);
233         scriptName = _free(scriptName);
234     }
235     if (u != NULL) {
236         switch (u->urltype) {
237         case URL_IS_HTTPS:
238         case URL_IS_HTTP:
239         case URL_IS_FTP:
240 if (_build_debug)
241 fprintf(stderr, "*** delMacros\n");
242             delMacro(spec->macros, "_remsh");
243             delMacro(spec->macros, "_remhost");
244             if (strcmp(rootDir, "/"))
245                 delMacro(spec->macros, "_remroot");
246             break;
247         case URL_IS_UNKNOWN:
248         case URL_IS_DASH:
249         case URL_IS_PATH:
250         case URL_IS_HKP:
251         default:
252             break;
253         }
254         u = urlFree(u);
255     }
256     argv = _free(argv);
257     buildCmd = _free(buildCmd);
258     buildTemplate = _free(buildTemplate);
259     buildPost = _free(buildPost);
260     buildDirURL = _free(buildDirURL);
261
262     return rc;
263 }
264
265 int buildSpec(rpmts ts, rpmSpec spec, int what, int test)
266 {
267     int rc = 0;
268
269     if (!spec->recursing && spec->BACount) {
270         int x;
271         /* When iterating over BANames, do the source    */
272         /* packaging on the first run, and skip RMSOURCE altogether */
273         if (spec->BASpecs != NULL)
274         for (x = 0; x < spec->BACount; x++) {
275             if ((rc = buildSpec(ts, spec->BASpecs[x],
276                                 (what & ~RPMBUILD_RMSOURCE) |
277                                 (x ? 0 : (what & RPMBUILD_PACKAGESOURCE)),
278                                 test))) {
279                 goto exit;
280             }
281         }
282     } else {
283         if ((what & RPMBUILD_PREP) &&
284             (rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test)))
285                 goto exit;
286
287         if ((what & RPMBUILD_BUILD) &&
288             (rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test)))
289                 goto exit;
290
291         if ((what & RPMBUILD_INSTALL) &&
292             (rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test)))
293                 goto exit;
294
295         if ((what & RPMBUILD_CHECK) &&
296             (rc = doScript(spec, RPMBUILD_CHECK, NULL, NULL, test)))
297                 goto exit;
298
299         if ((what & RPMBUILD_PACKAGESOURCE) &&
300             (rc = processSourceFiles(spec)))
301                 goto exit;
302
303         if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
304             (what & RPMBUILD_FILECHECK)) &&
305             (rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL, test)))
306                 goto exit;
307
308         if (((what & RPMBUILD_PACKAGESOURCE) && !test) &&
309             (rc = packageSources(spec)))
310                 return rc;
311
312         if (((what & RPMBUILD_PACKAGEBINARY) && !test) &&
313             (rc = packageBinaries(spec)))
314                 goto exit;
315         
316         if ((what & RPMBUILD_CLEAN) &&
317             (rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test)))
318                 goto exit;
319
320         if ((what & RPMBUILD_RMBUILD) &&
321             (rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test)))
322                 goto exit;
323     }
324
325     if (what & RPMBUILD_RMSOURCE)
326         doRmSource(spec);
327
328     if (what & RPMBUILD_RMSPEC)
329         (void) Unlink(spec->specFile);
330
331 exit:
332     if (rc && rpmlogGetNrecs() > 0) {
333         rpmlog(RPMLOG_NOTICE, _("\n\nRPM build errors:\n"));
334         rpmlogPrint(NULL);
335     }
336
337     return rc;
338 }