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