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

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

joined the tool and objsuff lookups into a single function, fixing bugs in both lookups and extending them to include more variations.

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