VirtualBox

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

Last change on this file since 684 was 646, checked in by bird, 18 years ago

Fixed bugs dealing with the order SDK properties was applied to sources.

File size: 54.5 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, iSdkEnd;
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 assert(iDirection == 1 || iDirection == -1);
809
810 /*
811 * Get the variables.
812 */
813 cVars = 12 * (pSdks->c + 5);
814 paVars = alloca(cVars * sizeof(paVars[0]));
815
816 iVar = 0;
817 /* the tool (lowest priority) */
818 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%", pTool, &Prop);
819 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldType);
820 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldTrg);
821 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldTrgArch);
822 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%.%", pTool, &Prop, pBldTrg, pBldTrgArch);
823 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &Prop, pBldTrgCpu);
824
825 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%", pTool, pType, &Prop);
826 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldType);
827 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldTrg);
828 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldTrgArch);
829 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%.%", pTool, pType, &Prop, pBldTrg, pBldTrgArch);
830 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &Prop, pBldTrgCpu);
831
832 /* the global sdks */
833 iSdkEnd = iDirection == 1 ? pSdks->iGlobal + pSdks->cGlobal : pSdks->iGlobal - 1;
834 for (iSdk = iDirection == 1 ? pSdks->iGlobal : pSdks->iGlobal + pSdks->cGlobal - 1;
835 iSdk != iSdkEnd;
836 iSdk += iDirection)
837 {
838 struct variable *pSdk = &pSdks->pa[iSdk];
839 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
840 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
841 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
842 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
843 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
844 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
845
846 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
847 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
848 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
849 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
850 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
851 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
852 }
853
854 /* the globals */
855 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%", &Prop);
856 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldType);
857 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldTrg);
858 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldTrgArch);
859 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%.%", &Prop, pBldTrg, pBldTrgArch);
860 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%.%", &Prop, pBldTrgCpu);
861
862 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%", pType, &Prop);
863 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldType);
864 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldTrg);
865 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldTrgArch);
866 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%.%", pType, &Prop, pBldTrg, pBldTrgArch);
867 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%%.%", pType, &Prop, pBldTrgCpu);
868
869 /* the target sdks */
870 iSdkEnd = iDirection == 1 ? pSdks->iTarget + pSdks->cTarget : pSdks->iTarget - 1;
871 for (iSdk = iDirection == 1 ? pSdks->iTarget : pSdks->iTarget + pSdks->cTarget - 1;
872 iSdk != iSdkEnd;
873 iSdk += iDirection)
874 {
875 struct variable *pSdk = &pSdks->pa[iSdk];
876 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
877 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
878 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
879 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
880 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
881 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
882
883 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
884 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
885 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
886 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
887 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
888 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
889 }
890
891 /* the target */
892 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%", pTarget, &Prop);
893 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldType);
894 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldTrg);
895 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldTrgArch);
896 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%.%", pTarget, &Prop, pBldTrg, pBldTrgArch);
897 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &Prop, pBldTrgCpu);
898
899 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%", pTarget, pType, &Prop);
900 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldType);
901 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldTrg);
902 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldTrgArch);
903 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%.%", pTarget, pType, &Prop, pBldTrg, pBldTrgArch);
904 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &Prop, pBldTrgCpu);
905
906 /* the source sdks */
907 iSdkEnd = iDirection == 1 ? pSdks->iSource + pSdks->cSource : pSdks->iSource - 1;
908 for (iSdk = iDirection == 1 ? pSdks->iSource : pSdks->iSource + pSdks->cSource - 1;
909 iSdk != iSdkEnd;
910 iSdk += iDirection)
911 {
912 struct variable *pSdk = &pSdks->pa[iSdk];
913 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
914 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
915 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
916 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
917 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
918 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
919
920 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
921 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
922 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
923 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
924 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
925 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
926 }
927
928 /* the source */
929 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%", pSource, &Prop);
930 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldType);
931 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldTrg);
932 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldTrgArch);
933 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%.%", pSource, &Prop, pBldTrg, pBldTrgArch);
934 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &Prop, pBldTrgCpu);
935
936 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%", pSource, pType, &Prop);
937 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldType);
938 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldTrg);
939 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldTrgArch);
940 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%.%", pSource, pType, &Prop, pBldTrg, pBldTrgArch);
941 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &Prop, pBldTrgCpu);
942
943
944 /* the target + source sdks */
945 iSdkEnd = iDirection == 1 ? pSdks->iTargetSource + pSdks->cTargetSource : pSdks->iTargetSource - 1;
946 for (iSdk = iDirection == 1 ? pSdks->iTargetSource : pSdks->iTargetSource + pSdks->cTargetSource - 1;
947 iSdk != iSdkEnd;
948 iSdk += iDirection)
949 {
950 struct variable *pSdk = &pSdks->pa[iSdk];
951 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%", pSdk, &Prop);
952 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldType);
953 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrg);
954 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
955 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
956 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
957
958 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%", pSdk, pType, &Prop);
959 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
960 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
961 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
962 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
963 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
964 }
965
966 /* the target + source */
967 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%", pTarget, pSource, &Prop);
968 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldType);
969 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldTrg);
970 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldTrgArch);
971 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%.%", pTarget, pSource, &Prop, pBldTrg, pBldTrgArch);
972 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &Prop, pBldTrgCpu);
973
974 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%", pTarget, pSource, pType, &Prop);
975 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldType);
976 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrg);
977 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrgArch);
978 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%.%", pTarget, pSource, pType, &Prop, pBldTrg, pBldTrgArch);
979 paVars[iVar++].pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrgCpu);
980
981 assert(cVars == iVar);
982
983 /*
984 * Expand the variables and calculate the total length.
985 */
986 cchTotal = 0;
987 iVarEnd = iDirection == 1 ? cVars : 0;
988 for (iVar = iDirection == 1 ? 0 : cVars - 1; iVar != iVarEnd; iVar += iDirection)
989 {
990 paVars[iVar].cchExp = 0;
991 if (!paVars[iVar].pVar)
992 continue;
993 if ( paVars[iVar].pVar->flavor == f_simple
994 || !strchr(paVars[iVar].pVar->value, '$'))
995 {
996 paVars[iVar].pszExp = paVars[iVar].pVar->value;
997 paVars[iVar].cchExp = paVars[iVar].pVar->value_length;
998 }
999 else
1000 {
1001 paVars[iVar].pszExp = allocated_variable_expand(paVars[iVar].pVar->value);
1002 paVars[iVar].cchExp = strlen(paVars[iVar].pszExp);
1003 }
1004 cchTotal += paVars[iVar].cchExp + 1;
1005 }
1006
1007 /*
1008 * Construct the result value.
1009 */
1010 psz = pszResult = xmalloc(cchTotal + 1);
1011 iVarEnd = iDirection == 1 ? cVars : 0;
1012 for (iVar = iDirection == 1 ? 0 : cVars - 1; iVar != iVarEnd; iVar += iDirection)
1013 {
1014 if (!paVars[iVar].cchExp)
1015 continue;
1016 memcpy(psz, paVars[iVar].pszExp, paVars[iVar].cchExp);
1017 psz += paVars[iVar].cchExp;
1018 *psz++ = ' ';
1019 if (paVars[iVar].pszExp != paVars[iVar].pVar->value)
1020 free(paVars[iVar].pszExp);
1021 }
1022 if (psz != pszResult)
1023 psz--;
1024 *psz = '\0';
1025 cchTotal = psz - pszResult;
1026
1027 pVar = define_variable_vl(pszVarName, strlen(pszVarName), pszResult, cchTotal,
1028 0 /* take pszResult */ , o_file, 0 /* !recursive */);
1029 return pVar;
1030}
1031
1032/* get a source property. */
1033char *
1034func_kbuild_source_prop(char *o, char **argv, const char *pszFuncName)
1035{
1036 struct variable *pTarget = kbuild_get_variable("target");
1037 struct variable *pSource = kbuild_get_variable("source");
1038 struct variable *pType = kbuild_get_variable("type");
1039 struct variable *pTool = kbuild_get_variable("tool");
1040 struct variable *pBldType = kbuild_get_variable("bld_type");
1041 struct variable *pBldTrg = kbuild_get_variable("bld_trg");
1042 struct variable *pBldTrgArch = kbuild_get_variable("bld_trg_arch");
1043 struct variable *pBldTrgCpu = kbuild_get_variable("bld_trg_cpu");
1044 struct variable *pVar;
1045 struct kbuild_sdks Sdks;
1046 int iDirection;
1047 if (!strcmp(argv[2], "left-to-right"))
1048 iDirection = 1;
1049 else if (!strcmp(argv[2], "right-to-left"))
1050 iDirection = -1;
1051 else
1052 fatal(NILF, _("incorrect direction argument `%s'!"), argv[2]);
1053
1054 kbuild_get_sdks(&Sdks, pTarget, pSource, pBldType, pBldTrg, pBldTrgArch);
1055
1056 pVar = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType,
1057 pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1058 argv[0], argv[1], iDirection);
1059 if (pVar)
1060 o = variable_buffer_output(o, pVar->value, pVar->value_length);
1061
1062 kbuild_put_sdks(&Sdks);
1063 return o;
1064
1065}
1066
1067/*
1068dep := $(obj)$(SUFF_DEP)
1069obj := $(outbase)$(objsuff)
1070dirdep := $(call DIRDEP,$(dir $(outbase)))
1071PATH_$(target)_$(source) := $(patsubst %/,%,$(dir $(outbase)))
1072*/
1073static struct variable *
1074kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(struct variable *pTarget, struct variable *pSource,
1075 struct variable *pOutBase, struct variable *pObjSuff,
1076 const char *pszVarName, struct variable **ppDep,
1077 struct variable **ppDirDep)
1078{
1079 struct variable *pDepSuff = kbuild_get_variable("SUFF_DEP");
1080 struct variable *pObj;
1081 size_t cch = pOutBase->value_length + pObjSuff->value_length + pDepSuff->value_length + 1;
1082 char *pszResult = alloca(cch);
1083 char *pszName, *psz;
1084
1085 /*
1086 * dep.
1087 */
1088 psz = pszResult;
1089 memcpy(psz, pOutBase->value, pOutBase->value_length); psz += pOutBase->value_length;
1090 memcpy(psz, pObjSuff->value, pObjSuff->value_length); psz += pObjSuff->value_length;
1091 memcpy(psz, pDepSuff->value, pDepSuff->value_length + 1);
1092 *ppDep = define_variable_vl("dep", 3, pszResult, cch - 1, 1 /*dup*/, o_file, 0 /* !recursive */);
1093
1094 /*
1095 * obj
1096 */
1097 *psz = '\0';
1098 pObj = define_variable_vl(pszVarName, strlen(pszVarName), pszResult, psz - pszResult,
1099 1/* dup */, o_file, 0 /* !recursive */);
1100
1101 /*
1102 * PATH_$(target)_$(source) - this is global!
1103 */
1104 /* calc variable name. */
1105 cch = sizeof("PATH_")-1 + pTarget->value_length + sizeof("_")-1 + pSource->value_length;
1106 psz = pszName = alloca(cch + 1);
1107 memcpy(psz, "PATH_", sizeof("PATH_") - 1); psz += sizeof("PATH_") - 1;
1108 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
1109 *psz++ = '_';
1110 memcpy(psz, pSource->value, pSource->value_length + 1);
1111
1112 /* strip off the filename. */
1113 psz = pszResult + pOutBase->value_length;
1114 for (;;)
1115 {
1116 psz--;
1117 if (psz <= pszResult)
1118 fatal(NULL, "whut!?! no path? result=`%s'", pszResult);
1119#ifdef HAVE_DOS_PATHS
1120 if (*psz == ':')
1121 {
1122 psz++;
1123 break;
1124 }
1125#endif
1126 if ( *psz == '/'
1127#ifdef HAVE_DOS_PATHS
1128 || *psz == '\\'
1129#endif
1130 )
1131 {
1132 while ( psz - 1 > pszResult
1133 && psz[-1] == '/'
1134#ifdef HAVE_DOS_PATHS
1135 || psz[-1] == '\\'
1136#endif
1137 )
1138 psz--;
1139#ifdef HAVE_DOS_PATHS
1140 if (psz == pszResult + 2 && pszResult[1] == ':')
1141 psz++;
1142#endif
1143 break;
1144 }
1145 }
1146 *psz = '\0';
1147
1148 /* set global variable */
1149 define_variable_vl_global(pszName, cch, pszResult, psz - pszResult, 1/*dup*/, o_file, 0 /* !recursive */, NILF);
1150
1151 /*
1152 * dirdep
1153 */
1154 if ( psz[-1] != '/'
1155#ifdef HAVE_DOS_PATHS
1156 && psz[-1] != '\\'
1157 && psz[-1] != ':'
1158#endif
1159 )
1160 {
1161 *psz++ = '/';
1162 *psz = '\0';
1163 }
1164 *ppDirDep = define_variable_vl("dirdep", 6, pszResult, psz - pszResult, 1/*dup*/, o_file, 0 /* !recursive */);
1165
1166 return pObj;
1167}
1168
1169
1170/* setup the base variables for def_target_source_c_cpp_asm_new:
1171
1172X := $(kb-src-tool tool)
1173x := $(kb-obj-base outbase)
1174x := $(kb-obj-suff objsuff)
1175obj := $(outbase)$(objsuff)
1176PATH_$(target)_$(source) := $(patsubst %/,%,$(dir $(outbase)))
1177
1178x := $(kb-src-prop DEFS,defs,left-to-right)
1179x := $(kb-src-prop INCS,incs,right-to-left)
1180x := $(kb-src-prop FLAGS,flags,right-to-left)
1181
1182x := $(kb-src-prop DEPS,deps,left-to-right)
1183dirdep := $(call DIRDEP,$(dir $(outbase)))
1184dep := $(obj)$(SUFF_DEP)
1185*/
1186char *
1187func_kbuild_source_one(char *o, char **argv, const char *pszFuncName)
1188{
1189 static int s_fNoCompileCmdsDepsDefined = -1;
1190 struct variable *pTarget = kbuild_get_variable("target");
1191 struct variable *pSource = kbuild_get_variable("source");
1192 struct variable *pType = kbuild_get_variable("type");
1193 struct variable *pBldType = kbuild_get_variable("bld_type");
1194 struct variable *pBldTrg = kbuild_get_variable("bld_trg");
1195 struct variable *pBldTrgArch= kbuild_get_variable("bld_trg_arch");
1196 struct variable *pBldTrgCpu = kbuild_get_variable("bld_trg_cpu");
1197 struct variable *pTool = kbuild_get_source_tool(pTarget, pSource, pType, pBldTrg, pBldTrgArch, "tool");
1198 struct variable *pOutBase = kbuild_get_object_base(pTarget, pSource, "outbase");
1199 struct variable *pObjSuff = kbuild_get_object_suffix(pTarget, pSource, pTool, pType, pBldTrg, pBldTrgArch, "objsuff");
1200 struct variable *pDefs, *pIncs, *pFlags, *pDeps, *pDirDep, *pDep, *pVar, *pOutput;
1201 struct variable *pObj = kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(pTarget, pSource, pOutBase, pObjSuff, "obj", &pDep, &pDirDep);
1202 char *pszDstVar, *pszDst, *pszSrcVar, *pszSrc, *pszVal, *psz;
1203 char *pszSavedVarBuf;
1204 unsigned cchSavedVarBuf;
1205 size_t cch;
1206 struct kbuild_sdks Sdks;
1207 kbuild_get_sdks(&Sdks, pTarget, pSource, pBldType, pBldTrg, pBldTrgArch);
1208
1209 pDefs = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1210 "DEFS", "defs", 1/* left-to-right */);
1211 pIncs = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1212 "INCS", "incs", -1/* right-to-left */);
1213 pFlags = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1214 "FLAGS", "flags", 1/* left-to-right */);
1215 pDeps = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1216 "DEPS", "deps", 1/* left-to-right */);
1217
1218 /*
1219 # dependencies
1220 ifndef NO_COMPILE_CMDS_DEPS
1221 _DEPFILES_INCLUDED += $(dep)
1222 $(if $(wildcard $(dep)),$(eval include $(dep)))
1223 endif
1224 */
1225 if (s_fNoCompileCmdsDepsDefined == -1)
1226 s_fNoCompileCmdsDepsDefined = kbuild_lookup_variable("NO_COMPILE_CMDS_DEPS") != NULL;
1227 if (!s_fNoCompileCmdsDepsDefined)
1228 {
1229 do_variable_definition(NILF, "_DEPFILES_INCLUDED", pDep->value, o_file, f_append, 0 /* !target_var */);
1230 eval_include_dep(pDep->value, NILF);
1231 }
1232
1233 /*
1234 # call the tool
1235 $(target)_$(source)_CMDS_ := $(TOOL_$(tool)_COMPILE_$(type)_CMDS)
1236 $(target)_$(source)_OUTPUT_ := $(TOOL_$(tool)_COMPILE_$(type)_OUTPUT)
1237 $(target)_$(source)_DEPEND_ := $(TOOL_$(tool)_COMPILE_$(type)_DEPEND) $(deps) $(source)
1238 $(target)_$(source)_DEPORD_ := $(TOOL_$(tool)_COMPILE_$(type)_DEPORD) $(dirdep)
1239 */
1240 cch = sizeof("TOOL_") + pTool->value_length + sizeof("_COMPILE_") + pType->value_length + sizeof("_OUTPUT");
1241 psz = pszSrcVar = alloca(cch);
1242 memcpy(psz, "TOOL_", sizeof("TOOL_") - 1); psz += sizeof("TOOL_") - 1;
1243 memcpy(psz, pTool->value, pTool->value_length); psz += pTool->value_length;
1244 memcpy(psz, "_COMPILE_", sizeof("_COMPILE_") - 1); psz += sizeof("_COMPILE_") - 1;
1245 memcpy(psz, pType->value, pType->value_length); psz += pType->value_length;
1246 pszSrc = psz;
1247
1248 cch = pTarget->value_length + 1 + pSource->value_length + sizeof("_OUTPUT_");
1249 psz = pszDstVar = alloca(cch);
1250 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
1251 *psz++ = '_';
1252 memcpy(psz, pSource->value, pSource->value_length); psz += pSource->value_length;
1253 pszDst = psz;
1254
1255 memcpy(pszSrc, "_CMDS", sizeof("_CMDS"));
1256 memcpy(pszDst, "_CMDS_", sizeof("_CMDS_"));
1257 pVar = kbuild_get_recursive_variable(pszSrcVar);
1258 do_variable_definition(NILF, pszDstVar, pVar->value, o_file, f_simple, 0 /* !target_var */);
1259
1260 memcpy(pszSrc, "_OUTPUT", sizeof("_OUTPUT"));
1261 memcpy(pszDst, "_OUTPUT_", sizeof("_OUTPUT_"));
1262 pVar = kbuild_get_recursive_variable(pszSrcVar);
1263 pOutput = do_variable_definition(NILF, pszDstVar, pVar->value, o_file, f_simple, 0 /* !target_var */);
1264
1265 memcpy(pszSrc, "_DEPEND", sizeof("_DEPEND"));
1266 memcpy(pszDst, "_DEPEND_", sizeof("_DEPEND_"));
1267 pVar = kbuild_get_recursive_variable(pszSrcVar);
1268 psz = pszVal = xmalloc(pVar->value_length + 1 + pDeps->value_length + 1 + pSource->value_length + 1);
1269 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1270 *psz++ = ' ';
1271 memcpy(psz, pDeps->value, pDeps->value_length); psz += pDeps->value_length;
1272 *psz++ = ' ';
1273 memcpy(psz, pSource->value, pSource->value_length + 1);
1274 do_variable_definition(NILF, pszDstVar, pszVal, o_file, f_simple, 0 /* !target_var */);
1275 free(pszVal);
1276
1277 memcpy(pszSrc, "_DEPORD", sizeof("_DEPORD"));
1278 memcpy(pszDst, "_DEPORD_", sizeof("_DEPORD_"));
1279 pVar = kbuild_get_recursive_variable(pszSrcVar);
1280 psz = pszVal = xmalloc(pVar->value_length + 1 + pDirDep->value_length + 1);
1281 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1282 *psz++ = ' ';
1283 memcpy(psz, pDirDep->value, pDirDep->value_length + 1);
1284 do_variable_definition(NILF, pszDstVar, pszVal, o_file, f_simple, 0 /* !target_var */);
1285 free(pszVal);
1286
1287 /*
1288 _OUT_FILES += $($(target)_$(source)_OUTPUT_)
1289 */
1290 pVar = kbuild_get_variable("_OUT_FILES");
1291 psz = pszVal = xmalloc(pVar->value_length + 1 + pOutput->value_length + 1);
1292 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1293 *psz++ = ' ';
1294 memcpy(psz, pOutput->value, pOutput->value_length + 1);
1295 do_variable_definition(NILF, "_OUT_FILES", pszVal, o_file, f_simple, 0 /* !target_var */);
1296 free(pszVal);
1297
1298 /*
1299 $(target)_OBJS_ += $(obj)
1300 */
1301 memcpy(pszDstVar + pTarget->value_length, "_OBJS_", sizeof("_OBJS_"));
1302 do_variable_definition(NILF, pszDstVar, pObj->value, o_file, f_append, 0 /* !target_var */);
1303
1304 /*
1305 $(eval $(def_target_source_rule))
1306 */
1307 pVar = kbuild_get_recursive_variable("def_target_source_rule");
1308 pszVal = allocated_variable_expand(pVar->value);
1309
1310 install_variable_buffer(&pszSavedVarBuf, &cchSavedVarBuf);
1311 eval_buffer(pszVal);
1312 restore_variable_buffer(pszSavedVarBuf, cchSavedVarBuf);
1313
1314 free(pszVal);
1315
1316 kbuild_put_sdks(&Sdks);
1317 return variable_buffer_output(o, "", 1);
1318}
1319
1320
1321#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