blob: b57681392a69433c9e2305396235c7410584c2bb [file] [log] [blame]
Zack Weinberg49e6c082000-03-04 19:42:04 +00001/* Dependency generator for Makefile fragments.
Jakub Jelinek748086b2009-04-09 17:00:19 +02002 Copyright (C) 2000, 2001, 2003, 2007, 2008, 2009
3 Free Software Foundation, Inc.
Zack Weinberg49e6c082000-03-04 19:42:04 +00004 Contributed by Zack Weinberg, Mar 2000
5
6This program is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
Jakub Jelinek748086b2009-04-09 17:00:19 +02008Free Software Foundation; either version 3, or (at your option) any
Zack Weinberg49e6c082000-03-04 19:42:04 +00009later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
Jakub Jelinek748086b2009-04-09 17:00:19 +020017along with this program; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>.
Zack Weinberg49e6c082000-03-04 19:42:04 +000019
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding! */
23
24#include "config.h"
25#include "system.h"
26#include "mkdeps.h"
27
Neil Booth03b9ab42001-01-04 10:25:55 +000028/* Keep this structure local to this file, so clients don't find it
29 easy to start making assumptions. */
30struct deps
31{
32 const char **targetv;
33 unsigned int ntargets; /* number of slots actually occupied */
34 unsigned int targets_size; /* amt of allocated space - in words */
35
36 const char **depv;
37 unsigned int ndeps;
38 unsigned int deps_size;
Zack Weinbergc6e83802004-06-05 20:58:06 +000039
40 const char **vpathv;
41 size_t *vpathlv;
42 unsigned int nvpaths;
43 unsigned int vpaths_size;
Neil Booth03b9ab42001-01-04 10:25:55 +000044};
45
Andreas Jaeger0c20a652003-07-06 11:56:09 +020046static const char *munge (const char *);
Zack Weinberg49e6c082000-03-04 19:42:04 +000047
Zack Weinberg49e6c082000-03-04 19:42:04 +000048/* Given a filename, quote characters in that filename which are
49 significant to Make. Note that it's not possible to quote all such
50 characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are
51 not properly handled. It isn't possible to get this right in any
52 current version of Make. (??? Still true? Old comment referred to
53 3.76.1.) */
Andreas Jaeger0c20a652003-07-06 11:56:09 +020054
Zack Weinberg49e6c082000-03-04 19:42:04 +000055static const char *
Andreas Jaeger0c20a652003-07-06 11:56:09 +020056munge (const char *filename)
Zack Weinberg49e6c082000-03-04 19:42:04 +000057{
58 int len;
59 const char *p, *q;
60 char *dst, *buffer;
61
62 for (p = filename, len = 0; *p; p++, len++)
63 {
64 switch (*p)
65 {
66 case ' ':
67 case '\t':
68 /* GNU make uses a weird quoting scheme for white space.
69 A space or tab preceded by 2N+1 backslashes represents
70 N backslashes followed by space; a space or tab
71 preceded by 2N backslashes represents N backslashes at
72 the end of a file name; and backslashes in other
73 contexts should not be doubled. */
Zack Weinberge23c0ba2000-03-07 23:11:06 +000074 for (q = p - 1; filename <= q && *q == '\\'; q--)
Zack Weinberg49e6c082000-03-04 19:42:04 +000075 len++;
76 len++;
77 break;
78
79 case '$':
Neil Bootha5a4ce32001-01-05 07:50:24 +000080 /* '$' is quoted by doubling it. */
Zack Weinberg49e6c082000-03-04 19:42:04 +000081 len++;
82 break;
Markus Milleder830465c2008-03-06 19:08:40 +010083
84 case '#':
85 /* '#' is quoted with a backslash. */
86 len++;
87 break;
Zack Weinberg49e6c082000-03-04 19:42:04 +000088 }
89 }
90
91 /* Now we know how big to make the buffer. */
Gabriel Dos Reisc3f829c2005-05-28 15:52:48 +000092 buffer = XNEWVEC (char, len + 1);
Zack Weinberg49e6c082000-03-04 19:42:04 +000093
94 for (p = filename, dst = buffer; *p; p++, dst++)
95 {
96 switch (*p)
97 {
98 case ' ':
99 case '\t':
Zack Weinberge23c0ba2000-03-07 23:11:06 +0000100 for (q = p - 1; filename <= q && *q == '\\'; q--)
Zack Weinberg49e6c082000-03-04 19:42:04 +0000101 *dst++ = '\\';
102 *dst++ = '\\';
103 break;
104
105 case '$':
106 *dst++ = '$';
107 break;
108
Markus Milleder830465c2008-03-06 19:08:40 +0100109 case '#':
110 *dst++ = '\\';
111 break;
112
Zack Weinberg49e6c082000-03-04 19:42:04 +0000113 default:
114 /* nothing */;
115 }
116 *dst = *p;
117 }
118
119 *dst = '\0';
120 return buffer;
121}
122
Zack Weinbergc6e83802004-06-05 20:58:06 +0000123/* If T begins with any of the partial pathnames listed in d->vpathv,
124 then advance T to point beyond that pathname. */
125static const char *
126apply_vpath (struct deps *d, const char *t)
127{
128 if (d->vpathv)
129 {
130 unsigned int i;
131 for (i = 0; i < d->nvpaths; i++)
132 {
Kai Tietz44898002011-03-25 20:11:26 +0100133 if (!filename_ncmp (d->vpathv[i], t, d->vpathlv[i]))
Zack Weinbergc6e83802004-06-05 20:58:06 +0000134 {
135 const char *p = t + d->vpathlv[i];
136 if (!IS_DIR_SEPARATOR (*p))
137 goto not_this_one;
138
139 /* Do not simplify $(vpath)/../whatever. ??? Might not
140 be necessary. */
141 if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3]))
142 goto not_this_one;
143
144 /* found a match */
145 t = t + d->vpathlv[i] + 1;
146 break;
147 }
148 not_this_one:;
149 }
150 }
151
152 /* Remove leading ./ in any case. */
153 while (t[0] == '.' && IS_DIR_SEPARATOR (t[1]))
Tom Tromey67e64432007-01-30 15:50:00 +0000154 {
155 t += 2;
156 /* If we removed a leading ./, then also remove any /s after the
157 first. */
158 while (IS_DIR_SEPARATOR (t[0]))
159 ++t;
160 }
Zack Weinbergc6e83802004-06-05 20:58:06 +0000161
162 return t;
163}
164
Zack Weinberg49e6c082000-03-04 19:42:04 +0000165/* Public routines. */
166
167struct deps *
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200168deps_init (void)
Zack Weinberg49e6c082000-03-04 19:42:04 +0000169{
Gabriel Dos Reisc3f829c2005-05-28 15:52:48 +0000170 return XCNEW (struct deps);
Zack Weinberg49e6c082000-03-04 19:42:04 +0000171}
172
173void
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200174deps_free (struct deps *d)
Zack Weinberg49e6c082000-03-04 19:42:04 +0000175{
176 unsigned int i;
Richard Kenner05bccae2000-03-07 11:41:32 +0000177
Neil Boothf7114e12001-01-06 00:15:29 +0000178 if (d->targetv)
179 {
180 for (i = 0; i < d->ntargets; i++)
Kaveh R. Ghazifad205f2003-06-16 21:41:10 +0000181 free ((void *) d->targetv[i]);
Neil Boothf7114e12001-01-06 00:15:29 +0000182 free (d->targetv);
183 }
Richard Kenner05bccae2000-03-07 11:41:32 +0000184
Neil Boothf7114e12001-01-06 00:15:29 +0000185 if (d->depv)
186 {
187 for (i = 0; i < d->ndeps; i++)
Kaveh R. Ghazifad205f2003-06-16 21:41:10 +0000188 free ((void *) d->depv[i]);
Neil Boothf7114e12001-01-06 00:15:29 +0000189 free (d->depv);
190 }
Zack Weinberg49e6c082000-03-04 19:42:04 +0000191
Zack Weinbergc6e83802004-06-05 20:58:06 +0000192 if (d->vpathv)
193 {
194 for (i = 0; i < d->nvpaths; i++)
195 free ((void *) d->vpathv[i]);
196 free (d->vpathv);
197 free (d->vpathlv);
198 }
199
Zack Weinberg49e6c082000-03-04 19:42:04 +0000200 free (d);
201}
202
Neil Bootha5a4ce32001-01-05 07:50:24 +0000203/* Adds a target T. We make a copy, so it need not be a permanent
204 string. QUOTE is true if the string should be quoted. */
Zack Weinberg49e6c082000-03-04 19:42:04 +0000205void
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200206deps_add_target (struct deps *d, const char *t, int quote)
Zack Weinberg49e6c082000-03-04 19:42:04 +0000207{
Zack Weinberg49e6c082000-03-04 19:42:04 +0000208 if (d->ntargets == d->targets_size)
209 {
Neil Boothf7114e12001-01-06 00:15:29 +0000210 d->targets_size = d->targets_size * 2 + 4;
Gabriel Dos Reisc3f829c2005-05-28 15:52:48 +0000211 d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size);
Zack Weinberg49e6c082000-03-04 19:42:04 +0000212 }
Richard Kenner05bccae2000-03-07 11:41:32 +0000213
Zack Weinbergc6e83802004-06-05 20:58:06 +0000214 t = apply_vpath (d, t);
Neil Bootha5a4ce32001-01-05 07:50:24 +0000215 if (quote)
216 t = munge (t); /* Also makes permanent copy. */
217 else
218 t = xstrdup (t);
219
Zack Weinberg49e6c082000-03-04 19:42:04 +0000220 d->targetv[d->ntargets++] = t;
221}
222
Neil Booth03b9ab42001-01-04 10:25:55 +0000223/* Sets the default target if none has been given already. An empty
Neil Bootha5a4ce32001-01-05 07:50:24 +0000224 string as the default target in interpreted as stdin. The string
225 is quoted for MAKE. */
Zack Weinberg49e6c082000-03-04 19:42:04 +0000226void
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200227deps_add_default_target (struct deps *d, const char *tgt)
Zack Weinberg49e6c082000-03-04 19:42:04 +0000228{
Neil Booth03b9ab42001-01-04 10:25:55 +0000229 /* Only if we have no targets. */
230 if (d->ntargets)
231 return;
Zack Weinberg49e6c082000-03-04 19:42:04 +0000232
Neil Booth03b9ab42001-01-04 10:25:55 +0000233 if (tgt[0] == '\0')
Neil Bootha5a4ce32001-01-05 07:50:24 +0000234 deps_add_target (d, "-", 1);
Zack Weinberg49e6c082000-03-04 19:42:04 +0000235 else
Neil Booth03b9ab42001-01-04 10:25:55 +0000236 {
DJ Delorie45936a82001-04-19 16:28:05 -0400237#ifndef TARGET_OBJECT_SUFFIX
238# define TARGET_OBJECT_SUFFIX ".o"
Neil Booth03b9ab42001-01-04 10:25:55 +0000239#endif
Andrew Cagney0821bff2001-08-03 15:42:25 +0000240 const char *start = lbasename (tgt);
Gabriel Dos Reisc3f829c2005-05-28 15:52:48 +0000241 char *o = (char *) alloca (strlen (start)
242 + strlen (TARGET_OBJECT_SUFFIX) + 1);
Nathan Sidwell48ce6bb2001-02-12 14:06:22 +0000243 char *suffix;
Neil Booth03b9ab42001-01-04 10:25:55 +0000244
Nathan Sidwell48ce6bb2001-02-12 14:06:22 +0000245 strcpy (o, start);
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200246
Nathan Sidwell48ce6bb2001-02-12 14:06:22 +0000247 suffix = strrchr (o, '.');
248 if (!suffix)
249 suffix = o + strlen (o);
DJ Delorie45936a82001-04-19 16:28:05 -0400250 strcpy (suffix, TARGET_OBJECT_SUFFIX);
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200251
Neil Bootha5a4ce32001-01-05 07:50:24 +0000252 deps_add_target (d, o, 1);
Neil Booth03b9ab42001-01-04 10:25:55 +0000253 }
Zack Weinberg49e6c082000-03-04 19:42:04 +0000254}
255
256void
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200257deps_add_dep (struct deps *d, const char *t)
Zack Weinberg49e6c082000-03-04 19:42:04 +0000258{
Zack Weinbergc6e83802004-06-05 20:58:06 +0000259 t = munge (apply_vpath (d, t)); /* Also makes permanent copy. */
Zack Weinberg49e6c082000-03-04 19:42:04 +0000260
261 if (d->ndeps == d->deps_size)
262 {
Neil Boothfa6f74f2001-01-06 11:08:49 +0000263 d->deps_size = d->deps_size * 2 + 8;
Gabriel Dos Reisc3f829c2005-05-28 15:52:48 +0000264 d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size);
Zack Weinberg49e6c082000-03-04 19:42:04 +0000265 }
266 d->depv[d->ndeps++] = t;
267}
268
269void
Zack Weinbergc6e83802004-06-05 20:58:06 +0000270deps_add_vpath (struct deps *d, const char *vpath)
271{
272 const char *elem, *p;
273 char *copy;
274 size_t len;
275
276 for (elem = vpath; *elem; elem = p)
277 {
278 for (p = elem; *p && *p != ':'; p++);
279 len = p - elem;
Gabriel Dos Reisc3f829c2005-05-28 15:52:48 +0000280 copy = XNEWVEC (char, len + 1);
Zack Weinbergc6e83802004-06-05 20:58:06 +0000281 memcpy (copy, elem, len);
282 copy[len] = '\0';
283 if (*p == ':')
284 p++;
285
286 if (d->nvpaths == d->vpaths_size)
287 {
288 d->vpaths_size = d->vpaths_size * 2 + 8;
Gabriel Dos Reisc3f829c2005-05-28 15:52:48 +0000289 d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size);
290 d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size);
Zack Weinbergc6e83802004-06-05 20:58:06 +0000291 }
292 d->vpathv[d->nvpaths] = copy;
293 d->vpathlv[d->nvpaths] = len;
294 d->nvpaths++;
295 }
296}
297
298void
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200299deps_write (const struct deps *d, FILE *fp, unsigned int colmax)
Zack Weinberg49e6c082000-03-04 19:42:04 +0000300{
301 unsigned int size, i, column;
302
303 column = 0;
304 if (colmax && colmax < 34)
305 colmax = 34;
306
307 for (i = 0; i < d->ntargets; i++)
308 {
309 size = strlen (d->targetv[i]);
310 column += size;
Zack Weinberg49e6c082000-03-04 19:42:04 +0000311 if (i)
312 {
Ralf Wildenhuesd482a072008-02-27 21:42:23 +0000313 if (colmax && column > colmax)
314 {
315 fputs (" \\\n ", fp);
316 column = 1 + size;
317 }
318 else
319 {
320 putc (' ', fp);
321 column++;
322 }
Zack Weinberg49e6c082000-03-04 19:42:04 +0000323 }
324 fputs (d->targetv[i], fp);
325 }
326
327 putc (':', fp);
Ralf Wildenhuesd482a072008-02-27 21:42:23 +0000328 column++;
Zack Weinberg49e6c082000-03-04 19:42:04 +0000329
330 for (i = 0; i < d->ndeps; i++)
331 {
332 size = strlen (d->depv[i]);
333 column += size;
334 if (colmax && column > colmax)
335 {
336 fputs (" \\\n ", fp);
337 column = 1 + size;
338 }
Ralf Wildenhuesd482a072008-02-27 21:42:23 +0000339 else
Zack Weinberg49e6c082000-03-04 19:42:04 +0000340 {
341 putc (' ', fp);
342 column++;
343 }
344 fputs (d->depv[i], fp);
345 }
346 putc ('\n', fp);
347}
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200348
Zack Weinberg49e6c082000-03-04 19:42:04 +0000349void
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200350deps_phony_targets (const struct deps *d, FILE *fp)
Zack Weinberg49e6c082000-03-04 19:42:04 +0000351{
Richard Kenner05bccae2000-03-07 11:41:32 +0000352 unsigned int i;
Zack Weinberg49e6c082000-03-04 19:42:04 +0000353
354 for (i = 1; i < d->ndeps; i++)
355 {
Neil Bootha5a4ce32001-01-05 07:50:24 +0000356 putc ('\n', fp);
Zack Weinberg49e6c082000-03-04 19:42:04 +0000357 fputs (d->depv[i], fp);
358 putc (':', fp);
359 putc ('\n', fp);
360 }
361}
Geoffrey Keating17211ab2003-01-10 02:22:34 +0000362
363/* Write out a deps buffer to a file, in a form that can be read back
364 with deps_restore. Returns nonzero on error, in which case the
365 error number will be in errno. */
366
367int
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200368deps_save (struct deps *deps, FILE *f)
Geoffrey Keating17211ab2003-01-10 02:22:34 +0000369{
370 unsigned int i;
371
372 /* The cppreader structure contains makefile dependences. Write out this
373 structure. */
374
375 /* The number of dependences. */
376 if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1)
377 return -1;
378 /* The length of each dependence followed by the string. */
379 for (i = 0; i < deps->ndeps; i++)
380 {
381 size_t num_to_write = strlen (deps->depv[i]);
382 if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1)
383 return -1;
384 if (fwrite (deps->depv[i], num_to_write, 1, f) != 1)
385 return -1;
386 }
387
388 return 0;
389}
390
391/* Read back dependency information written with deps_save into
392 the deps buffer. The third argument may be NULL, in which case
393 the dependency information is just skipped, or it may be a filename,
394 in which case that filename is skipped. */
395
396int
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200397deps_restore (struct deps *deps, FILE *fd, const char *self)
Geoffrey Keating17211ab2003-01-10 02:22:34 +0000398{
399 unsigned int i, count;
400 size_t num_to_read;
401 size_t buf_size = 512;
Tobias Burnus55e7f902012-10-15 22:08:57 +0200402 char *buf;
Geoffrey Keating17211ab2003-01-10 02:22:34 +0000403
404 /* Number of dependences. */
405 if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
406 return -1;
407
Tobias Burnus55e7f902012-10-15 22:08:57 +0200408 buf = XNEWVEC (char, buf_size);
409
Geoffrey Keating17211ab2003-01-10 02:22:34 +0000410 /* The length of each dependence string, followed by the string. */
411 for (i = 0; i < count; i++)
412 {
413 /* Read in # bytes in string. */
414 if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
Tobias Burnus55e7f902012-10-15 22:08:57 +0200415 {
416 free (buf);
417 return -1;
418 }
Geoffrey Keating17211ab2003-01-10 02:22:34 +0000419 if (buf_size < num_to_read + 1)
420 {
421 buf_size = num_to_read + 1 + 127;
Gabriel Dos Reisc3f829c2005-05-28 15:52:48 +0000422 buf = XRESIZEVEC (char, buf, buf_size);
Geoffrey Keating17211ab2003-01-10 02:22:34 +0000423 }
424 if (fread (buf, 1, num_to_read, fd) != num_to_read)
Tobias Burnus55e7f902012-10-15 22:08:57 +0200425 {
426 free (buf);
427 return -1;
428 }
Geoffrey Keating17211ab2003-01-10 02:22:34 +0000429 buf[num_to_read] = '\0';
430
Andreas Jaeger0c20a652003-07-06 11:56:09 +0200431 /* Generate makefile dependencies from .pch if -nopch-deps. */
Kai Tietz44898002011-03-25 20:11:26 +0100432 if (self != NULL && filename_cmp (buf, self) != 0)
Geoffrey Keating17211ab2003-01-10 02:22:34 +0000433 deps_add_dep (deps, buf);
434 }
435
436 free (buf);
437 return 0;
438}