VirtualBox

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

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

Fixed missing expansion in kbuild_lookup_variable.

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

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