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

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

a couple of fixes.

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