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

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

Some fixes.

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