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

Last change on this file since 535 was 534, checked in by bird, 19 years ago

Made it build again on linux.

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