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

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

simpler.

File size: 52.1 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 * 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,
570 pTarget->value, pBldType->value,
571 pTarget->value, pBldTrg->value,
572 pTarget->value, pBldTrg->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,
583 pSource->value, pBldType->value,
584 pSource->value, pBldTrg->value,
585 pSource->value, pBldTrg->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,
596 pTarget->value, pSource->value, pBldType->value,
597 pTarget->value, pSource->value, pBldTrg->value,
598 pTarget->value, pSource->value, pBldTrg->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 + 5);
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 = sizeof("PATH_")-1 + pTarget->value_length + sizeof("_")-1 + pSource->value_length;
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.