VirtualBox

source: kBuild/trunk/src/gmake/kbuild.c@ 587

Last change on this file since 587 was 575, checked in by bird, 18 years ago

Fixed an bug in the code getting SDKs. And fetch SDK.$(BUILD_TARGET_ARCH) too (old bug).

File size: 53.7 KB
Line 
1/* $Id: $ */
2/** @file
3 *
4 * kBuild specific make functionality.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <[email protected]>
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, cch;
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 = sizeof("$(__SDKS) $(__SDKS.) $(__SDKS.) $(__SDKS.) $(__SDKS..)")
562 + (pTarget->value_length + pSource->value_length) * 5
563 + pBldType->value_length
564 + pBldTrg->value_length
565 + pBldTrgArch->value_length
566 + pBldTrg->value_length + pBldTrgArch->value_length;
567 pszTmp = alloca(cchTmp);
568
569 /* the global sdks. */
570 pSdks->iGlobal = i;
571 pSdks->cGlobal = 0;
572 sprintf(pszTmp, "$(SDKS) $(SDKS.%s) $(SDKS.%s) $(SDKS.%s) $(SDKS.%s.%s)",
573 pBldType->value,
574 pBldTrg->value,
575 pBldTrgArch->value,
576 pBldTrg->value, pBldTrgArch->value);
577 pszIterator = pSdks->apsz[0] = allocated_variable_expand(pszTmp);
578 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
579 pSdks->cGlobal++;
580 i += pSdks->cGlobal;
581
582 /* the target sdks.*/
583 pSdks->iTarget = i;
584 pSdks->cTarget = 0;
585 sprintf(pszTmp, "$(%s_SDKS) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s.%s)",
586 pTarget->value,
587 pTarget->value, pBldType->value,
588 pTarget->value, pBldTrg->value,
589 pTarget->value, pBldTrgArch->value,
590 pTarget->value, pBldTrg->value, pBldTrgArch->value);
591 pszIterator = pSdks->apsz[1] = allocated_variable_expand(pszTmp);
592 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
593 pSdks->cTarget++;
594 i += pSdks->cTarget;
595
596 /* the source sdks.*/
597 pSdks->iSource = i;
598 pSdks->cSource = 0;
599 sprintf(pszTmp, "$(%s_SDKS) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s.%s)",
600 pSource->value,
601 pSource->value, pBldType->value,
602 pSource->value, pBldTrg->value,
603 pSource->value, pBldTrgArch->value,
604 pSource->value, pBldTrg->value, pBldTrgArch->value);
605 pszIterator = pSdks->apsz[2] = allocated_variable_expand(pszTmp);
606 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
607 pSdks->cSource++;
608 i += pSdks->cSource;
609
610 /* the target + source sdks. */
611 pSdks->iTargetSource = i;
612 pSdks->cTargetSource = 0;
613 cch = sprintf(pszTmp, "$(%s_%s_SDKS) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s.%s)",
614 pTarget->value, pSource->value,
615 pTarget->value, pSource->value, pBldType->value,
616 pTarget->value, pSource->value, pBldTrg->value,
617 pTarget->value, pSource->value, pBldTrgArch->value,
618 pTarget->value, pSource->value, pBldTrg->value, pBldTrgArch->value);
619 assert(cch < cchTmp); (void)cch;
620 pszIterator = pSdks->apsz[3] = allocated_variable_expand(pszTmp);
621 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
622 pSdks->cTargetSource++;
623 i += pSdks->cTargetSource;
624
625 pSdks->c = i;
626 if (!i)
627 return;
628
629 /*
630 * Allocate the variable array and create the variables.
631 */
632 pSdks->pa = (struct variable *)xmalloc(sizeof(pSdks->pa[0]) * i);
633 memset(pSdks->pa, 0, sizeof(pSdks->pa[0]) * i);
634 for (i = j = 0; j < sizeof(pSdks->apsz) / sizeof(pSdks->apsz[0]); j++)
635 {
636 int k = i;
637 pszIterator = pSdks->apsz[j];
638 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
639 {
640 pSdks->pa[i].value = pszCur;
641 pSdks->pa[i].value_length = cchCur;
642 i++;
643 }
644 }
645 assert(i == pSdks->c);
646
647 /* terminate them (find_next_token won't work if we terminate them in the previous loop). */
648 while (i-- > 0)
649 pSdks->pa[i].value[pSdks->pa[i].value_length] = '\0';
650}
651
652/* releases resources allocated in the kbuild_get_sdks. */
653kbuild_put_sdks(struct kbuild_sdks *pSdks)
654{
655 unsigned j;
656 for (j = 0; j < sizeof(pSdks->apsz) / sizeof(pSdks->apsz[0]); j++)
657 free(pSdks->apsz[j]);
658 free(pSdks->pa);
659}
660
661/* this kind of stuff:
662
663defs := $(kb-src-exp defs)
664 $(TOOL_$(tool)_DEFS)\
665 $(TOOL_$(tool)_DEFS.$(bld_type))\
666 $(TOOL_$(tool)_DEFS.$(bld_trg))\
667 $(TOOL_$(tool)_DEFS.$(bld_trg_arch))\
668 $(TOOL_$(tool)_DEFS.$(bld_trg).$(bld_trg_arch))\
669 $(TOOL_$(tool)_DEFS.$(bld_trg_cpu))\
670 $(TOOL_$(tool)_$(type)DEFS)\
671 $(TOOL_$(tool)_$(type)DEFS.$(bld_type))\
672 $(foreach sdk, $(SDKS.$(bld_trg)) \
673 $(SDKS.$(bld_trg).$(bld_trg_arch)) \
674 $(SDKS.$(bld_type)) \
675 $(SDKS),\
676 $(SDK_$(sdk)_DEFS)\
677 $(SDK_$(sdk)_DEFS.$(bld_type))\
678 $(SDK_$(sdk)_DEFS.$(bld_trg))\
679 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
680 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
681 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
682 $(SDK_$(sdk)_$(type)DEFS)\
683 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
684 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
685 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
686 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
687 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
688 $(DEFS)\
689 $(DEFS.$(bld_type))\
690 $(DEFS.$(bld_trg))\
691 $(DEFS.$(bld_trg_arch))\
692 $(DEFS.$(bld_trg).$(bld_trg_arch))\
693 $(DEFS.$(bld_trg_cpu))\
694 $($(type)DEFS)\
695 $($(type)DEFS.$(bld_type))\
696 $($(type)DEFS.$(bld_trg))\
697 $($(type)DEFS.$(bld_trg_arch))\
698 $($(type)DEFS.$(bld_trg).$(bld_trg_arch))\
699 $($(type)DEFS.$(bld_trg_cpu))\
700 $(foreach sdk, $($(target)_SDKS.$(bld_trg)) \
701 $($(target)_SDKS.$(bld_trg).$(bld_trg_arch)) \
702 $($(target)_SDKS.$(bld_type)) \
703 $($(target)_SDKS),\
704 $(SDK_$(sdk)_DEFS)\
705 $(SDK_$(sdk)_DEFS.$(bld_type))\
706 $(SDK_$(sdk)_DEFS.$(bld_trg))\
707 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
708 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
709 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
710 $(SDK_$(sdk)_$(type)DEFS)\
711 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
712 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
713 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
714 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
715 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
716 $($(target)_DEFS)\
717 $($(target)_DEFS.$(bld_type))\
718 $($(target)_DEFS.$(bld_trg))\
719 $($(target)_DEFS.$(bld_trg_arch))\
720 $($(target)_DEFS.$(bld_trg).$(bld_trg_arch))\
721 $($(target)_DEFS.$(bld_trg_cpu))\
722 $($(target)_$(type)DEFS)\
723 $($(target)_$(type)DEFS.$(bld_type))\
724 $($(target)_$(type)DEFS.$(bld_trg))\
725 $($(target)_$(type)DEFS.$(bld_trg_arch))\
726 $($(target)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
727 $($(target)_$(type)DEFS.$(bld_trg_cpu))\
728 $(foreach sdk, $($(source)_SDKS.$(bld_trg)) \
729 $($(source)_SDKS.$(bld_trg).$(bld_trg_arch)) \
730 $($(source)_SDKS.$(bld_type)) \
731 $($(source)_SDKS),\
732 $(SDK_$(sdk)_DEFS)\
733 $(SDK_$(sdk)_DEFS.$(bld_type))\
734 $(SDK_$(sdk)_DEFS.$(bld_trg))\
735 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
736 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
737 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
738 $(SDK_$(sdk)_$(type)DEFS)\
739 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
740 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
741 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
742 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
743 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
744 $($(source)_DEFS)\
745 $($(source)_DEFS.$(bld_type))\
746 $($(source)_DEFS.$(bld_trg))\
747 $($(source)_DEFS.$(bld_trg_arch))\
748 $($(source)_DEFS.$(bld_trg).$(bld_trg_arch))\
749 $($(source)_DEFS.$(bld_trg_cpu))\
750 $($(source)_$(type)DEFS)\
751 $($(source)_$(type)DEFS.$(bld_type))\
752 $($(source)_$(type)DEFS.$(bld_trg))\
753 $($(source)_$(type)DEFS.$(bld_trg_arch))\
754 $($(source)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
755 $($(source)_$(type)DEFS.$(bld_trg_cpu))\
756 $(foreach sdk, $($(target)_$(source)_SDKS.$(bld_trg)) \
757 $($(target)_$(source)_SDKS.$(bld_trg).$(bld_trg_arch)) \
758 $($(target)_$(source)_SDKS.$(bld_type)) \
759 $($(target)_$(source)_SDKS),\
760 $(SDK_$(sdk)_DEFS)\
761 $(SDK_$(sdk)_DEFS.$(bld_type))\
762 $(SDK_$(sdk)_DEFS.$(bld_trg))\
763 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
764 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
765 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
766 $(SDK_$(sdk)_$(type)DEFS)\
767 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
768 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
769 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
770 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
771 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
772 $($(target)_$(source)_DEFS)\
773 $($(target)_$(source)_DEFS.$(bld_type))\
774 $($(target)_$(source)_DEFS.$(bld_trg))\
775 $($(target)_$(source)_DEFS.$(bld_trg_arch))\
776 $($(target)_$(source)_DEFS.$(bld_trg).$(bld_trg_arch))\
777 $($(target)_$(source)_DEFS.$(bld_trg_cpu))\
778 $($(target)_$(source)_$(type)DEFS)\
779 $($(target)_$(source)_$(type)DEFS.$(bld_type))\
780 $($(target)_$(source)_$(type)DEFS.$(bld_trg))\
781 $($(target)_$(source)_$(type)DEFS.$(bld_trg_arch))\
782 $($(target)_$(source)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
783 $($(target)_$(source)_$(type)DEFS.$(bld_trg_cpu))
784*/
785static struct variable *
786kbuild_collect_source_prop(struct variable *pTarget, struct variable *pSource,
787 struct variable *pTool, struct kbuild_sdks *pSdks,
788 struct variable *pType, struct variable *pBldType,
789 struct variable *pBldTrg, struct variable *pBldTrgArch, struct variable *pBldTrgCpu,
790 const char *pszProp, const char *pszVarName, int iDirection)
791{
792 struct variable *pVar;
793 unsigned iSdk;
794 int cVars, iVar, iVarEnd;
795 size_t cchTotal;
796 char *pszResult, *psz;
797 struct
798 {
799 struct variable *pVar;
800 size_t cchExp;
801 char *pszExp;
802 } *paVars;
803
804 struct variable Prop = {0};
805 Prop.value = (char *)pszProp;
806 Prop.value_length = strlen(pszProp);
807
808 /*
809 * Get the variables.
810 */
811 cVars = 12 * (pSdks->c + 5);
812 paVars = alloca(cVars * sizeof(paVars[0]));
813
814 iVar = 0;
815 /* the tool (lowest priority) */
816 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%", pTool, &Prop);
817 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldType);
818 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldTrg);
819 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldTrgArch);
820 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%.%", pTool, &Prop, pBldTrg, pBldTrgArch);
821 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldTrgCpu);
822
823 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%", pTool, pType, &Prop);
824 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldType);
825 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldTrg);
826 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldTrgArch);
827 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%.%", pTool, pType, &Prop, pBldTrg, pBldTrgArch);
828 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldTrgCpu);
829
830 /* the global sdks */
831 for (iSdk = pSdks->iGlobal; iSdk < pSdks->cGlobal; iSdk++)
832 {
833 struct variable *pSdk = &pSdks->pa[iSdk];
834 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
835 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
836 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
837 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
838 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
839 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
840
841 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
842 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
843 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
844 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
845 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
846 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
847 }
848
849 /* the globals */
850 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%", &Prop);
851 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldType);
852 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldTrg);
853 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldTrgArch);
854 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%.%", &Prop, pBldTrg, pBldTrgArch);
855 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldTrgCpu);
856
857 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%", pType, &Prop);
858 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldType);
859 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldTrg);
860 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldTrgArch);
861 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%.%", pType, &Prop, pBldTrg, pBldTrgArch);
862 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldTrgCpu);
863
864 /* the target sdks */
865 for (iSdk = pSdks->iTarget; iSdk < pSdks->cTarget; iSdk++)
866 {
867 struct variable *pSdk = &pSdks->pa[iSdk];
868 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
869 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
870 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
871 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
872 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
873 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
874
875 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
876 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
877 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
878 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
879 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
880 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
881 }
882
883 /* the target */
884 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%", pTarget, &Prop);
885 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldType);
886 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldTrg);
887 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldTrgArch);
888 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%.%", pTarget, &Prop, pBldTrg, pBldTrgArch);
889 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldTrgCpu);
890
891 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%", pTarget, pType, &Prop);
892 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldType);
893 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldTrg);
894 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldTrgArch);
895 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%.%", pTarget, pType, &Prop, pBldTrg, pBldTrgArch);
896 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldTrgCpu);
897
898 /* the source sdks */
899 for (iSdk = pSdks->iSource; iSdk < pSdks->cSource; iSdk++)
900 {
901 struct variable *pSdk = &pSdks->pa[iSdk];
902 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
903 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
904 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
905 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
906 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
907 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
908
909 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
910 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
911 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
912 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
913 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
914 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
915 }
916
917 /* the source */
918 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%", pSource, &Prop);
919 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldType);
920 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldTrg);
921 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldTrgArch);
922 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%.%", pSource, &Prop, pBldTrg, pBldTrgArch);
923 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldTrgCpu);
924
925 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%", pSource, pType, &Prop);
926 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldType);
927 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldTrg);
928 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldTrgArch);
929 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%.%", pSource, pType, &Prop, pBldTrg, pBldTrgArch);
930 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldTrgCpu);
931
932
933 /* the target + source sdks */
934 for (iSdk = pSdks->iTargetSource; iSdk < pSdks->cTargetSource; iSdk++)
935 {
936 struct variable *pSdk = &pSdks->pa[iSdk];
937 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
938 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
939 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
940 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
941 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
942 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
943
944 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
945 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
946 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
947 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
948 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
949 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
950 }
951
952 /* the target + source */
953 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%", pTarget, pSource, &Prop);
954 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldType);
955 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldTrg);
956 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldTrgArch);
957 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%.%", pTarget, pSource, &Prop, pBldTrg, pBldTrgArch);
958 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldTrgCpu);
959
960 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%", pTarget, pSource, pType, &Prop);
961 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldType);
962 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrg);
963 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrgArch);
964 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%.%", pTarget, pSource, pType, &Prop, pBldTrg, pBldTrgArch);
965 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrgCpu);
966
967 assert(cVars == iVar);
968
969 /*
970 * Expand the variables and calculate the total length.
971 */
972 cchTotal = 0;
973 iVarEnd = iDirection > -1 ? cVars : 0;
974 for (iVar = iDirection > 0 ? 0 : cVars - 1; iVar != iVarEnd; iVar += iDirection)
975 {
976 paVars[iVar].cchExp = 0;
977 if (!paVars[iVar].pVar)
978 continue;
979 if ( paVars[iVar].pVar->flavor == f_simple
980 || !strchr(paVars[iVar].pVar->value, '$'))
981 {
982 paVars[iVar].pszExp = paVars[iVar].pVar->value;
983 paVars[iVar].cchExp = paVars[iVar].pVar->value_length;
984 }
985 else
986 {
987 paVars[iVar].pszExp = allocated_variable_expand(paVars[iVar].pVar->value);
988 paVars[iVar].cchExp = strlen(paVars[iVar].pszExp);
989 }
990 cchTotal += paVars[iVar].cchExp + 1;
991 }
992
993 /*
994 * Construct the result value.
995 */
996 psz = pszResult = xmalloc(cchTotal + 1);
997 iVarEnd = iDirection > -1 ? cVars : 0;
998 for (iVar = iDirection > 0 ? 0 : cVars - 1; iVar != iVarEnd; iVar += iDirection)
999 {
1000 if (!paVars[iVar].cchExp)
1001 continue;
1002 memcpy(psz, paVars[iVar].pszExp, paVars[iVar].cchExp);
1003 psz += paVars[iVar].cchExp;
1004 *psz++ = ' ';
1005 if (paVars[iVar].pszExp != paVars[iVar].pVar->value)
1006 free(paVars[iVar].pszExp);
1007 }
1008 if (psz != pszResult)
1009 psz--;
1010 *psz = '\0';
1011 cchTotal = psz - pszResult;
1012
1013 pVar = define_variable_vl(pszVarName, strlen(pszVarName), pszResult, cchTotal,
1014 0 /* take pszResult */ , o_file, 0 /* !recursive */);
1015 return pVar;
1016}
1017
1018/* get a source property. */
1019char *
1020func_kbuild_source_prop(char *o, char **argv, const char *pszFuncName)
1021{
1022 struct variable *pTarget = kbuild_get_variable("target");
1023 struct variable *pSource = kbuild_get_variable("source");
1024 struct variable *pType = kbuild_get_variable("type");
1025 struct variable *pTool = kbuild_get_variable("tool");
1026 struct variable *pBldType = kbuild_get_variable("bld_type");
1027 struct variable *pBldTrg = kbuild_get_variable("bld_trg");
1028 struct variable *pBldTrgArch = kbuild_get_variable("bld_trg_arch");
1029 struct variable *pBldTrgCpu = kbuild_get_variable("bld_trg_cpu");
1030 struct variable *pVar;
1031 struct kbuild_sdks Sdks;
1032 int iDirection;
1033 if (!strcmp(argv[2], "left-to-right"))
1034 iDirection = 1;
1035 else if (!strcmp(argv[2], "right-to-left"))
1036 iDirection = 1;
1037 else
1038 fatal(NILF, _("incorrect direction argument `%s'!"), argv[2]);
1039
1040 kbuild_get_sdks(&Sdks, pTarget, pSource, pBldType, pBldTrg, pBldTrgArch);
1041
1042 pVar = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType,
1043 pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1044 argv[0], argv[1], iDirection);
1045 if (pVar)
1046 o = variable_buffer_output(o, pVar->value, pVar->value_length);
1047
1048 kbuild_put_sdks(&Sdks);
1049 return o;
1050
1051}
1052
1053/*
1054dep := $(obj)$(SUFF_DEP)
1055obj := $(outbase)$(objsuff)
1056dirdep := $(call DIRDEP,$(dir $(outbase)))
1057PATH_$(target)_$(source) := $(patsubst %/,%,$(dir $(outbase)))
1058*/
1059static struct variable *
1060kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(struct variable *pTarget, struct variable *pSource,
1061 struct variable *pOutBase, struct variable *pObjSuff,
1062 const char *pszVarName, struct variable **ppDep,
1063 struct variable **ppDirDep)
1064{
1065 struct variable *pDepSuff = kbuild_get_variable("SUFF_DEP");
1066 struct variable *pObj;
1067 size_t cch = pOutBase->value_length + pObjSuff->value_length + pDepSuff->value_length + 1;
1068 char *pszResult = alloca(cch);
1069 char *pszName, *psz;
1070
1071 /*
1072 * dep.
1073 */
1074 psz = pszResult;
1075 memcpy(psz, pOutBase->value, pOutBase->value_length); psz += pOutBase->value_length;
1076 memcpy(psz, pObjSuff->value, pObjSuff->value_length); psz += pObjSuff->value_length;
1077 memcpy(psz, pDepSuff->value, pDepSuff->value_length + 1);
1078 *ppDep = define_variable_vl("dep", 3, pszResult, cch - 1, 1 /*dup*/, o_file, 0 /* !recursive */);
1079
1080 /*
1081 * obj
1082 */
1083 *psz = '\0';
1084 pObj = define_variable_vl(pszVarName, strlen(pszVarName), pszResult, psz - pszResult,
1085 1/* dup */, o_file, 0 /* !recursive */);
1086
1087 /*
1088 * PATH_$(target)_$(source) - this is global!
1089 */
1090 /* calc variable name. */
1091 cch = sizeof("PATH_")-1 + pTarget->value_length + sizeof("_")-1 + pSource->value_length;
1092 psz = pszName = alloca(cch + 1);
1093 memcpy(psz, "PATH_", sizeof("PATH_") - 1); psz += sizeof("PATH_") - 1;
1094 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
1095 *psz++ = '_';
1096 memcpy(psz, pSource->value, pSource->value_length + 1);
1097
1098 /* strip off the filename. */
1099 psz = pszResult + pOutBase->value_length;
1100 for (;;)
1101 {
1102 psz--;
1103 if (psz <= pszResult)
1104 fatal(NULL, "whut!?! no path? result=`%s'", pszResult);
1105#ifdef HAVE_DOS_PATHS
1106 if (*psz == ':')
1107 {
1108 psz++;
1109 break;
1110 }
1111#endif
1112 if ( *psz == '/'
1113#ifdef HAVE_DOS_PATHS
1114 || *psz == '\\'
1115#endif
1116 )
1117 {
1118 while ( psz - 1 > pszResult
1119 && psz[-1] == '/'
1120#ifdef HAVE_DOS_PATHS
1121 || psz[-1] == '\\'
1122#endif
1123 )
1124 psz--;
1125#ifdef HAVE_DOS_PATHS
1126 if (psz == pszResult + 2 && pszResult[1] == ':')
1127 psz++;
1128#endif
1129 break;
1130 }
1131 }
1132 *psz = '\0';
1133
1134 /* set global variable */
1135 define_variable_vl_global(pszName, cch, pszResult, psz - pszResult, 1/*dup*/, o_file, 0 /* !recursive */, NILF);
1136
1137 /*
1138 * dirdep
1139 */
1140 if ( psz[-1] != '/'
1141#ifdef HAVE_DOS_PATHS
1142 && psz[-1] != '\\'
1143 && psz[-1] != ':'
1144#endif
1145 )
1146 {
1147 *psz++ = '/';
1148 *psz = '\0';
1149 }
1150 *ppDirDep = define_variable_vl("dirdep", 6, pszResult, psz - pszResult, 1/*dup*/, o_file, 0 /* !recursive */);
1151
1152 return pObj;
1153}
1154
1155
1156/* setup the base variables for def_target_source_c_cpp_asm_new:
1157
1158X := $(kb-src-tool tool)
1159x := $(kb-obj-base outbase)
1160x := $(kb-obj-suff objsuff)
1161obj := $(outbase)$(objsuff)
1162PATH_$(target)_$(source) := $(patsubst %/,%,$(dir $(outbase)))
1163
1164x := $(kb-src-prop DEFS,defs,left-to-right)
1165x := $(kb-src-prop INCS,incs,right-to-left)
1166x := $(kb-src-prop FLAGS,flags,right-to-left)
1167
1168x := $(kb-src-prop DEPS,deps,left-to-right)
1169dirdep := $(call DIRDEP,$(dir $(outbase)))
1170dep := $(obj)$(SUFF_DEP)
1171*/
1172char *
1173func_kbuild_source_one(char *o, char **argv, const char *pszFuncName)
1174{
1175 static int s_fNoCompileCmdsDepsDefined = -1;
1176 struct variable *pTarget = kbuild_get_variable("target");
1177 struct variable *pSource = kbuild_get_variable("source");
1178 struct variable *pType = kbuild_get_variable("type");
1179 struct variable *pBldType = kbuild_get_variable("bld_type");
1180 struct variable *pBldTrg = kbuild_get_variable("bld_trg");
1181 struct variable *pBldTrgArch= kbuild_get_variable("bld_trg_arch");
1182 struct variable *pBldTrgCpu = kbuild_get_variable("bld_trg_cpu");
1183 struct variable *pTool = kbuild_get_source_tool(pTarget, pSource, pType, pBldTrg, pBldTrgArch, "tool");
1184 struct variable *pOutBase = kbuild_get_object_base(pTarget, pSource, "outbase");
1185 struct variable *pObjSuff = kbuild_get_object_suffix(pTarget, pSource, pTool, pType, pBldTrg, pBldTrgArch, "objsuff");
1186 struct variable *pDefs, *pIncs, *pFlags, *pDeps, *pDirDep, *pDep, *pVar, *pOutput;
1187 struct variable *pObj = kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(pTarget, pSource, pOutBase, pObjSuff, "obj", &pDep, &pDirDep);
1188 char *pszDstVar, *pszDst, *pszSrcVar, *pszSrc, *pszVal, *psz;
1189 char *pszSavedVarBuf;
1190 unsigned cchSavedVarBuf;
1191 size_t cch;
1192 struct kbuild_sdks Sdks;
1193 kbuild_get_sdks(&Sdks, pTarget, pSource, pBldType, pBldTrg, pBldTrgArch);
1194
1195 pDefs = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1196 "DEFS", "defs", 1/* left-to-right */);
1197 pIncs = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1198 "INCS", "incs", 1/* right-to-left */);
1199 pFlags = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1200 "FLAGS", "flags", 1/* right-to-left */);
1201 pDeps = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1202 "DEPS", "deps", 1/* left-to-right */);
1203
1204 /*
1205 # dependencies
1206 ifndef NO_COMPILE_CMDS_DEPS
1207 _DEPFILES_INCLUDED += $(dep)
1208 $(if $(wildcard $(dep)),$(eval include $(dep)))
1209 endif
1210 */
1211 if (s_fNoCompileCmdsDepsDefined == -1)
1212 s_fNoCompileCmdsDepsDefined = kbuild_lookup_variable("NO_COMPILE_CMDS_DEPS") != NULL;
1213 if (!s_fNoCompileCmdsDepsDefined)
1214 {
1215 do_variable_definition(NILF, "_DEPFILES_INCLUDED", pDep->value, o_file, f_append, 0 /* !target_var */);
1216 eval_include_dep(pDep->value, NILF);
1217 }
1218
1219 /*
1220 # call the tool
1221 $(target)_$(source)_CMDS_ := $(TOOL_$(tool)_COMPILE_$(type)_CMDS)
1222 $(target)_$(source)_OUTPUT_ := $(TOOL_$(tool)_COMPILE_$(type)_OUTPUT)
1223 $(target)_$(source)_DEPEND_ := $(TOOL_$(tool)_COMPILE_$(type)_DEPEND) $(deps) $(source)
1224 $(target)_$(source)_DEPORD_ := $(TOOL_$(tool)_COMPILE_$(type)_DEPORD) $(dirdep)
1225 */
1226 cch = sizeof("TOOL_") + pTool->value_length + sizeof("_COMPILE_") + pType->value_length + sizeof("_OUTPUT");
1227 psz = pszSrcVar = alloca(cch);
1228 memcpy(psz, "TOOL_", sizeof("TOOL_") - 1); psz += sizeof("TOOL_") - 1;
1229 memcpy(psz, pTool->value, pTool->value_length); psz += pTool->value_length;
1230 memcpy(psz, "_COMPILE_", sizeof("_COMPILE_") - 1); psz += sizeof("_COMPILE_") - 1;
1231 memcpy(psz, pType->value, pType->value_length); psz += pType->value_length;
1232 pszSrc = psz;
1233
1234 cch = pTarget->value_length + 1 + pSource->value_length + sizeof("_OUTPUT_");
1235 psz = pszDstVar = alloca(cch);
1236 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
1237 *psz++ = '_';
1238 memcpy(psz, pSource->value, pSource->value_length); psz += pSource->value_length;
1239 pszDst = psz;
1240
1241 memcpy(pszSrc, "_CMDS", sizeof("_CMDS"));
1242 memcpy(pszDst, "_CMDS_", sizeof("_CMDS_"));
1243 pVar = kbuild_get_recursive_variable(pszSrcVar);
1244 do_variable_definition(NILF, pszDstVar, pVar->value, o_file, f_simple, 0 /* !target_var */);
1245
1246 memcpy(pszSrc, "_OUTPUT", sizeof("_OUTPUT"));
1247 memcpy(pszDst, "_OUTPUT_", sizeof("_OUTPUT_"));
1248 pVar = kbuild_get_recursive_variable(pszSrcVar);
1249 pOutput = do_variable_definition(NILF, pszDstVar, pVar->value, o_file, f_simple, 0 /* !target_var */);
1250
1251 memcpy(pszSrc, "_DEPEND", sizeof("_DEPEND"));
1252 memcpy(pszDst, "_DEPEND_", sizeof("_DEPEND_"));
1253 pVar = kbuild_get_recursive_variable(pszSrcVar);
1254 psz = pszVal = xmalloc(pVar->value_length + 1 + pDeps->value_length + 1 + pSource->value_length + 1);
1255 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1256 *psz++ = ' ';
1257 memcpy(psz, pDeps->value, pDeps->value_length); psz += pDeps->value_length;
1258 *psz++ = ' ';
1259 memcpy(psz, pSource->value, pSource->value_length + 1);
1260 do_variable_definition(NILF, pszDstVar, pszVal, o_file, f_simple, 0 /* !target_var */);
1261 free(pszVal);
1262
1263 memcpy(pszSrc, "_DEPORD", sizeof("_DEPORD"));
1264 memcpy(pszDst, "_DEPORD_", sizeof("_DEPORD_"));
1265 pVar = kbuild_get_recursive_variable(pszSrcVar);
1266 psz = pszVal = xmalloc(pVar->value_length + 1 + pDirDep->value_length + 1);
1267 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1268 *psz++ = ' ';
1269 memcpy(psz, pDirDep->value, pDirDep->value_length + 1);
1270 do_variable_definition(NILF, pszDstVar, pszVal, o_file, f_simple, 0 /* !target_var */);
1271 free(pszVal);
1272
1273 /*
1274 _OUT_FILES += $($(target)_$(source)_OUTPUT_)
1275 */
1276 pVar = kbuild_get_variable("_OUT_FILES");
1277 psz = pszVal = xmalloc(pVar->value_length + 1 + pOutput->value_length + 1);
1278 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1279 *psz++ = ' ';
1280 memcpy(psz, pOutput->value, pOutput->value_length + 1);
1281 do_variable_definition(NILF, "_OUT_FILES", pszVal, o_file, f_simple, 0 /* !target_var */);
1282 free(pszVal);
1283
1284 /*
1285 $(target)_OBJS_ += $(obj)
1286 */
1287 memcpy(pszDstVar + pTarget->value_length, "_OBJS_", sizeof("_OBJS_"));
1288 do_variable_definition(NILF, pszDstVar, pObj->value, o_file, f_append, 0 /* !target_var */);
1289
1290 /*
1291 $(eval $(def_target_source_rule))
1292 */
1293 pVar = kbuild_get_recursive_variable("def_target_source_rule");
1294 pszVal = allocated_variable_expand(pVar->value);
1295
1296 install_variable_buffer(&pszSavedVarBuf, &cchSavedVarBuf);
1297 eval_buffer(pszVal);
1298 restore_variable_buffer(pszSavedVarBuf, cchSavedVarBuf);
1299
1300 free(pszVal);
1301
1302 kbuild_put_sdks(&Sdks);
1303 return variable_buffer_output(o, "", 1);
1304}
1305
1306
1307#endif /* KMK_HELPERS */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette