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

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

fixed kbuild_get_object_suffix bug wrt to generated sources.

File size: 53.0 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 size_t cchSrcPrefix = 0;
415 const char *pszSrcEnd;
416 char *pszSrc;
417 char *pszResult;
418 char *psz;
419 size_t cch;
420
421 /*
422 * Strip the source filename of any uncessary leading path and root specs.
423 */
424 /* */
425 if ( pSource->value_length > pPathTarget->value_length
426 && !strncmp(pSource->value, pPathTarget->value, pPathTarget->value_length))
427 {
428 pszSrc = pSource->value + pPathTarget->value_length;
429 pszSrcPrefix = "gen/";
430 cchSrcPrefix = sizeof("gen/") - 1;
431 if ( *pszSrc == '/'
432 && !strncmp(pszSrc + 1, pTarget->value, pTarget->value_length)
433 && ( pszSrc[pTarget->value_length + 1] == '/'
434 || pszSrc[pTarget->value_length + 1] == '\0'))
435 pszSrc += 1 + pTarget->value_length;
436 }
437 else if ( pSource->value_length > pPathRoot->value_length
438 && !strncmp(pSource->value, pPathRoot->value, pPathRoot->value_length))
439 {
440 pszSrc = pSource->value + pPathRoot->value_length;
441 if ( *pszSrc == '/'
442 && !strncmp(pszSrc + 1, pPathSubCur->value, pPathSubCur->value_length)
443 && ( pszSrc[pPathSubCur->value_length + 1] == '/'
444 || pszSrc[pPathSubCur->value_length + 1] == '\0'))
445 pszSrc += 1 + pPathSubCur->value_length;
446 }
447 else
448 pszSrc = pSource->value;
449
450 /* skip root specification */
451#ifdef HAVE_DOS_PATHS
452 if (isalpha(pszSrc[0]) && pszSrc[1] == ':')
453 pszSrc += 2;
454#endif
455 while (*pszSrc == '/'
456#ifdef HAVE_DOS_PATHS
457 || *pszSrc == '\\'
458#endif
459 )
460 pszSrc++;
461
462 /* drop the source extension. */
463 pszSrcEnd = pSource->value + pSource->value_length;
464 for (;;)
465 {
466 pszSrcEnd--;
467 if ( pszSrcEnd <= pszSrc
468 || *pszSrcEnd == '/'
469#ifdef HAVE_DOS_PATHS
470 || *pszSrcEnd == '\\'
471 || *pszSrcEnd == ':'
472#endif
473 )
474 {
475 pszSrcEnd = pSource->value + pSource->value_length;
476 break;
477 }
478 if (*pszSrcEnd == '.')
479 break;
480 }
481
482 /*
483 * Assemble the string on the stack and define the objbase variable
484 * which we then return.
485 */
486 cch = pPathTarget->value_length
487 + 1 /* slash */
488 + pTarget->value_length
489 + 1 /* slash */
490 + cchSrcPrefix
491 + pszSrcEnd - pszSrc
492 + 1;
493 psz = pszResult = xmalloc(cch);
494
495 memcpy(psz, pPathTarget->value, pPathTarget->value_length); psz += pPathTarget->value_length;
496 *psz++ = '/';
497 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
498 *psz++ = '/';
499 if (pszSrcPrefix)
500 {
501 memcpy(psz, pszSrcPrefix, cchSrcPrefix);
502 psz += cchSrcPrefix;
503 }
504 memcpy(psz, pszSrc, pszSrcEnd - pszSrc); psz += pszSrcEnd - pszSrc;
505 *psz = '\0';
506
507 /*
508 * Define the variable in the current set and return it.
509 */
510 return define_variable_vl(pszVarName, strlen(pszVarName), pszResult, cch - 1,
511 0 /* use pszResult */, o_file, 0 /* !recursive */);
512}
513
514/* Implements _OBJECT_BASE. */
515char *
516func_kbuild_object_base(char *o, char **argv, const char *pszFuncName)
517{
518 struct variable *pVar = kbuild_get_object_base(kbuild_lookup_variable("target"),
519 kbuild_lookup_variable("source"),
520 argv[0]);
521 if (pVar)
522 o = variable_buffer_output(o, pVar->value, pVar->value_length);
523 return o;
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,
583 pTarget->value, pBldType->value,
584 pTarget->value, pBldTrg->value,
585 pTarget->value, pBldTrg->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,
596 pSource->value, pBldType->value,
597 pSource->value, pBldTrg->value,
598 pSource->value, pBldTrg->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,
609 pTarget->value, pSource->value, pBldType->value,
610 pTarget->value, pSource->value, pBldTrg->value,
611 pTarget->value, pSource->value, pBldTrg->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 + 5);
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 = sizeof("PATH_")-1 + pTarget->value_length + sizeof("_")-1 + pSource->value_length;
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, pTool, pType, 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.