VirtualBox

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

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

fixed some OBJSUFF and TOOL variable name typos. Drop the expansion checks in the same two function since kbuild_lookup_varaible*() does it.

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