First attempt at librpmbuild API.
[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 static int writeVars(Spec spec, FILE *f);
8 #endif
9
10 static void doRmSource(Spec spec)
11 {
12     struct Source *p;
13     Package pkg;
14     char buf[BUFSIZ];
15     
16     unlink(spec->specFile);
17
18     p = spec->sources;
19     while (p) {
20         if (! (p->flags & RPMBUILD_ISNO)) {
21             sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), p->source);
22             unlink(buf);
23         }
24         p = p->next;
25     }
26
27     pkg = spec->packages;
28     while (pkg) {
29         p = pkg->icon;
30         while (p) {
31             if (! (p->flags & RPMBUILD_ISNO)) {
32                 sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), p->source);
33                 unlink(buf);
34             }
35             p = p->next;
36         }
37         pkg = pkg->next;
38     }
39 }
40
41 static int writeVars(Spec spec, FILE *f)
42 {
43     char *arch, *os, *s;
44     
45     rpmGetArchInfo(&arch, NULL);
46     rpmGetOsInfo(&os, NULL);
47
48     fprintf(f, "RPM_SOURCE_DIR=\"%s\"\n", rpmGetVar(RPMVAR_SOURCEDIR));
49     fprintf(f, "RPM_BUILD_DIR=\"%s\"\n", rpmGetVar(RPMVAR_BUILDDIR));
50     fprintf(f, "RPM_DOC_DIR=\"%s\"\n", spec->docDir);
51     fprintf(f, "RPM_OPT_FLAGS=\"%s\"\n", rpmGetVar(RPMVAR_OPTFLAGS));
52     fprintf(f, "RPM_ARCH=\"%s\"\n", arch);
53     fprintf(f, "RPM_OS=\"%s\"\n", os);
54     fprintf(f, "export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_DOC_DIR "
55             "RPM_OPT_FLAGS RPM_ARCH RPM_OS\n");
56
57     if (spec->buildRoot) {
58         fprintf(f, "RPM_BUILD_ROOT=\"%s\"\n", spec->buildRoot);
59         fprintf(f, "export RPM_BUILD_ROOT\n");
60         /* This could really be checked internally */
61         fprintf(f, "if [ -z \"$RPM_BUILD_ROOT\" -o -z \"`echo $RPM_BUILD_ROOT | sed -e 's#/##g'`\" ]; then\n");
62         fprintf(f, "  echo 'Warning: Spec contains BuildRoot: tag that is either empty or is set to \"/\"'\n");
63         fprintf(f, "  exit 1\n");
64         fprintf(f, "fi\n");
65     }
66
67     headerGetEntry(spec->packages->header, RPMTAG_NAME,
68                    NULL, (void **)&s, NULL);
69     fprintf(f, "RPM_PACKAGE_NAME=\"%s\"\n", s);
70     headerGetEntry(spec->packages->header, RPMTAG_VERSION,
71                    NULL, (void **)&s, NULL);
72     fprintf(f, "RPM_PACKAGE_VERSION=\"%s\"\n", s);
73     headerGetEntry(spec->packages->header, RPMTAG_RELEASE,
74                    NULL, (void **)&s, NULL);
75     fprintf(f, "RPM_PACKAGE_RELEASE=\"%s\"\n", s);
76     fprintf(f, "export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION "
77             "RPM_PACKAGE_RELEASE\n");
78     
79     return 0;
80 }
81
82 int doScript(Spec spec, int what, char *name, StringBuf sb, int test)
83 {
84     int fd;
85     FILE *f;
86     char *scriptName;
87     int pid;
88     int status;
89     char *buildShell;
90     
91     switch (what) {
92       case RPMBUILD_PREP:
93         name = "%prep";
94         sb = spec->prep;
95         break;
96       case RPMBUILD_BUILD:
97         name = "%build";
98         sb = spec->build;
99         break;
100       case RPMBUILD_INSTALL:
101         name = "%install";
102         sb = spec->install;
103         break;
104       case RPMBUILD_CLEAN:
105         name = "%clean";
106         sb = spec->clean;
107         break;
108       case RPMBUILD_RMBUILD:
109         name = "--clean";
110         break;
111       case RPMBUILD_STRINGBUF:
112         break;
113     }
114     if ((what != RPMBUILD_RMBUILD) && !sb) {
115         return 0;
116     }
117     
118     if (makeTempFile(NULL, &scriptName, &fd)) {
119         rpmError(RPMERR_SCRIPT, "Unable to open temp file");
120         return RPMERR_SCRIPT;
121     }
122     f = fdopen(fd, "w");
123     
124     if (writeVars(spec, f)) {
125         fclose(f);
126         unlink(scriptName);
127         FREE(scriptName);
128         return RPMERR_SCRIPT;
129     }
130     
131     fprintf(f, rpmIsVerbose() ? "set -x\n\n" : "exec > /dev/null\n\n");
132     fprintf(f, "umask 022\n");
133     fprintf(f, "cd %s\n", rpmGetVar(RPMVAR_BUILDDIR));
134     if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD) {
135         if (spec->buildSubdir) {
136             fprintf(f, "cd %s\n", spec->buildSubdir);
137         }
138     }
139     if (what == RPMBUILD_RMBUILD) {
140         if (spec->buildSubdir) {
141             fprintf(f, "rm -rf %s\n", spec->buildSubdir);
142         }
143     } else {
144         fprintf(f, "%s", getStringBuf(sb));
145     }
146     fprintf(f, "\nexit 0\n");
147     
148     fclose(f);
149     chmod(scriptName, 0600);
150
151     if (test) {
152         FREE(scriptName);
153         return 0;
154     }
155     
156     rpmMessage(RPMMESS_NORMAL, "Executing: %s\n", name);
157     if (!(pid = fork())) {
158         buildShell = rpmGetVar(RPMVAR_BUILDSHELL);
159         execl(buildShell, buildShell, "-e", scriptName, scriptName, NULL);
160         rpmError(RPMERR_SCRIPT, "Exec of %s failed (%s)",
161                  scriptName, name);
162         unlink(scriptName);
163         FREE(scriptName);
164         return RPMERR_SCRIPT;
165     }
166     wait(&status);
167     if (! WIFEXITED(status) || WEXITSTATUS(status)) {
168         rpmError(RPMERR_SCRIPT, "Bad exit status from %s (%s)",
169                  scriptName, name);
170         unlink(scriptName);
171         FREE(scriptName);
172         return RPMERR_SCRIPT;
173     }
174     
175     unlink(scriptName);
176     FREE(scriptName);
177
178     return 0;
179 }
180
181 int buildSpec(Spec spec, int what, int test)
182 {
183     int x, rc;
184
185     if (!spec->inBuildArchitectures && spec->buildArchitectureCount) {
186         /* When iterating over buildArchitectures, do the source    */
187         /* packaging on the first run, and skip RMSOURCE altogether */
188         x = 0;
189         while (x < spec->buildArchitectureCount) {
190             if ((rc = buildSpec(spec->buildArchitectureSpecs[x],
191                                 (what & ~RPMBUILD_RMSOURCE) |
192                                 (x ? 0 : (what & RPMBUILD_PACKAGESOURCE)),
193                                 test))) {
194                 return rc;
195             }
196             x++;
197         }
198     } else {
199         if (what & RPMBUILD_PREP) {
200             if ((rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test))) {
201                 return rc;
202             }
203         }
204         if (what & RPMBUILD_BUILD) {
205             if ((rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test))) {
206                 return rc;
207             }
208         }
209         if (what & RPMBUILD_INSTALL) {
210             if ((rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test))) {
211                 return rc;
212             }
213         }
214
215         if (what & RPMBUILD_PACKAGESOURCE) {
216             if ((rc = processSourceFiles(spec))) {
217                 return rc;
218             }
219         }
220
221         if ((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
222             (what & RPMBUILD_FILECHECK)) {
223             if ((rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL,
224                                          test))) {
225                 return rc;
226             }
227         }
228
229         if (what & RPMBUILD_PACKAGESOURCE && !test) {
230             if ((rc = packageSources(spec))) {
231                 return rc;
232             }
233         }
234         if (what & RPMBUILD_PACKAGEBINARY && !test) {
235             if ((rc = packageBinaries(spec))) {
236                 return rc;
237             }
238         }
239         
240         if (what & RPMBUILD_CLEAN) {
241             if ((rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test))) {
242                 return rc;
243             }
244         }
245         if (what & RPMBUILD_RMBUILD) {
246             if ((rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test))) {
247                 return rc;
248             }
249         }
250     }
251
252     if (what & RPMBUILD_RMSOURCE) {
253         doRmSource(spec);
254     }
255
256     return 0;
257 }