source: trunk/src/gmake/kbuild.c@ 530

Last change on this file since 530 was 530, checked in by bird, 19 years ago

Added kBuild specific functions for speeding up source processing.

File size: 52.1 KB
Line 
1/* $Id: $ */
2/** @file
3 *
4 * kBuild specific make functionality.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird@innotek.de>
7 *
8 *
9 * This file is part of kBuild.
10 *
11 * kBuild is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * kBuild is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kBuild; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27/* No GNU coding style here! */
28
29#include "make.h"
30#include "variable.h"
31#include "dep.h"
32#include "debug.h"
33
34#include "kbuild.h"
35
36#include <assert.h>
37#include <stdarg.h>
38#ifndef va_copy
39# define va_copy(dst, src) do {(dst) = (src);} while (0)
40#endif
41
42
43/**
44 * Gets a variable that must exist.
45 * Will cause a fatal failure if the variable doesn't exist.
46 *
47 * @returns Pointer to the variable.
48 * @param pszName The variable name.
49 */
50static struct variable *
51kbuild_get_variable(const char *pszName)
52{
53 struct variable *pVar = lookup_variable(pszName, strlen(pszName));
54 if (!pVar)
55 fatal(NILF, _("variable `%s' isn't defined!"), pszName);
56 if (pVar->recursive)
57 fatal(NILF, _("variable `%s' is defined as `recursive' instead of `simple'!"), pszName);
58 pVar->value_length = strlen(pVar->value);
59 return pVar;
60}
61
62/**
63 * Gets a variable that must exist and can be recursive.
64 * Will cause a fatal failure if the variable doesn't exist.
65 *
66 * @returns Pointer to the variable.
67 * @param pszName The variable name.
68 */
69static struct variable *
70kbuild_get_recursive_variable(const char *pszName)
71{
72 struct variable *pVar = lookup_variable(pszName, strlen(pszName));
73 if (!pVar)
74 fatal(NILF, _("variable `%s' isn't defined!"), pszName);
75 pVar->value_length = strlen(pVar->value);
76 return pVar;
77}
78
79
80/**
81 * Looks up a variable.
82 * The value_length field is valid upon successful return.
83 *
84 * @returns Pointer to the variable. NULL if not found.
85 * @param pszName The variable name.
86 */
87static struct variable *
88kbuild_lookup_variable(const char *pszName)
89{
90 struct variable *pVar = lookup_variable(pszName, strlen(pszName));
91 if (pVar)
92 pVar->value_length = strlen(pVar->value);
93 return pVar;
94}
95
96/** Same as kbuild_lookup_variable except that a '%s' in the name string
97 * will be substituted with the values of the variables in the va list. */
98static struct variable *
99kbuild_lookup_variable_fmt_va(const char *pszNameFmt, va_list va)
100{
101 va_list va2;
102 size_t cchName;
103 const char *pszFmt;
104 char *pszName;
105 char *psz;
106
107 /* first pass, calc value name size and allocate stack buffer. */
108 va_copy(va2, va);
109
110 cchName = strlen(pszNameFmt) + 1;
111 pszFmt = strchr(pszNameFmt, '%');
112 while (pszFmt)
113 {
114 struct variable *pVar = va_arg(va, struct variable *);
115 if (pVar)
116 cchName += pVar->value_length;
117 pszFmt = strchr(pszFmt + 1, '%');
118 }
119 pszName = alloca(cchName);
120
121 /* second pass format it. */
122 pszFmt = pszNameFmt;
123 psz = pszName;
124 for (;;)
125 {
126 char ch = *pszFmt++;
127 if (ch != '%')
128 {
129 *psz++ = ch;
130 if (!ch)
131 break;
132 }
133 else
134 {
135 struct variable *pVar = va_arg(va2, struct variable *);
136 if (pVar)
137 {
138 memcpy(psz, pVar->value, pVar->value_length);
139 psz += pVar->value_length;
140 }
141 }
142 }
143 va_end(va2);
144
145 return kbuild_lookup_variable(pszName);
146}
147
148/** Same as kbuild_lookup_variable except that a '%s' in the name string
149 * will be substituted with the values of the variables in the ellipsis. */
150static struct variable *
151kbuild_lookup_variable_fmt(const char *pszNameFmt, ...)
152{
153 struct variable *pVar;
154 va_list va;
155 va_start(va, pszNameFmt);
156 pVar = kbuild_lookup_variable_fmt_va(pszNameFmt, va);
157 va_end(va);
158 return pVar;
159}
160
161
162/*
163_SOURCE_TOOL = $(strip $(firstword \
164 $($(target)_$(source)_$(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
165 $($(target)_$(source)_$(type)TOOL.$(bld_trg)) \
166 $($(target)_$(source)_$(type)TOOL) \
167 $($(target)_$(source)_TOOL.$(bld_trg).$(bld_trg_arch)) \
168 $($(target)_$(source)_TOOL.$(bld_trg)) \
169 $($(target)_$(source)_TOOL) \
170 $($(source)_$(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
171 $($(source)_$(type)TOOL.$(bld_trg)) \
172 $($(source)_$(type)TOOL) \
173 $($(source)_TOOL.$(bld_trg).$(bld_trg_arch)) \
174 $($(source)_TOOL.$(bld_trg)) \
175 $($(source)_TOOL) \
176 $($(target)_$(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
177 $($(target)_$(type)TOOL.$(bld_trg)) \
178 $($(target)_$(type)TOOL) \
179 $($(target)_TOOL.$(bld_trg).$(bld_trg_arch)) \
180 $($(target)_TOOL.$(bld_trg)) \
181 $($(target)_TOOL) \
182 $($(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
183 $($(type)TOOL.$(bld_trg)) \
184 $($(type)TOOL) \
185 $(TOOL.$(bld_trg).$(bld_trg_arch)) \
186 $(TOOL.$(bld_trg)) \
187 $(TOOL) ))
188*/
189static struct variable *
190kbuild_get_source_tool(struct variable *pTarget, struct variable *pSource, struct variable *pType,
191 struct variable *pBldTrg, struct variable *pBldTrgArch, const char *pszVarName)
192{
193 struct variable *pVar;
194 if ( (pVar = kbuild_lookup_variable_fmt("%_%_%TOOL_.%.%", pTarget, pSource, pType, pBldTrg, pBldTrgArch))
195 || (pVar = kbuild_lookup_variable_fmt("%_%_%TOOL_.%", pTarget, pSource, pType, pBldTrg))
196 || (pVar = kbuild_lookup_variable_fmt("%_%_%TOOL", pTarget, pSource, pType))
197 || (pVar = kbuild_lookup_variable_fmt("%_%_TOOL_.%.%", pTarget, pSource, pBldTrg, pBldTrgArch))
198 || (pVar = kbuild_lookup_variable_fmt("%_%_TOOL_.%", pTarget, pSource, pBldTrg))
199 || (pVar = kbuild_lookup_variable_fmt("%_%_TOOL", pTarget, pSource))
200 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL_.%.%", pSource, pType, pBldTrg, pBldTrgArch))
201 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL_.%", pSource, pType, pBldTrg))
202 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL", pSource, pType))
203 || (pVar = kbuild_lookup_variable_fmt("%_TOOL_.%.%", pSource, pBldTrg, pBldTrgArch))
204 || (pVar = kbuild_lookup_variable_fmt("%_TOOL_.%", pSource, pBldTrg))
205 || (pVar = kbuild_lookup_variable_fmt("%_TOOL", pSource))
206 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL_.%.%", pTarget, pType, pBldTrg, pBldTrgArch))
207 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL_.%", pTarget, pType, pBldTrg))
208 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL", pTarget, pType))
209 || (pVar = kbuild_lookup_variable_fmt("%_TOOL_.%.%", pTarget, pBldTrg, pBldTrgArch))
210 || (pVar = kbuild_lookup_variable_fmt("%_TOOL_.%", pTarget, pBldTrg))
211 || (pVar = kbuild_lookup_variable_fmt("%_TOOL", pTarget))
212 || (pVar = kbuild_lookup_variable_fmt("%TOOL_.%.%", pType, pBldTrg, pBldTrgArch))
213 || (pVar = kbuild_lookup_variable_fmt("%TOOL_.%", pType, pBldTrg))
214 || (pVar = kbuild_lookup_variable_fmt("%TOOL", pType))
215 || (pVar = kbuild_lookup_variable_fmt("TOOL_.%.%", pBldTrg, pBldTrgArch))
216 || (pVar = kbuild_lookup_variable_fmt("TOOL_.%", pBldTrg))
217 || (pVar = kbuild_lookup_variable("TOOL"))
218 )
219 {
220 /* strip it */
221 char *psz = pVar->value;
222 char *pszEnd = psz + pVar->value_length;
223 while (isblank((unsigned char)*psz))
224 psz++;
225 while (pszEnd > psz && isblank((unsigned char)pszEnd[-1]))
226 pszEnd--;
227 if (pszEnd > psz)
228 {
229 char chSaved = *pszEnd;
230 *pszEnd = '\0';
231 if (!strchr(pszEnd, '$'))
232 pVar = define_variable(pszVarName, strlen(pszVarName), psz, o_file, 0 /* !recursive */);
233 else
234 {
235 /* needs expanding and stripping. */
236 char *pszFree;
237 char *pszExp = pszFree = allocated_variable_expand(psz);
238 char *pszExpEnd = strchr(pszExp, '\0');
239 while (isblank((unsigned char)*pszExp))
240 pszExp++;
241 while (pszExpEnd > pszExp && isblank((unsigned char)pszExpEnd[-1]))
242 pszExpEnd--;
243 if (pszExpEnd > pszExp)
244 {
245 *pszExpEnd = '\0';
246 pVar = define_variable(pszVarName, strlen(pszVarName), pszExp, o_file, 0 /* !recursive */);
247 }
248 else
249 pVar = NULL;
250 free(pszFree);
251 }
252 *pszEnd = chSaved;
253 if (pVar)
254 return pVar;
255 }
256 }
257
258 fatal(NILF, _("no tool for source `%s' in target `%s'!"), pSource->value, pTarget->value);
259 return NULL;
260}
261
262/* Implements _SOURCE_TOOL. */
263char *
264func_kbuild_source_tool(char *o, char **argv, const char *pszFuncName)
265{
266 struct variable *pVar = kbuild_get_source_tool(kbuild_get_variable("target"),
267 kbuild_get_variable("source"),
268 kbuild_get_variable("type"),
269 kbuild_get_variable("bld_trg"),
270 kbuild_get_variable("bld_trg_arch"),
271 argv[0]);
272 if (pVar)
273 o = variable_buffer_output(o, pVar->value, pVar->value_length);
274 return o;
275
276}
277
278/*
279## Figure out where to put object files.
280# @param $1 source file
281# @param $2 normalized main target
282# @remark There are two major hacks here:
283# 1. Source files in the output directory are translated into a gen/ subdir.
284# 2. Catch anyone specifying $(PATH_SUB_CURRENT)/sourcefile.c.
285_OBJECT_BASE = $(PATH_TARGET)/$(2)/$(call no-root-slash,$(call no-drive,$(basename \
286 $(patsubst $(PATH_ROOT)/%,%,$(patsubst $(PATH_SUB_CURRENT)/%,%,$(patsubst $(PATH_TARGET)/$(2)/%,gen/%,$(1)))))))
287*/
288static struct variable *
289kbuild_get_object_base(struct variable *pTarget, struct variable *pSource, const char *pszVarName)
290{
291 struct variable *pPathTarget = kbuild_get_variable("PATH_TARGET");
292 struct variable *pPathRoot = kbuild_get_variable("PATH_ROOT");
293 struct variable *pPathSubCur = kbuild_get_variable("PATH_SUB_CURRENT");
294 const char *pszSrcPrefix = NULL;
295 const char *pszSrcEnd;
296 char *pszSrc;
297 char *pszResult;
298 char *psz;
299 size_t cch;
300
301 /*
302 * Strip the source filename of any uncessary leading path and root specs.
303 */
304 /* */
305 if ( pSource->value_length > pPathTarget->value_length
306 && !strncmp(pSource->value, pPathTarget->value, pPathTarget->value_length))
307 {
308 pszSrc = pSource->value + pPathTarget->value_length;
309 pszSrcPrefix = "gen/";
310 }
311 else if ( pSource->value_length > pPathRoot->value_length
312 && !strncmp(pSource->value, pPathRoot->value, pPathRoot->value_length))
313 {
314 pszSrc = pSource->value + pPathRoot->value_length;
315 if ( *pszSrc == '/'
316 && !strncmp(pszSrc, pPathSubCur->value, pPathSubCur->value_length))
317 pszSrc += 1 + pPathSubCur->value_length;
318 }
319 else
320 pszSrc = pSource->value;
321
322 /* skip root specification */
323#ifdef HAVE_DOS_PATHS
324 if (isalpha(pszSrc[0]) && pszSrc[1] == ':')
325 pszSrc += 2;
326#endif
327 while (*pszSrc == '/'
328#ifdef HAVE_DOS_PATHS
329 || *pszSrc == '\\'
330#endif
331 )
332 pszSrc++;
333
334 /* drop the source extension. */
335 pszSrcEnd = pSource->value + pSource->value_length;
336 for (;;)
337 {
338 pszSrcEnd--;
339 if ( pszSrcEnd <= pszSrc
340 || *pszSrcEnd == '/'
341#ifdef HAVE_DOS_PATHS
342 || *pszSrcEnd == '\\'
343 || *pszSrcEnd == ':'
344#endif
345 )
346 {
347 pszSrcEnd = pSource->value + pSource->value_length;
348 break;
349 }
350 if (*pszSrcEnd == '.')
351 break;
352 }
353
354 /*
355 * Assemble the string on the stack and define the objbase variable
356 * which we then return.
357 */
358 cch = pPathTarget->value_length
359 + 1 /* slash */
360 + pTarget->value_length
361 + 1 /* slash */
362 + pszSrcEnd - pszSrc
363 + 1;
364 psz = pszResult = alloca(cch);
365
366 memcpy(psz, pPathTarget->value, pPathTarget->value_length); psz += pPathTarget->value_length;
367 *psz++ = '/';
368 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
369 *psz++ = '/';
370 memcpy(psz, pszSrc, pszSrcEnd - pszSrc); psz += pszSrcEnd - pszSrc;
371 *psz = '\0';
372
373 /*
374 * Define the variable in the current set and return it.
375 */
376 return define_variable(pszVarName, strlen(pszVarName), pszResult, o_file, 0 /* !recursive */);
377}
378
379/* Implements _OBJECT_BASE. */
380char *
381func_kbuild_object_base(char *o, char **argv, const char *pszFuncName)
382{
383 struct variable *pVar = kbuild_get_object_base(kbuild_lookup_variable("target"),
384 kbuild_lookup_variable("source"),
385 argv[0]);
386 if (pVar)
387 o = variable_buffer_output(o, pVar->value, pVar->value_length);
388 return o;
389
390}
391
392
393/*
394$(firstword \
395 $($(target)_$(source)_OBJSUFF.$(bld_trg).$(bld_trg_arch))\
396 $($(target)_$(source)_OBJSUFF.$(bld_trg))\
397 $($(target)_$(source)_OBJSUFF)\
398 $($(source)_OBJSUFF.$(bld_trg).$(bld_trg_arch))\
399 $($(source)_OBJSUFF.$(bld_trg))\
400 $($(source)_OBJSUFF)\
401 $($(target)_OBJSUFF.$(bld_trg).$(bld_trg_arch))\
402 $($(target)_OBJSUFF.$(bld_trg))\
403 $($(target)_OBJSUFF)\
404 $(TOOL_$(tool)_$(type)OBJSUFF.$(bld_trg).$(bld_trg_arch))\
405 $(TOOL_$(tool)_$(type)OBJSUFF.$(bld_trg))\
406 $(TOOL_$(tool)_$(type)OBJSUFF)\
407 $(SUFF_OBJ))
408*/
409static struct variable *
410kbuild_get_object_suffix(struct variable *pTarget, struct variable *pSource,
411 struct variable *pBldTrg, struct variable *pBldTrgArch,
412 const char *pszVarName)
413{
414 /** @todo ignore variables without content. Can generalize this and join with the tool getter. */
415 struct variable *pVar;
416 if ( (pVar = kbuild_lookup_variable_fmt("%_%_OBJSUFF_.%.%", pTarget, pSource, pBldTrg, pBldTrgArch))
417 || (pVar = kbuild_lookup_variable_fmt("%_%_OBJSUFF_.%", pTarget, pSource, pBldTrg))
418 || (pVar = kbuild_lookup_variable_fmt("%_%_OBJSUFF", pTarget, pSource))
419 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF_.%.%", pSource, pBldTrg, pBldTrgArch))
420 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF_.%", pSource, pBldTrg))
421 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF", pSource))
422 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF_.%.%", pTarget, pBldTrg, pBldTrgArch))
423 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF_.%", pTarget, pBldTrg))
424 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF", pTarget))
425 || (pVar = kbuild_lookup_variable_fmt("OBJSUFF.%.%", pBldTrg, pBldTrgArch))
426 || (pVar = kbuild_lookup_variable_fmt("OBJSUFF.%", pBldTrg))
427 || (pVar = kbuild_lookup_variable("SUFF_OBJ"))
428 )
429 {
430 /* strip it */
431 char *psz = pVar->value;
432 char *pszEnd = psz + pVar->value_length;
433 while (isblank((unsigned char)*psz))
434 psz++;
435 while (pszEnd > psz && isblank((unsigned char)pszEnd[-1]))
436 pszEnd--;
437 if (pszEnd > psz)
438 {
439 char chSaved = *pszEnd;
440 *pszEnd = '\0';
441 if (!strchr(pszEnd, '$'))
442 pVar = define_variable(pszVarName, strlen(pszVarName), psz, o_file, 0 /* !recursive */);
443 else
444 {
445 /* needs expanding and stripping. */
446 char *pszFree;
447 char *pszExp = pszFree = allocated_variable_expand(psz);
448 char *pszExpEnd = strchr(pszExp, '\0');
449 while (isblank((unsigned char)*pszExp))
450 pszExp++;
451 while (pszExpEnd > pszExp && isblank((unsigned char)pszExpEnd[-1]))
452 pszExpEnd--;
453 if (pszExpEnd > pszExp)
454 {
455 *pszExpEnd = '\0';
456 pVar = define_variable(pszVarName, strlen(pszVarName), pszExp, o_file, 0 /* !recursive */);
457 }
458 else
459 pVar = NULL;
460 free(pszFree);
461 }
462 *pszEnd = chSaved;
463 if (pVar)
464 return pVar;
465 }
466 }
467
468 fatal(NILF, _("no tool for source `%s' in target `%s'!"), pSource->value, pTarget->value);
469 return NULL;
470}
471
472/* */
473char *
474func_kbuild_object_suffix(char *o, char **argv, const char *pszFuncName)
475{
476 struct variable *pVar = kbuild_get_object_suffix(kbuild_get_variable("target"),
477 kbuild_get_variable("source"),
478 kbuild_get_variable("bld_trg"),
479 kbuild_get_variable("bld_trg_arch"),
480 argv[0]);
481 if (pVar)
482 o = variable_buffer_output(o, pVar->value, pVar->value_length);
483 return o;
484
485}
486
487
488
489
490struct kbuild_sdks
491{
492 char *apsz[4];
493 struct variable *pa;
494 unsigned c;
495 unsigned iGlobal;
496 unsigned cGlobal;
497 unsigned iTarget;
498 unsigned cTarget;
499 unsigned iSource;
500 unsigned cSource;
501 unsigned iTargetSource;
502 unsigned cTargetSource;
503};
504
505/* Fills in the SDK struct (remember to free it). */
506static void
507kbuild_get_sdks(struct kbuild_sdks *pSdks, struct variable *pTarget, struct variable *pSource,
508 struct variable *pBldType, struct variable *pBldTrg, struct variable *pBldTrgArch)
509{
510 int i, j;
511 size_t cchTmp;
512 char *pszTmp;
513 unsigned cchCur;
514 char *pszCur;
515 char *pszIterator;
516
517 /* basic init. */
518 pSdks->pa = NULL;
519 pSdks->c = 0;
520 i = 0;
521
522 /* determin required tmp variable name space. */
523 cchTmp = ( pTarget->value_length + 1
524 + pSource->value_length + 6
525 + pBldTrg->value_length + 1
526 + pBldTrgArch->value_length + 4) * 4;
527 pszTmp = alloca(cchTmp);
528
529
530 /* the global sdks. */
531 pSdks->iGlobal = i;
532 pSdks->cGlobal = 0;
533 sprintf(pszTmp, "$(SDKS) $(SDKS.%s) $(SDKS.%s) $(SDKS.%s.%s)",
534 pBldType->value, pBldTrg->value, pBldTrg->value, pBldTrgArch->value);
535 pszIterator = pSdks->apsz[0] = allocated_variable_expand(pszTmp);
536 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
537 pSdks->cGlobal++;
538 i += pSdks->cGlobal;
539
540 /* the target sdks.*/
541 pSdks->iTarget = i;
542 pSdks->cTarget = 0;
543 sprintf(pszTmp, "$(%s_SDKS) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s.%s)",
544 pTarget->value, pBldType->value,
545 pTarget->value, pBldTrg->value,
546 pTarget->value, pBldTrg->value,
547 pTarget->value, pBldTrgArch->value);
548 pszIterator = pSdks->apsz[1] = allocated_variable_expand(pszTmp);
549 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
550 pSdks->cTarget++;
551 i += pSdks->cTarget;
552
553 /* the source sdks.*/
554 pSdks->iSource = i;
555 pSdks->cSource = 0;
556 sprintf(pszTmp, "$(%s_SDKS) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s.%s)",
557 pSource->value, pBldType->value,
558 pSource->value, pBldTrg->value,
559 pSource->value, pBldTrg->value,
560 pSource->value, pBldTrgArch->value);
561 pszIterator = pSdks->apsz[2] = allocated_variable_expand(pszTmp);
562 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
563 pSdks->cSource++;
564 i += pSdks->cSource;
565
566 /* the target + source sdks. */
567 pSdks->iTargetSource = i;
568 pSdks->cTargetSource = 0;
569 sprintf(pszTmp, "$(%s_%s_SDKS) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s.%s)",
570 pTarget->value, pSource->value, pBldType->value,
571 pTarget->value, pSource->value, pBldTrg->value,
572 pTarget->value, pSource->value, pBldTrg->value,
573 pTarget->value, pSource->value, pBldTrgArch->value);
574 pszIterator = pSdks->apsz[3] = allocated_variable_expand(pszTmp);
575 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
576 pSdks->cTargetSource++;
577 i += pSdks->cTargetSource;
578
579 pSdks->c = i;
580 if (!i)
581 return;
582
583 /*
584 * Allocate the variable array and create the variables.
585 */
586 pSdks->pa = (struct variable *)xmalloc(sizeof(pSdks->pa[0]) * i);
587 memset(pSdks->pa, 0, sizeof(pSdks->pa[0]) * i);
588 for (i = j = 0; j < sizeof(pSdks->apsz) / sizeof(pSdks->apsz[0]); j++)
589 {
590 pszIterator = pSdks->apsz[j];
591 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
592 {
593 pSdks->pa[i].value = pszCur;
594 pSdks->pa[i].value_length = cchCur;
595 pszCur[cchCur] = '\0';
596 }
597 }
598}
599
600/* releases resources allocated in the kbuild_get_sdks. */
601kbuild_put_sdks(struct kbuild_sdks *pSdks)
602{
603 unsigned j;
604 for (j = 0; j < sizeof(pSdks->apsz) / sizeof(pSdks->apsz[0]); j++)
605 free(pSdks->apsz[j]);
606 free(pSdks->pa);
607}
608
609/* this kind of stuff:
610
611defs := $(kb-src-exp defs)
612 $(TOOL_$(tool)_DEFS)\
613 $(TOOL_$(tool)_DEFS.$(bld_type))\
614 $(TOOL_$(tool)_DEFS.$(bld_trg))\
615 $(TOOL_$(tool)_DEFS.$(bld_trg_arch))\
616 $(TOOL_$(tool)_DEFS.$(bld_trg).$(bld_trg_arch))\
617 $(TOOL_$(tool)_DEFS.$(bld_trg_cpu))\
618 $(TOOL_$(tool)_$(type)DEFS)\
619 $(TOOL_$(tool)_$(type)DEFS.$(bld_type))\
620 $(foreach sdk, $(SDKS.$(bld_trg)) \
621 $(SDKS.$(bld_trg).$(bld_trg_arch)) \
622 $(SDKS.$(bld_type)) \
623 $(SDKS),\
624 $(SDK_$(sdk)_DEFS)\
625 $(SDK_$(sdk)_DEFS.$(bld_type))\
626 $(SDK_$(sdk)_DEFS.$(bld_trg))\
627 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
628 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
629 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
630 $(SDK_$(sdk)_$(type)DEFS)\
631 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
632 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
633 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
634 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
635 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
636 $(DEFS)\
637 $(DEFS.$(bld_type))\
638 $(DEFS.$(bld_trg))\
639 $(DEFS.$(bld_trg_arch))\
640 $(DEFS.$(bld_trg).$(bld_trg_arch))\
641 $(DEFS.$(bld_trg_cpu))\
642 $($(type)DEFS)\
643 $($(type)DEFS.$(bld_type))\
644 $($(type)DEFS.$(bld_trg))\
645 $($(type)DEFS.$(bld_trg_arch))\
646 $($(type)DEFS.$(bld_trg).$(bld_trg_arch))\
647 $($(type)DEFS.$(bld_trg_cpu))\
648 $(foreach sdk, $($(target)_SDKS.$(bld_trg)) \
649 $($(target)_SDKS.$(bld_trg).$(bld_trg_arch)) \
650 $($(target)_SDKS.$(bld_type)) \
651 $($(target)_SDKS),\
652 $(SDK_$(sdk)_DEFS)\
653 $(SDK_$(sdk)_DEFS.$(bld_type))\
654 $(SDK_$(sdk)_DEFS.$(bld_trg))\
655 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
656 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
657 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
658 $(SDK_$(sdk)_$(type)DEFS)\
659 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
660 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
661 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
662 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
663 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
664 $($(target)_DEFS)\
665 $($(target)_DEFS.$(bld_type))\
666 $($(target)_DEFS.$(bld_trg))\
667 $($(target)_DEFS.$(bld_trg_arch))\
668 $($(target)_DEFS.$(bld_trg).$(bld_trg_arch))\
669 $($(target)_DEFS.$(bld_trg_cpu))\
670 $($(target)_$(type)DEFS)\
671 $($(target)_$(type)DEFS.$(bld_type))\
672 $($(target)_$(type)DEFS.$(bld_trg))\
673 $($(target)_$(type)DEFS.$(bld_trg_arch))\
674 $($(target)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
675 $($(target)_$(type)DEFS.$(bld_trg_cpu))\
676 $(foreach sdk, $($(source)_SDKS.$(bld_trg)) \
677 $($(source)_SDKS.$(bld_trg).$(bld_trg_arch)) \
678 $($(source)_SDKS.$(bld_type)) \
679 $($(source)_SDKS),\
680 $(SDK_$(sdk)_DEFS)\
681 $(SDK_$(sdk)_DEFS.$(bld_type))\
682 $(SDK_$(sdk)_DEFS.$(bld_trg))\
683 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
684 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
685 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
686 $(SDK_$(sdk)_$(type)DEFS)\
687 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
688 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
689 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
690 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
691 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
692 $($(source)_DEFS)\
693 $($(source)_DEFS.$(bld_type))\
694 $($(source)_DEFS.$(bld_trg))\
695 $($(source)_DEFS.$(bld_trg_arch))\
696 $($(source)_DEFS.$(bld_trg).$(bld_trg_arch))\
697 $($(source)_DEFS.$(bld_trg_cpu))\
698 $($(source)_$(type)DEFS)\
699 $($(source)_$(type)DEFS.$(bld_type))\
700 $($(source)_$(type)DEFS.$(bld_trg))\
701 $($(source)_$(type)DEFS.$(bld_trg_arch))\
702 $($(source)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
703 $($(source)_$(type)DEFS.$(bld_trg_cpu))\
704 $(foreach sdk, $($(target)_$(source)_SDKS.$(bld_trg)) \
705 $($(target)_$(source)_SDKS.$(bld_trg).$(bld_trg_arch)) \
706 $($(target)_$(source)_SDKS.$(bld_type)) \
707 $($(target)_$(source)_SDKS),\
708 $(SDK_$(sdk)_DEFS)\
709 $(SDK_$(sdk)_DEFS.$(bld_type))\
710 $(SDK_$(sdk)_DEFS.$(bld_trg))\
711 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
712 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
713 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
714 $(SDK_$(sdk)_$(type)DEFS)\
715 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
716 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
717 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
718 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
719 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
720 $($(target)_$(source)_DEFS)\
721 $($(target)_$(source)_DEFS.$(bld_type))\
722 $($(target)_$(source)_DEFS.$(bld_trg))\
723 $($(target)_$(source)_DEFS.$(bld_trg_arch))\
724 $($(target)_$(source)_DEFS.$(bld_trg).$(bld_trg_arch))\
725 $($(target)_$(source)_DEFS.$(bld_trg_cpu))\
726 $($(target)_$(source)_$(type)DEFS)\
727 $($(target)_$(source)_$(type)DEFS.$(bld_type))\
728 $($(target)_$(source)_$(type)DEFS.$(bld_trg))\
729 $($(target)_$(source)_$(type)DEFS.$(bld_trg_arch))\
730 $($(target)_$(source)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
731 $($(target)_$(source)_$(type)DEFS.$(bld_trg_cpu))
732*/
733static struct variable *
734kbuild_collect_source_prop(struct variable *pTarget, struct variable *pSource,
735 struct variable *pTool, struct kbuild_sdks *pSdks,
736 struct variable *pType, struct variable *pBldType,
737 struct variable *pBldTrg, struct variable *pBldTrgArch, struct variable *pBldTrgCpu,
738 const char *pszProp, const char *pszVarName, int iDirection)
739{
740 struct variable *pVar;
741 unsigned iSdk;
742 int cVars, iVar, iVarEnd;
743 size_t cchTotal;
744 char *pszResult, *psz;
745 struct
746 {
747 struct variable *pVar;
748 size_t cchExp;
749 char *pszExp;
750 } *paVars;
751
752 struct variable Prop = {0};
753 Prop.value = (char *)pszProp;
754 Prop.value_length = strlen(pszProp);
755
756 /*
757 * Get the variables.
758 */
759 cVars = 12 + (pSdks->c + 1) * 12 * 4;
760 paVars = alloca(cVars * sizeof(paVars[0]));
761
762 iVar = 0;
763 /* the tool (lowest priority) */
764 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%", pTool, &Prop);
765 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldType);
766 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldTrg);
767 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldTrgArch);
768 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%.%", pTool, &Prop, pBldTrg, pBldTrgArch);
769 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldTrgCpu);
770
771 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%", pTool, pType, &Prop);
772 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldType);
773 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldTrg);
774 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldTrgArch);
775 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%.%", pTool, pType, &Prop, pBldTrg, pBldTrgArch);
776 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldTrgCpu);
777
778 /* the global sdks */
779 for (iSdk = pSdks->iGlobal; iSdk < pSdks->cGlobal; iSdk++)
780 {
781 struct variable *pSdk = &pSdks->pa[iSdk];
782 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
783 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
784 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
785 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
786 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
787 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
788
789 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
790 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
791 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
792 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
793 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
794 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
795 }
796
797 /* the globals */
798 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%", &Prop);
799 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldType);
800 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldTrg);
801 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldTrgArch);
802 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%.%", &Prop, pBldTrg, pBldTrgArch);
803 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldTrgCpu);
804
805 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%", pType, &Prop);
806 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldType);
807 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldTrg);
808 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldTrgArch);
809 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%.%", pType, &Prop, pBldTrg, pBldTrgArch);
810 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldTrgCpu);
811
812 /* the target sdks */
813 for (iSdk = pSdks->iTarget; iSdk < pSdks->cTarget; iSdk++)
814 {
815 struct variable *pSdk = &pSdks->pa[iSdk];
816 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
817 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
818 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
819 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
820 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
821 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
822
823 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
824 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
825 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
826 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
827 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
828 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
829 }
830
831 /* the target */
832 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%", pTarget, &Prop);
833 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldType);
834 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldTrg);
835 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldTrgArch);
836 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%.%", pTarget, &Prop, pBldTrg, pBldTrgArch);
837 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldTrgCpu);
838
839 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%", pTarget, pType, &Prop);
840 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldType);
841 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldTrg);
842 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldTrgArch);
843 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%.%", pTarget, pType, &Prop, pBldTrg, pBldTrgArch);
844 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldTrgCpu);
845
846 /* the source sdks */
847 for (iSdk = pSdks->iSource; iSdk < pSdks->cSource; iSdk++)
848 {
849 struct variable *pSdk = &pSdks->pa[iSdk];
850 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
851 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
852 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
853 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
854 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
855 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
856
857 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
858 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
859 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
860 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
861 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
862 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
863 }
864
865 /* the source */
866 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%", pSource, &Prop);
867 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldType);
868 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldTrg);
869 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldTrgArch);
870 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%.%", pSource, &Prop, pBldTrg, pBldTrgArch);
871 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldTrgCpu);
872
873 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%", pSource, pType, &Prop);
874 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldType);
875 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldTrg);
876 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldTrgArch);
877 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%.%", pSource, pType, &Prop, pBldTrg, pBldTrgArch);
878 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldTrgCpu);
879
880
881 /* the target + source sdks */
882 for (iSdk = pSdks->iTargetSource; iSdk < pSdks->cTargetSource; iSdk++)
883 {
884 struct variable *pSdk = &pSdks->pa[iSdk];
885 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
886 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
887 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
888 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
889 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
890 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
891
892 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
893 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
894 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
895 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
896 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
897 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
898 }
899
900 /* the target + source */
901 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%", pTarget, pSource, &Prop);
902 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldType);
903 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldTrg);
904 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldTrgArch);
905 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%.%", pTarget, pSource, &Prop, pBldTrg, pBldTrgArch);
906 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldTrgCpu);
907
908 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%", pTarget, pSource, pType, &Prop);
909 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldType);
910 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrg);
911 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrgArch);
912 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%.%", pTarget, pSource, pType, &Prop, pBldTrg, pBldTrgArch);
913 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrgCpu);
914
915 assert(cVars == iVar);
916
917 /*
918 * Expand the variables and calculate the total length.
919 */
920 cchTotal = 0;
921 iVarEnd = iDirection > -1 ? cVars : 0;
922 for (iVar = iDirection > 0 ? 0 : cVars - 1; iVar != iVarEnd; iVar += iDirection)
923 {
924 paVars[iVar].cchExp = 0;
925 if (!paVars[iVar].pVar)
926 continue;
927 if ( paVars[iVar].pVar->flavor == f_simple
928 || !strchr(paVars[iVar].pVar->value, '$'))
929 {
930 paVars[iVar].pszExp = paVars[iVar].pVar->value;
931 paVars[iVar].cchExp = paVars[iVar].pVar->value_length;
932 }
933 else
934 {
935 paVars[iVar].pszExp = allocated_variable_expand(paVars[iVar].pVar->value);
936 paVars[iVar].cchExp = strlen(paVars[iVar].pszExp);
937 }
938 cchTotal += paVars[iVar].cchExp + 1;
939 }
940
941 /*
942 * Construct the result value.
943 */
944 psz = pszResult = xmalloc(cchTotal + 1);
945 iVarEnd = iDirection > -1 ? cVars : 0;
946 for (iVar = iDirection > 0 ? 0 : cVars - 1; iVar != iVarEnd; iVar += iDirection)
947 {
948 if (!paVars[iVar].cchExp)
949 continue;
950 memcpy(psz, paVars[iVar].pszExp, paVars[iVar].cchExp);
951 psz += paVars[iVar].cchExp;
952 *psz++ = ' ';
953 if (paVars[iVar].pszExp != paVars[iVar].pVar->value)
954 free(paVars[iVar].pszExp);
955 }
956 psz[-(cchTotal != 0)] = '\0';
957
958 pVar = define_variable(pszVarName, strlen(pszVarName), pszResult, o_file, 0 /* !recursive */);
959 free(pszResult);
960 return pVar;
961}
962
963/* get a source property. */
964char *
965func_kbuild_source_prop(char *o, char **argv, const char *pszFuncName)
966{
967 struct variable *pTarget = kbuild_get_variable("target");
968 struct variable *pSource = kbuild_get_variable("source");
969 struct variable *pType = kbuild_get_variable("type");
970 struct variable *pTool = kbuild_get_variable("tool");
971 struct variable *pBldType = kbuild_get_variable("bld_type");
972 struct variable *pBldTrg = kbuild_get_variable("bld_trg");
973 struct variable *pBldTrgArch = kbuild_get_variable("bld_trg_arch");
974 struct variable *pBldTrgCpu = kbuild_get_variable("bld_trg_cpu");
975 struct variable *pVar;
976 struct kbuild_sdks Sdks;
977 int iDirection;
978 if (!strcmp(argv[2], "left-to-right"))
979 iDirection = 1;
980 else if (!strcmp(argv[2], "right-to-left"))
981 iDirection = 1;
982 else
983 fatal(NILF, _("incorrect direction argument `%s'!"), argv[2]);
984
985 kbuild_get_sdks(&Sdks, pTarget, pSource, pBldType, pBldTrg, pBldTrgArch);
986
987 pVar = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType,
988 pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
989 argv[0], argv[1], iDirection);
990 if (pVar)
991 o = variable_buffer_output(o, pVar->value, pVar->value_length);
992
993 kbuild_put_sdks(&Sdks);
994 return o;
995
996}
997
998/*
999dep := $(obj)$(SUFF_DEP)
1000obj := $(outbase)$(objsuff)
1001dirdep := $(call DIRDEP,$(dir $(outbase)))
1002PATH_$(target)_$(source) := $(patsubst %/,%,$(dir $(outbase)))
1003*/
1004static struct variable *
1005kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(struct variable *pTarget, struct variable *pSource,
1006 struct variable *pOutBase, struct variable *pObjSuff,
1007 const char *pszVarName, struct variable **ppDep,
1008 struct variable **ppDirDep)
1009{
1010 struct variable *pDepSuff = kbuild_get_variable("SUFF_DEP");
1011 struct variable *pObj;
1012 size_t cch = pOutBase->value_length + pObjSuff->value_length + pDepSuff->value_length + 1;
1013 char *pszResult = alloca(cch);
1014 char *pszName, *psz;
1015
1016 /*
1017 * dep.
1018 */
1019 psz = pszResult;
1020 memcpy(psz, pOutBase->value, pOutBase->value_length); psz += pOutBase->value_length;
1021 memcpy(psz, pObjSuff->value, pObjSuff->value_length); psz += pObjSuff->value_length;
1022 memcpy(psz, pDepSuff->value, pDepSuff->value_length + 1);
1023 *ppDep = define_variable("dep", 3, pszResult, o_file, 0 /* !recursive */);
1024
1025 /*
1026 * obj
1027 */
1028 *psz = '\0';
1029 pObj = define_variable(pszVarName, strlen(pszVarName), pszResult, o_file, 0 /* !recursive */);
1030
1031 /*
1032 * PATH_$(target)_$(source) - this is global!
1033 */
1034 /* calc variable name. */
1035 cch = pTarget->value_length + pSource->value_length + 7;
1036 psz = pszName = alloca(cch + 1);
1037 memcpy(psz, "PATH_", sizeof("PATH_") - 1); psz += sizeof("PATH_") - 1;
1038 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
1039 *psz++ = '_';
1040 memcpy(psz, pSource->value, pSource->value_length + 1);
1041
1042 /* strip off the filename. */
1043 psz = pszResult + pOutBase->value_length;
1044 for (;;)
1045 {
1046 psz--;
1047 if (psz <= pszResult)
1048 fatal(NULL, "whut!?! no path? result=`%s'", pszResult);
1049#ifdef HAVE_DOS_PATHS
1050 if (*psz == ':')
1051 {
1052 psz++;
1053 break;
1054 }
1055#endif
1056 if ( *psz == '/'
1057#ifdef HAVE_DOS_PATHS
1058 || *psz == '\\'
1059#endif
1060 )
1061 {
1062 while ( psz - 1 > pszResult
1063 && psz[-1] == '/'
1064#ifdef HAVE_DOS_PATHS
1065 || psz[-1] == '\\'
1066#endif
1067 )
1068 psz--;
1069#ifdef HAVE_DOS_PATHS
1070 if (psz == pszResult + 2 && pszResult[1] == ':')
1071 psz++;
1072#endif
1073 break;
1074 }
1075 }
1076 *psz = '\0';
1077
1078 /* set global variable */
1079 define_variable_global(pszName, cch, pszResult, o_file, 0 /* !recursive */, NILF);
1080
1081 /*
1082 * dirdep
1083 */
1084 if ( psz[-1] != '/'
1085#ifdef HAVE_DOS_PATHS
1086 && psz[-1] != '\\'
1087 && psz[-1] != ':'
1088#endif
1089 )
1090 {
1091 *psz++ = '/';
1092 *psz = '\0';
1093 }
1094 *ppDirDep = define_variable("dirdep", 6, pszResult, o_file, 0 /* !recursive */);
1095
1096 return pObj;
1097}
1098
1099
1100/* setup the base variables for def_target_source_c_cpp_asm_new:
1101
1102X := $(kb-src-tool tool)
1103x := $(kb-obj-base outbase)
1104x := $(kb-obj-suff objsuff)
1105obj := $(outbase)$(objsuff)
1106PATH_$(target)_$(source) := $(patsubst %/,%,$(dir $(outbase)))
1107
1108x := $(kb-src-prop DEFS,defs,left-to-right)
1109x := $(kb-src-prop INCS,incs,right-to-left)
1110x := $(kb-src-prop FLAGS,flags,right-to-left)
1111
1112x := $(kb-src-prop DEPS,deps,left-to-right)
1113dirdep := $(call DIRDEP,$(dir $(outbase)))
1114dep := $(obj)$(SUFF_DEP)
1115*/
1116char *
1117func_kbuild_source_one(char *o, char **argv, const char *pszFuncName)
1118{
1119 static int s_fNoCompileCmdsDepsDefined = -1;
1120 struct variable *pTarget = kbuild_get_variable("target");
1121 struct variable *pSource = kbuild_get_variable("source");
1122 struct variable *pType = kbuild_get_variable("type");
1123 struct variable *pBldType = kbuild_get_variable("bld_type");
1124 struct variable *pBldTrg = kbuild_get_variable("bld_trg");
1125 struct variable *pBldTrgArch= kbuild_get_variable("bld_trg_arch");
1126 struct variable *pBldTrgCpu = kbuild_get_variable("bld_trg_cpu");
1127 struct variable *pTool = kbuild_get_source_tool(pTarget, pSource, pType, pBldTrg, pBldTrgArch, "tool");
1128 struct variable *pOutBase = kbuild_get_object_base(pTarget, pSource, "outbase");
1129 struct variable *pObjSuff = kbuild_get_object_suffix(pTarget, pSource, pBldTrg, pBldTrgArch, "objsuff");
1130 struct variable *pDefs, *pIncs, *pFlags, *pDeps, *pDirDep, *pDep, *pVar, *pOutput;
1131 struct variable *pObj = kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(pTarget, pSource, pOutBase, pObjSuff, "obj", &pDep, &pDirDep);
1132 char *pszDstVar, *pszDst, *pszSrcVar, *pszSrc, *pszVal, *psz;
1133 char *pszSavedVarBuf;
1134 unsigned cchSavedVarBuf;
1135 size_t cch;
1136 struct kbuild_sdks Sdks;
1137 kbuild_get_sdks(&Sdks, pTarget, pSource, pBldType, pBldTrg, pBldTrgArch);
1138
1139 pDefs = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1140 "DEFS", "defs", 1/* left-to-right */);
1141 pIncs = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1142 "INCS", "incs", 1/* right-to-left */);
1143 pFlags = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1144 "FLAGS", "flags", 1/* right-to-left */);
1145 pDeps = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1146 "DEPS", "deps", 1/* left-to-right */);
1147
1148 /*
1149 # dependencies
1150 ifndef NO_COMPILE_CMDS_DEPS
1151 _DEPFILES_INCLUDED += $(dep)
1152 $(if $(wildcard $(dep)),$(eval include $(dep)))
1153 endif
1154 */
1155 if (s_fNoCompileCmdsDepsDefined == -1)
1156 s_fNoCompileCmdsDepsDefined = kbuild_lookup_variable("NO_COMPILE_CMDS_DEPS") != NULL;
1157 if (!s_fNoCompileCmdsDepsDefined)
1158 {
1159 do_variable_definition(NILF, "_DEPFILES_INCLUDED", pDep->value, o_file, f_append, 0 /* !target_var */);
1160 eval_include_dep(pDep->value, NILF);
1161 }
1162
1163 /*
1164 # call the tool
1165 $(target)_$(source)_CMDS_ := $(TOOL_$(tool)_COMPILE_$(type)_CMDS)
1166 $(target)_$(source)_OUTPUT_ := $(TOOL_$(tool)_COMPILE_$(type)_OUTPUT)
1167 $(target)_$(source)_DEPEND_ := $(TOOL_$(tool)_COMPILE_$(type)_DEPEND) $(deps) $(source)
1168 $(target)_$(source)_DEPORD_ := $(TOOL_$(tool)_COMPILE_$(type)_DEPORD) $(dirdep)
1169 */
1170 cch = sizeof("TOOL_") + pTool->value_length + sizeof("_COMPILE_") + pType->value_length + sizeof("_OUTPUT");
1171 psz = pszSrcVar = alloca(cch);
1172 memcpy(psz, "TOOL_", sizeof("TOOL_") - 1); psz += sizeof("TOOL_") - 1;
1173 memcpy(psz, pTool->value, pTool->value_length); psz += pTool->value_length;
1174 memcpy(psz, "_COMPILE_", sizeof("_COMPILE_") - 1); psz += sizeof("_COMPILE_") - 1;
1175 memcpy(psz, pType->value, pType->value_length); psz += pType->value_length;
1176 pszSrc = psz;
1177
1178 cch = pTarget->value_length + 1 + pSource->value_length + sizeof("_OUTPUT_");
1179 psz = pszDstVar = alloca(cch);
1180 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
1181 *psz++ = '_';
1182 memcpy(psz, pSource->value, pSource->value_length); psz += pSource->value_length;
1183 pszDst = psz;
1184
1185 memcpy(pszSrc, "_CMDS", sizeof("_CMDS"));
1186 memcpy(pszDst, "_CMDS_", sizeof("_CMDS_"));
1187 pVar = kbuild_get_recursive_variable(pszSrcVar);
1188 do_variable_definition(NILF, pszDstVar, pVar->value, o_file, f_simple, 0 /* !target_var */);
1189
1190 memcpy(pszSrc, "_OUTPUT", sizeof("_OUTPUT"));
1191 memcpy(pszDst, "_OUTPUT_", sizeof("_OUTPUT_"));
1192 pVar = kbuild_get_recursive_variable(pszSrcVar);
1193 pOutput = do_variable_definition(NILF, pszDstVar, pVar->value, o_file, f_simple, 0 /* !target_var */);
1194
1195 memcpy(pszSrc, "_DEPEND", sizeof("_DEPEND"));
1196 memcpy(pszDst, "_DEPEND_", sizeof("_DEPEND_"));
1197 pVar = kbuild_get_recursive_variable(pszSrcVar);
1198 psz = pszVal = xmalloc(pVar->value_length + 1 + pDeps->value_length + 1 + pSource->value_length + 1);
1199 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1200 *psz++ = ' ';
1201 memcpy(psz, pDeps->value, pDeps->value_length); psz += pDeps->value_length;
1202 *psz++ = ' ';
1203 memcpy(psz, pSource->value, pSource->value_length + 1);
1204 do_variable_definition(NILF, pszDstVar, pszVal, o_file, f_simple, 0 /* !target_var */);
1205 free(pszVal);
1206
1207 memcpy(pszSrc, "_DEPORD", sizeof("_DEPORD"));
1208 memcpy(pszDst, "_DEPORD_", sizeof("_DEPORD_"));
1209 pVar = kbuild_get_recursive_variable(pszSrcVar);
1210 psz = pszVal = xmalloc(pVar->value_length + 1 + pDirDep->value_length + 1);
1211 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1212 *psz++ = ' ';
1213 memcpy(psz, pDirDep->value, pDirDep->value_length + 1);
1214 do_variable_definition(NILF, pszDstVar, pszVal, o_file, f_simple, 0 /* !target_var */);
1215 free(pszVal);
1216
1217 /*
1218 _OUT_FILES += $($(target)_$(source)_OUTPUT_)
1219 */
1220 pVar = kbuild_get_variable("_OUT_FILES");
1221 psz = pszVal = xmalloc(pVar->value_length + 1 + pOutput->value_length + 1);
1222 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1223 *psz++ = ' ';
1224 memcpy(psz, pOutput->value, pOutput->value_length + 1);
1225 do_variable_definition(NILF, "_OUT_FILES", pszVal, o_file, f_simple, 0 /* !target_var */);
1226 free(pszVal);
1227
1228 /*
1229 $(target)_OBJS_ += $(obj)
1230 */
1231 memcpy(pszDstVar + pTarget->value_length, "_OBJS_", sizeof("_OBJS_"));
1232 do_variable_definition(NILF, pszDstVar, pObj->value, o_file, f_append, 0 /* !target_var */);
1233
1234 /*
1235 $(eval $(def_target_source_rule))
1236 */
1237 pVar = kbuild_get_recursive_variable("def_target_source_rule");
1238 pszVal = allocated_variable_expand(pVar->value);
1239
1240 install_variable_buffer(&pszSavedVarBuf, &cchSavedVarBuf);
1241 eval_buffer(pszVal);
1242 restore_variable_buffer(pszSavedVarBuf, cchSavedVarBuf);
1243
1244 free(pszVal);
1245
1246 kbuild_put_sdks(&Sdks);
1247 return variable_buffer_output(o, "", 1);
1248}
1249
Note: See TracBrowser for help on using the repository browser.