source: trunk/src/gmakenew/kbuild.c@ 917

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

PATH_KBUILD and PATH_KBUILD_BIN improvements. Avoid LOCALEDIR, ALIASDIR, LIBDIR and INCLUDEDIR.

  • Property svn:eol-style set to native
File size: 62.8 KB
Line 
1/* $Id: $ */
2/** @file
3 *
4 * kBuild specific make functionality.
5 *
6 * Copyright (c) 2006-2007 knut st. osmundsen <bird-kBuild-spam@anduin.net>
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
30/*******************************************************************************
31* Header Files *
32*******************************************************************************/
33#include "make.h"
34#include "filedef.h"
35#include "variable.h"
36#include "dep.h"
37#include "debug.h"
38
39#include "kbuild.h"
40
41#include <assert.h>
42#include <stdarg.h>
43#ifndef va_copy
44# define va_copy(dst, src) do {(dst) = (src);} while (0)
45#endif
46
47
48/*******************************************************************************
49* Internal Functions *
50*******************************************************************************/
51/* function.c */
52char * abspath(const char *name, char *apath);
53
54/*******************************************************************************
55* Global Variables *
56*******************************************************************************/
57/** The argv[0] passed to main. */
58static const char *g_argv0 = "";
59
60
61/**
62 * Initialize kBuild stuff.
63 *
64 * @param argc Number of arguments to main().
65 * @param argv The main() argument vector.
66 */
67void init_kbuild(int argc, char **argv)
68{
69 g_argv0 = argv[0];
70}
71
72
73/**
74 * Determin the PATH_KBUILD value.
75 *
76 * @returns Pointer to static buffer to be treated as read only!
77 */
78const char *get_path_kbuild(void)
79{
80 static const char *s_pszPath = NULL;
81 if (!s_pszPath)
82 {
83 PATH_VAR(szTmpPath);
84 const char *pszEnvVar = getenv("PATH_KBUILD");
85 if ( !pszEnvVar
86 || !abspath(pszEnvVar, szTmpPath))
87 {
88#ifdef PATH_KBUILD
89 return s_pszPath = PATH_KBUILD;
90#else
91 /* $(abspath $(PATH_KBUILD_BIN)/../..)*/
92 size_t cch = strlen(get_path_kbuild_bin());
93 char *pszTmp2 = alloca(cch + sizeof("/../.."));
94 strcat(strcpy(pszTmp2, get_path_kbuild_bin()), "/../..");
95 if (!abspath(pszTmp2, szTmpPath))
96 fatal(NILF, _("failed to determin PATH_KBUILD"));
97#endif
98 }
99 s_pszPath = xstrdup(szTmpPath);
100 }
101 return s_pszPath;
102}
103
104
105/**
106 * Determin the PATH_KBUILD_BIN value.
107 *
108 * @returns Pointer to static buffer to be treated as read only!
109 */
110const char *get_path_kbuild_bin(void)
111{
112 static const char *s_pszPath = NULL;
113 if (!s_pszPath)
114 {
115 PATH_VAR(szTmpPath);
116 const char *pszEnvVar = getenv("PATH_KBUILD_BIN");
117 if ( !pszEnvVar
118 || !abspath(pszEnvVar, szTmpPath))
119 {
120#ifdef PATH_KBUILD
121 return s_pszPath = PATH_KBUILD_BIN;
122#else
123 /* $(abspath $(ARGV0)/../../..) - the filename shouldn't cause trouble... */
124 size_t cch = strlen(g_argv0);
125 char *pszTmp2 = alloca(cch + sizeof("/../../.."));
126 strcat(strcpy(pszTmp2, g_argv0), "/../../..");
127 if (!abspath(pszTmp2, szTmpPath))
128 fatal(NILF, _("failed to determin PATH_KBUILD_BIN"));
129#endif
130 }
131 s_pszPath = xstrdup(szTmpPath);
132 }
133 return s_pszPath;
134}
135
136
137#ifdef KMK_HELPERS
138
139/**
140 * Applies the specified default path to any relative paths in *ppsz.
141 *
142 * @param pDefPath The default path.
143 * @param ppsz Pointer to the string pointer. If we expand anything, *ppsz
144 * will be replaced and the caller is responsible for calling free() on it.
145 * @param pcch IN: *pcch contains the current string length.
146 * OUT: *pcch contains the new string length.
147 * @param pcchAlloc *pcchAlloc contains the length allocated for the string. Can be NULL.
148 * @param fCanFree Whether *ppsz should be freed when we replace it.
149 */
150static void
151kbuild_apply_defpath(struct variable *pDefPath, char **ppsz, int *pcch, int *pcchAlloc, int fCanFree)
152{
153 char *pszIterator;
154 const char *pszInCur;
155 unsigned int cchInCur;
156 unsigned int cRelativePaths;
157
158 /*
159 * The first pass, count the relative paths.
160 */
161 cRelativePaths = 0;
162 pszIterator = *ppsz;
163 while ((pszInCur = find_next_token(&pszIterator, &cchInCur)))
164 {
165 /* is relative? */
166#ifdef HAVE_DOS_PATHS
167 if (pszInCur[0] != '/' && pszInCur[0] != '\\' && (cchInCur < 2 || pszInCur[1] != ':'))
168#else
169 if (pszInCur[0] != '/')
170#endif
171 cRelativePaths++;
172 }
173
174 /*
175 * The second pass construct the new string.
176 */
177 if (cRelativePaths)
178 {
179 const size_t cchOut = *pcch + cRelativePaths * (pDefPath->value_length + 1) + 1;
180 char *pszOut = xmalloc(cchOut);
181 char *pszOutCur = pszOut;
182 const char *pszInNextCopy = *ppsz;
183
184 cRelativePaths = 0;
185 pszIterator = *ppsz;
186 while ((pszInCur = find_next_token(&pszIterator, &cchInCur)))
187 {
188 /* is relative? */
189#ifdef HAVE_DOS_PATHS
190 if (pszInCur[0] != '/' && pszInCur[0] != '\\' && (cchInCur < 2 || pszInCur[1] != ':'))
191#else
192 if (pszInCur[0] != '/')
193#endif
194 {
195 PATH_VAR(szAbsPathIn);
196 PATH_VAR(szAbsPathOut);
197
198 if (pDefPath->value_length + cchInCur + 1 >= GET_PATH_MAX)
199 continue;
200
201 /* Create the abspath input. */
202 memcpy(szAbsPathIn, pDefPath->value, pDefPath->value_length);
203 szAbsPathIn[pDefPath->value_length] = '/';
204 memcpy(&szAbsPathIn[pDefPath->value_length + 1], pszInCur, cchInCur);
205 szAbsPathIn[pDefPath->value_length + 1 + cchInCur] = '\0';
206
207 if (abspath(szAbsPathIn, szAbsPathOut) != NULL)
208 {
209 const size_t cchAbsPathOut = strlen(szAbsPathOut);
210 assert(cchAbsPathOut <= pDefPath->value_length + 1 + cchInCur);
211
212 /* copy leading input */
213 if (pszInCur != pszInNextCopy)
214 {
215 const size_t cchCopy = pszInCur - pszInNextCopy;
216 memcpy(pszOutCur, pszInNextCopy, cchCopy);
217 pszOutCur += cchCopy;
218 }
219 pszInNextCopy = pszInCur + cchInCur;
220
221 /* copy out the abspath. */
222 memcpy(pszOutCur, szAbsPathOut, cchAbsPathOut);
223 pszOutCur += cchAbsPathOut;
224 }
225 }
226 }
227 /* the final copy (includes the nil). */
228 cchInCur = *ppsz + *pcch - pszInNextCopy;
229 memcpy(pszOutCur, pszInNextCopy, cchInCur);
230 pszOutCur += cchInCur;
231 *pszOutCur = '\0';
232 assert((size_t)(pszOutCur - pszOut) < cchOut);
233
234 /* set return values */
235 if (fCanFree)
236 free(*ppsz);
237 *ppsz = pszOut;
238 *pcch = pszOutCur - pszOut;
239 if (pcchAlloc)
240 *pcchAlloc = cchOut;
241 }
242}
243
244
245/**
246 * Gets a variable that must exist.
247 * Will cause a fatal failure if the variable doesn't exist.
248 *
249 * @returns Pointer to the variable.
250 * @param pszName The variable name.
251 */
252static struct variable *
253kbuild_get_variable(const char *pszName)
254{
255#ifndef NDEBUG
256 unsigned i;
257#endif
258 struct variable *pVar = lookup_variable(pszName, strlen(pszName));
259 if (!pVar)
260 fatal(NILF, _("variable `%s' isn't defined!"), pszName);
261 if (pVar->recursive)
262 fatal(NILF, _("variable `%s' is defined as `recursive' instead of `simple'!"), pszName);
263#ifndef NDEBUG
264 i = strlen(pVar->value);
265 if (i != pVar->value_length)
266 {
267 printf("%d != %d %s\n", pVar->value_length, i, pVar->name);
268# ifdef _MSC_VER
269 __debugbreak();
270# endif
271 assert(0);
272 }
273#endif
274 return pVar;
275}
276
277/**
278 * Gets a variable that must exist and can be recursive.
279 * Will cause a fatal failure if the variable doesn't exist.
280 *
281 * @returns Pointer to the variable.
282 * @param pszName The variable name.
283 */
284static struct variable *
285kbuild_get_recursive_variable(const char *pszName)
286{
287#ifndef NDEBUG
288 unsigned i;
289#endif
290 struct variable *pVar = lookup_variable(pszName, strlen(pszName));
291 if (!pVar)
292 fatal(NILF, _("variable `%s' isn't defined!"), pszName);
293#ifndef NDEBUG
294 i = strlen(pVar->value);
295 if (i != pVar->value_length)
296 {
297 printf("%d != %d %s\n", pVar->value_length, i, pVar->name);
298# ifdef _MSC_VER
299 __debugbreak();
300# endif
301 assert(0);
302 }
303#endif
304 return pVar;
305}
306
307/**
308 * Converts the specified variable into a 'simple' one.
309 * @returns pVar.
310 * @param pVar The variable.
311 */
312static struct variable *
313kbuild_simplify_variable(struct variable *pVar)
314{
315 if (memchr(pVar->value, '$', pVar->value_length))
316 {
317 char *pszExpanded = allocated_variable_expand(pVar->value);
318 free(pVar->value);
319 pVar->value = pszExpanded;
320 pVar->value_length = strlen(pVar->value);
321 pVar->value_alloc_len = pVar->value_length + 1;
322 }
323 pVar->recursive = 0;
324 return pVar;
325}
326
327/**
328 * Looks up a variable.
329 * The value_length field is valid upon successful return.
330 *
331 * @returns Pointer to the variable. NULL if not found.
332 * @param pszName The variable name.
333 */
334static struct variable *
335kbuild_lookup_variable(const char *pszName)
336{
337 struct variable *pVar = lookup_variable(pszName, strlen(pszName));
338 if (pVar)
339 {
340#ifndef NDEBUG
341 unsigned i = strlen(pVar->value);
342 if (i != pVar->value_length)
343 {
344 printf("%d != %d %s\n", pVar->value_length, i, pVar->name);
345# ifdef _MSC_VER
346 __debugbreak();
347# endif
348 assert(0);
349 }
350#endif
351 /* Make sure the variable is simple, convert it if necessary. */
352 if (pVar->recursive)
353 kbuild_simplify_variable(pVar);
354 }
355 return pVar;
356}
357
358/**
359 * Looks up a variable and applies default a path to all relative paths.
360 * The value_length field is valid upon successful return.
361 *
362 * @returns Pointer to the variable. NULL if not found.
363 * @param pDefPath The default path.
364 * @param pszName The variable name.
365 */
366static struct variable *
367kbuild_lookup_variable_defpath(struct variable *pDefPath, const char *pszName)
368{
369 struct variable *pVar = kbuild_lookup_variable(pszName);
370 if (pVar && pDefPath)
371 kbuild_apply_defpath(pDefPath, &pVar->value, &pVar->value_length, &pVar->value_alloc_len, 1);
372 return pVar;
373}
374
375/** Same as kbuild_lookup_variable except that a '%s' in the name string
376 * will be substituted with the values of the variables in the va list. */
377static struct variable *
378kbuild_lookup_variable_fmt_va(struct variable *pDefPath, const char *pszNameFmt, va_list va)
379{
380 va_list va2;
381 size_t cchName;
382 const char *pszFmt;
383 char *pszName;
384 char *psz;
385
386 /* first pass, calc value name size and allocate stack buffer. */
387 va_copy(va2, va);
388
389 cchName = strlen(pszNameFmt) + 1;
390 pszFmt = strchr(pszNameFmt, '%');
391 while (pszFmt)
392 {
393 struct variable *pVar = va_arg(va, struct variable *);
394 if (pVar)
395 cchName += pVar->value_length;
396 pszFmt = strchr(pszFmt + 1, '%');
397 }
398 pszName = alloca(cchName);
399
400 /* second pass format it. */
401 pszFmt = pszNameFmt;
402 psz = pszName;
403 for (;;)
404 {
405 char ch = *pszFmt++;
406 if (ch != '%')
407 {
408 *psz++ = ch;
409 if (!ch)
410 break;
411 }
412 else
413 {
414 struct variable *pVar = va_arg(va2, struct variable *);
415 if (pVar)
416 {
417 memcpy(psz, pVar->value, pVar->value_length);
418 psz += pVar->value_length;
419 }
420 }
421 }
422 va_end(va2);
423
424 if (pDefPath)
425 return kbuild_lookup_variable_defpath(pDefPath, pszName);
426 return kbuild_lookup_variable(pszName);
427}
428
429/** Same as kbuild_lookup_variable except that a '%s' in the name string
430 * will be substituted with the values of the variables in the ellipsis. */
431static struct variable *
432kbuild_lookup_variable_fmt(struct variable *pDefPath, const char *pszNameFmt, ...)
433{
434 struct variable *pVar;
435 va_list va;
436 va_start(va, pszNameFmt);
437 pVar = kbuild_lookup_variable_fmt_va(pDefPath, pszNameFmt, va);
438 va_end(va);
439 return pVar;
440}
441
442/**
443 * Gets the first defined property variable.
444 */
445static struct variable *
446kbuild_first_prop(struct variable *pTarget, struct variable *pSource,
447 struct variable *pTool, struct variable *pType,
448 struct variable *pBldTrg, struct variable *pBldTrgArch,
449 const char *pszPropF1, const char *pszPropF2, const char *pszVarName)
450{
451 struct variable *pVar;
452 struct variable PropF1, PropF2;
453
454 PropF1.value = (char *)pszPropF1;
455 PropF1.value_length = strlen(pszPropF1);
456
457 PropF2.value = (char *)pszPropF2;
458 PropF2.value_length = strlen(pszPropF2);
459
460 if ( (pVar = kbuild_lookup_variable_fmt(NULL, "%_%_%%.%.%",pTarget, pSource, pType, &PropF2, pBldTrg, pBldTrgArch))
461 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%_%%.%", pTarget, pSource, pType, &PropF2, pBldTrg))
462 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%_%%", pTarget, pSource, pType, &PropF2))
463 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%_%.%.%", pTarget, pSource, &PropF2, pBldTrg, pBldTrgArch))
464 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%_%.%", pTarget, pSource, &PropF2, pBldTrg))
465 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%_%", pTarget, pSource, &PropF2))
466 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%%.%.%", pSource, pType, &PropF2, pBldTrg, pBldTrgArch))
467 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%%.%", pSource, pType, &PropF2, pBldTrg))
468 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%%", pSource, pType, &PropF2))
469 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%.%.%", pSource, &PropF2, pBldTrg, pBldTrgArch))
470 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%.%", pSource, &PropF2, pBldTrg))
471 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%", pSource, &PropF2))
472 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%%.%.%", pTarget, pType, &PropF2, pBldTrg, pBldTrgArch))
473 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%%.%", pTarget, pType, &PropF2, pBldTrg))
474 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%%", pTarget, pType, &PropF2))
475 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%.%.%", pTarget, &PropF2, pBldTrg, pBldTrgArch))
476 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%.%", pTarget, &PropF2, pBldTrg))
477 || (pVar = kbuild_lookup_variable_fmt(NULL, "%_%", pTarget, &PropF2))
478
479 || (pTool && (pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%%.%.%", pTool, pType, &PropF2, pBldTrg, pBldTrgArch)))
480 || (pTool && (pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%%.%", pTool, pType, &PropF2, pBldTrg)))
481 || (pTool && (pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%%", pTool, pType, &PropF2)))
482 || (pTool && (pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%.%.%", pTool, &PropF2, pBldTrg, pBldTrgArch)))
483 || (pTool && (pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%.%", pTool, &PropF2, pBldTrg)))
484 || (pTool && (pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%", pTool, &PropF2)))
485
486 || (pVar = kbuild_lookup_variable_fmt(NULL, "%%.%.%", pType, &PropF1, pBldTrg, pBldTrgArch))
487 || (pVar = kbuild_lookup_variable_fmt(NULL, "%%.%", pType, &PropF1, pBldTrg))
488 || (pVar = kbuild_lookup_variable_fmt(NULL, "%%", pType, &PropF1))
489 || (pVar = kbuild_lookup_variable_fmt(NULL, "%.%.%", &PropF1, pBldTrg, pBldTrgArch))
490 || (pVar = kbuild_lookup_variable_fmt(NULL, "%.%", &PropF1, pBldTrg))
491 || (pVar = kbuild_lookup_variable(pszPropF1))
492 )
493 {
494 /* strip it */
495 char *psz = pVar->value;
496 char *pszEnd = psz + pVar->value_length;
497 while (isblank((unsigned char)*psz))
498 psz++;
499 while (pszEnd > psz && isblank((unsigned char)pszEnd[-1]))
500 pszEnd--;
501 if (pszEnd > psz)
502 {
503 char chSaved = *pszEnd;
504 *pszEnd = '\0';
505 pVar = define_variable_vl(pszVarName, strlen(pszVarName), psz, pszEnd - psz,
506 1 /* duplicate */, o_file, 0 /* !recursive */);
507 *pszEnd = chSaved;
508 if (pVar)
509 return pVar;
510 }
511 }
512 return NULL;
513}
514
515/*
516_SOURCE_TOOL = $(strip $(firstword \
517 $($(target)_$(source)_$(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
518 $($(target)_$(source)_$(type)TOOL.$(bld_trg)) \
519 $($(target)_$(source)_$(type)TOOL) \
520 $($(target)_$(source)_TOOL.$(bld_trg).$(bld_trg_arch)) \
521 $($(target)_$(source)_TOOL.$(bld_trg)) \
522 $($(target)_$(source)_TOOL) \
523 $($(source)_$(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
524 $($(source)_$(type)TOOL.$(bld_trg)) \
525 $($(source)_$(type)TOOL) \
526 $($(source)_TOOL.$(bld_trg).$(bld_trg_arch)) \
527 $($(source)_TOOL.$(bld_trg)) \
528 $($(source)_TOOL) \
529 $($(target)_$(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
530 $($(target)_$(type)TOOL.$(bld_trg)) \
531 $($(target)_$(type)TOOL) \
532 $($(target)_TOOL.$(bld_trg).$(bld_trg_arch)) \
533 $($(target)_TOOL.$(bld_trg)) \
534 $($(target)_TOOL) \
535 $($(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
536 $($(type)TOOL.$(bld_trg)) \
537 $($(type)TOOL) \
538 $(TOOL.$(bld_trg).$(bld_trg_arch)) \
539 $(TOOL.$(bld_trg)) \
540 $(TOOL) ))
541*/
542static struct variable *
543kbuild_get_source_tool(struct variable *pTarget, struct variable *pSource, struct variable *pType,
544 struct variable *pBldTrg, struct variable *pBldTrgArch, const char *pszVarName)
545{
546 struct variable *pVar = kbuild_first_prop(pTarget, pSource, NULL, pType, pBldTrg, pBldTrgArch,
547 "TOOL", "TOOL", pszVarName);
548 if (!pVar)
549 fatal(NILF, _("no tool for source `%s' in target `%s'!"), pSource->value, pTarget->value);
550 return pVar;
551}
552
553/* Implements _SOURCE_TOOL. */
554char *
555func_kbuild_source_tool(char *o, char **argv, const char *pszFuncName)
556{
557 struct variable *pVar = kbuild_get_source_tool(kbuild_get_variable("target"),
558 kbuild_get_variable("source"),
559 kbuild_get_variable("type"),
560 kbuild_get_variable("bld_trg"),
561 kbuild_get_variable("bld_trg_arch"),
562 argv[0]);
563 if (pVar)
564 o = variable_buffer_output(o, pVar->value, pVar->value_length);
565 return o;
566
567}
568
569/* This has been extended a bit, it's now identical to _SOURCE_TOOL.
570$(firstword \
571 $($(target)_$(source)_OBJSUFF.$(bld_trg).$(bld_trg_arch))\
572 $($(target)_$(source)_OBJSUFF.$(bld_trg))\
573 $($(target)_$(source)_OBJSUFF)\
574 $($(source)_OBJSUFF.$(bld_trg).$(bld_trg_arch))\
575 $($(source)_OBJSUFF.$(bld_trg))\
576 $($(source)_OBJSUFF)\
577 $($(target)_OBJSUFF.$(bld_trg).$(bld_trg_arch))\
578 $($(target)_OBJSUFF.$(bld_trg))\
579 $($(target)_OBJSUFF)\
580 $(TOOL_$(tool)_$(type)OBJSUFF.$(bld_trg).$(bld_trg_arch))\
581 $(TOOL_$(tool)_$(type)OBJSUFF.$(bld_trg))\
582 $(TOOL_$(tool)_$(type)OBJSUFF)\
583 $(SUFF_OBJ))
584*/
585static struct variable *
586kbuild_get_object_suffix(struct variable *pTarget, struct variable *pSource,
587 struct variable *pTool, struct variable *pType,
588 struct variable *pBldTrg, struct variable *pBldTrgArch, const char *pszVarName)
589{
590 struct variable *pVar = kbuild_first_prop(pTarget, pSource, pTool, pType, pBldTrg, pBldTrgArch,
591 "SUFF_OBJ", "OBJSUFF", pszVarName);
592 if (!pVar)
593 fatal(NILF, _("no OBJSUFF attribute or SUFF_OBJ default for source `%s' in target `%s'!"), pSource->value, pTarget->value);
594 return pVar;
595}
596
597/* */
598char *
599func_kbuild_object_suffix(char *o, char **argv, const char *pszFuncName)
600{
601 struct variable *pVar = kbuild_get_object_suffix(kbuild_get_variable("target"),
602 kbuild_get_variable("source"),
603 kbuild_get_variable("tool"),
604 kbuild_get_variable("type"),
605 kbuild_get_variable("bld_trg"),
606 kbuild_get_variable("bld_trg_arch"),
607 argv[0]);
608 if (pVar)
609 o = variable_buffer_output(o, pVar->value, pVar->value_length);
610 return o;
611
612}
613
614
615/*
616## Figure out where to put object files.
617# @param $1 source file
618# @param $2 normalized main target
619# @remark There are two major hacks here:
620# 1. Source files in the output directory are translated into a gen/ subdir.
621# 2. Catch anyone specifying $(PATH_SUB_CURRENT)/sourcefile.c.
622_OBJECT_BASE = $(PATH_TARGET)/$(2)/$(call no-root-slash,$(call no-drive,$(basename \
623 $(patsubst $(PATH_ROOT)/%,%,$(patsubst $(PATH_SUB_CURRENT)/%,%,$(patsubst $(PATH_TARGET)/$(2)/%,gen/%,$(1)))))))
624*/
625static struct variable *
626kbuild_get_object_base(struct variable *pTarget, struct variable *pSource, const char *pszVarName)
627{
628 struct variable *pPathTarget = kbuild_get_variable("PATH_TARGET");
629 struct variable *pPathRoot = kbuild_get_variable("PATH_ROOT");
630 struct variable *pPathSubCur = kbuild_get_variable("PATH_SUB_CURRENT");
631 const char *pszSrcPrefix = NULL;
632 size_t cchSrcPrefix = 0;
633 const char *pszSrcEnd;
634 char *pszSrc;
635 char *pszResult;
636 char *psz;
637 size_t cch;
638
639 /*
640 * Strip the source filename of any uncessary leading path and root specs.
641 */
642 /* */
643 if ( pSource->value_length > pPathTarget->value_length
644 && !strncmp(pSource->value, pPathTarget->value, pPathTarget->value_length))
645 {
646 pszSrc = pSource->value + pPathTarget->value_length;
647 pszSrcPrefix = "gen/";
648 cchSrcPrefix = sizeof("gen/") - 1;
649 if ( *pszSrc == '/'
650 && !strncmp(pszSrc + 1, pTarget->value, pTarget->value_length)
651 && ( pszSrc[pTarget->value_length + 1] == '/'
652 || pszSrc[pTarget->value_length + 1] == '\0'))
653 pszSrc += 1 + pTarget->value_length;
654 }
655 else if ( pSource->value_length > pPathRoot->value_length
656 && !strncmp(pSource->value, pPathRoot->value, pPathRoot->value_length))
657 {
658 pszSrc = pSource->value + pPathRoot->value_length;
659 if ( *pszSrc == '/'
660 && !strncmp(pszSrc + 1, pPathSubCur->value, pPathSubCur->value_length)
661 && ( pszSrc[pPathSubCur->value_length + 1] == '/'
662 || pszSrc[pPathSubCur->value_length + 1] == '\0'))
663 pszSrc += 1 + pPathSubCur->value_length;
664 }
665 else
666 pszSrc = pSource->value;
667
668 /* skip root specification */
669#ifdef HAVE_DOS_PATHS
670 if (isalpha(pszSrc[0]) && pszSrc[1] == ':')
671 pszSrc += 2;
672#endif
673 while (*pszSrc == '/'
674#ifdef HAVE_DOS_PATHS
675 || *pszSrc == '\\'
676#endif
677 )
678 pszSrc++;
679
680 /* drop the source extension. */
681 pszSrcEnd = pSource->value + pSource->value_length;
682 for (;;)
683 {
684 pszSrcEnd--;
685 if ( pszSrcEnd <= pszSrc
686 || *pszSrcEnd == '/'
687#ifdef HAVE_DOS_PATHS
688 || *pszSrcEnd == '\\'
689 || *pszSrcEnd == ':'
690#endif
691 )
692 {
693 pszSrcEnd = pSource->value + pSource->value_length;
694 break;
695 }
696 if (*pszSrcEnd == '.')
697 break;
698 }
699
700 /*
701 * Assemble the string on the stack and define the objbase variable
702 * which we then return.
703 */
704 cch = pPathTarget->value_length
705 + 1 /* slash */
706 + pTarget->value_length
707 + 1 /* slash */
708 + cchSrcPrefix
709 + pszSrcEnd - pszSrc
710 + 1;
711 psz = pszResult = xmalloc(cch);
712
713 memcpy(psz, pPathTarget->value, pPathTarget->value_length); psz += pPathTarget->value_length;
714 *psz++ = '/';
715 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
716 *psz++ = '/';
717 if (pszSrcPrefix)
718 {
719 memcpy(psz, pszSrcPrefix, cchSrcPrefix);
720 psz += cchSrcPrefix;
721 }
722 memcpy(psz, pszSrc, pszSrcEnd - pszSrc); psz += pszSrcEnd - pszSrc;
723 *psz = '\0';
724
725 /*
726 * Define the variable in the current set and return it.
727 */
728 return define_variable_vl(pszVarName, strlen(pszVarName), pszResult, cch - 1,
729 0 /* use pszResult */, o_file, 0 /* !recursive */);
730}
731
732/* Implements _OBJECT_BASE. */
733char *
734func_kbuild_object_base(char *o, char **argv, const char *pszFuncName)
735{
736 struct variable *pVar = kbuild_get_object_base(kbuild_lookup_variable("target"),
737 kbuild_lookup_variable("source"),
738 argv[0]);
739 if (pVar)
740 o = variable_buffer_output(o, pVar->value, pVar->value_length);
741 return o;
742
743}
744
745
746struct kbuild_sdks
747{
748 char *apsz[4];
749 struct variable *pa;
750 unsigned c;
751 unsigned iGlobal;
752 unsigned cGlobal;
753 unsigned iTarget;
754 unsigned cTarget;
755 unsigned iSource;
756 unsigned cSource;
757 unsigned iTargetSource;
758 unsigned cTargetSource;
759};
760
761/* Fills in the SDK struct (remember to free it). */
762static void
763kbuild_get_sdks(struct kbuild_sdks *pSdks, struct variable *pTarget, struct variable *pSource,
764 struct variable *pBldType, struct variable *pBldTrg, struct variable *pBldTrgArch)
765{
766 int i, j;
767 size_t cchTmp, cch;
768 char *pszTmp;
769 unsigned cchCur;
770 char *pszCur;
771 char *pszIterator;
772
773 /* basic init. */
774 pSdks->pa = NULL;
775 pSdks->c = 0;
776 i = 0;
777
778 /* determin required tmp variable name space. */
779 cchTmp = sizeof("$(__SDKS) $(__SDKS.) $(__SDKS.) $(__SDKS.) $(__SDKS..)")
780 + (pTarget->value_length + pSource->value_length) * 5
781 + pBldType->value_length
782 + pBldTrg->value_length
783 + pBldTrgArch->value_length
784 + pBldTrg->value_length + pBldTrgArch->value_length;
785 pszTmp = alloca(cchTmp);
786
787 /* the global sdks. */
788 pSdks->iGlobal = i;
789 pSdks->cGlobal = 0;
790 sprintf(pszTmp, "$(SDKS) $(SDKS.%s) $(SDKS.%s) $(SDKS.%s) $(SDKS.%s.%s)",
791 pBldType->value,
792 pBldTrg->value,
793 pBldTrgArch->value,
794 pBldTrg->value, pBldTrgArch->value);
795 pszIterator = pSdks->apsz[0] = allocated_variable_expand(pszTmp);
796 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
797 pSdks->cGlobal++;
798 i += pSdks->cGlobal;
799
800 /* the target sdks.*/
801 pSdks->iTarget = i;
802 pSdks->cTarget = 0;
803 sprintf(pszTmp, "$(%s_SDKS) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s.%s)",
804 pTarget->value,
805 pTarget->value, pBldType->value,
806 pTarget->value, pBldTrg->value,
807 pTarget->value, pBldTrgArch->value,
808 pTarget->value, pBldTrg->value, pBldTrgArch->value);
809 pszIterator = pSdks->apsz[1] = allocated_variable_expand(pszTmp);
810 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
811 pSdks->cTarget++;
812 i += pSdks->cTarget;
813
814 /* the source sdks.*/
815 pSdks->iSource = i;
816 pSdks->cSource = 0;
817 sprintf(pszTmp, "$(%s_SDKS) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s.%s)",
818 pSource->value,
819 pSource->value, pBldType->value,
820 pSource->value, pBldTrg->value,
821 pSource->value, pBldTrgArch->value,
822 pSource->value, pBldTrg->value, pBldTrgArch->value);
823 pszIterator = pSdks->apsz[2] = allocated_variable_expand(pszTmp);
824 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
825 pSdks->cSource++;
826 i += pSdks->cSource;
827
828 /* the target + source sdks. */
829 pSdks->iTargetSource = i;
830 pSdks->cTargetSource = 0;
831 cch = sprintf(pszTmp, "$(%s_%s_SDKS) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s.%s)",
832 pTarget->value, pSource->value,
833 pTarget->value, pSource->value, pBldType->value,
834 pTarget->value, pSource->value, pBldTrg->value,
835 pTarget->value, pSource->value, pBldTrgArch->value,
836 pTarget->value, pSource->value, pBldTrg->value, pBldTrgArch->value);
837 assert(cch < cchTmp); (void)cch;
838 pszIterator = pSdks->apsz[3] = allocated_variable_expand(pszTmp);
839 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
840 pSdks->cTargetSource++;
841 i += pSdks->cTargetSource;
842
843 pSdks->c = i;
844 if (!i)
845 return;
846
847 /*
848 * Allocate the variable array and create the variables.
849 */
850 pSdks->pa = (struct variable *)xmalloc(sizeof(pSdks->pa[0]) * i);
851 memset(pSdks->pa, 0, sizeof(pSdks->pa[0]) * i);
852 for (i = j = 0; j < sizeof(pSdks->apsz) / sizeof(pSdks->apsz[0]); j++)
853 {
854 int k = i;
855 pszIterator = pSdks->apsz[j];
856 while ((pszCur = find_next_token(&pszIterator, &cchCur)) != 0)
857 {
858 pSdks->pa[i].value = pszCur;
859 pSdks->pa[i].value_length = cchCur;
860 i++;
861 }
862 }
863 assert(i == pSdks->c);
864
865 /* terminate them (find_next_token won't work if we terminate them in the previous loop). */
866 while (i-- > 0)
867 pSdks->pa[i].value[pSdks->pa[i].value_length] = '\0';
868}
869
870/* releases resources allocated in the kbuild_get_sdks. */
871static void
872kbuild_put_sdks(struct kbuild_sdks *pSdks)
873{
874 unsigned j;
875 for (j = 0; j < sizeof(pSdks->apsz) / sizeof(pSdks->apsz[0]); j++)
876 free(pSdks->apsz[j]);
877 free(pSdks->pa);
878}
879
880/* this kind of stuff:
881
882defs := $(kb-src-exp defs)
883 $(TOOL_$(tool)_DEFS)\
884 $(TOOL_$(tool)_DEFS.$(bld_type))\
885 $(TOOL_$(tool)_DEFS.$(bld_trg))\
886 $(TOOL_$(tool)_DEFS.$(bld_trg_arch))\
887 $(TOOL_$(tool)_DEFS.$(bld_trg).$(bld_trg_arch))\
888 $(TOOL_$(tool)_DEFS.$(bld_trg_cpu))\
889 $(TOOL_$(tool)_$(type)DEFS)\
890 $(TOOL_$(tool)_$(type)DEFS.$(bld_type))\
891 $(foreach sdk, $(SDKS.$(bld_trg)) \
892 $(SDKS.$(bld_trg).$(bld_trg_arch)) \
893 $(SDKS.$(bld_type)) \
894 $(SDKS),\
895 $(SDK_$(sdk)_DEFS)\
896 $(SDK_$(sdk)_DEFS.$(bld_type))\
897 $(SDK_$(sdk)_DEFS.$(bld_trg))\
898 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
899 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
900 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
901 $(SDK_$(sdk)_$(type)DEFS)\
902 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
903 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
904 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
905 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
906 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
907 $(DEFS)\
908 $(DEFS.$(bld_type))\
909 $(DEFS.$(bld_trg))\
910 $(DEFS.$(bld_trg_arch))\
911 $(DEFS.$(bld_trg).$(bld_trg_arch))\
912 $(DEFS.$(bld_trg_cpu))\
913 $($(type)DEFS)\
914 $($(type)DEFS.$(bld_type))\
915 $($(type)DEFS.$(bld_trg))\
916 $($(type)DEFS.$(bld_trg_arch))\
917 $($(type)DEFS.$(bld_trg).$(bld_trg_arch))\
918 $($(type)DEFS.$(bld_trg_cpu))\
919 $(foreach sdk, $($(target)_SDKS.$(bld_trg)) \
920 $($(target)_SDKS.$(bld_trg).$(bld_trg_arch)) \
921 $($(target)_SDKS.$(bld_type)) \
922 $($(target)_SDKS),\
923 $(SDK_$(sdk)_DEFS)\
924 $(SDK_$(sdk)_DEFS.$(bld_type))\
925 $(SDK_$(sdk)_DEFS.$(bld_trg))\
926 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
927 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
928 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
929 $(SDK_$(sdk)_$(type)DEFS)\
930 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
931 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
932 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
933 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
934 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
935 $($(target)_DEFS)\
936 $($(target)_DEFS.$(bld_type))\
937 $($(target)_DEFS.$(bld_trg))\
938 $($(target)_DEFS.$(bld_trg_arch))\
939 $($(target)_DEFS.$(bld_trg).$(bld_trg_arch))\
940 $($(target)_DEFS.$(bld_trg_cpu))\
941 $($(target)_$(type)DEFS)\
942 $($(target)_$(type)DEFS.$(bld_type))\
943 $($(target)_$(type)DEFS.$(bld_trg))\
944 $($(target)_$(type)DEFS.$(bld_trg_arch))\
945 $($(target)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
946 $($(target)_$(type)DEFS.$(bld_trg_cpu))\
947 $(foreach sdk, $($(source)_SDKS.$(bld_trg)) \
948 $($(source)_SDKS.$(bld_trg).$(bld_trg_arch)) \
949 $($(source)_SDKS.$(bld_type)) \
950 $($(source)_SDKS),\
951 $(SDK_$(sdk)_DEFS)\
952 $(SDK_$(sdk)_DEFS.$(bld_type))\
953 $(SDK_$(sdk)_DEFS.$(bld_trg))\
954 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
955 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
956 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
957 $(SDK_$(sdk)_$(type)DEFS)\
958 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
959 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
960 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
961 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
962 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
963 $($(source)_DEFS)\
964 $($(source)_DEFS.$(bld_type))\
965 $($(source)_DEFS.$(bld_trg))\
966 $($(source)_DEFS.$(bld_trg_arch))\
967 $($(source)_DEFS.$(bld_trg).$(bld_trg_arch))\
968 $($(source)_DEFS.$(bld_trg_cpu))\
969 $($(source)_$(type)DEFS)\
970 $($(source)_$(type)DEFS.$(bld_type))\
971 $($(source)_$(type)DEFS.$(bld_trg))\
972 $($(source)_$(type)DEFS.$(bld_trg_arch))\
973 $($(source)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
974 $($(source)_$(type)DEFS.$(bld_trg_cpu))\
975 $(foreach sdk, $($(target)_$(source)_SDKS.$(bld_trg)) \
976 $($(target)_$(source)_SDKS.$(bld_trg).$(bld_trg_arch)) \
977 $($(target)_$(source)_SDKS.$(bld_type)) \
978 $($(target)_$(source)_SDKS),\
979 $(SDK_$(sdk)_DEFS)\
980 $(SDK_$(sdk)_DEFS.$(bld_type))\
981 $(SDK_$(sdk)_DEFS.$(bld_trg))\
982 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
983 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
984 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
985 $(SDK_$(sdk)_$(type)DEFS)\
986 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
987 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
988 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
989 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
990 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
991 $($(target)_$(source)_DEFS)\
992 $($(target)_$(source)_DEFS.$(bld_type))\
993 $($(target)_$(source)_DEFS.$(bld_trg))\
994 $($(target)_$(source)_DEFS.$(bld_trg_arch))\
995 $($(target)_$(source)_DEFS.$(bld_trg).$(bld_trg_arch))\
996 $($(target)_$(source)_DEFS.$(bld_trg_cpu))\
997 $($(target)_$(source)_$(type)DEFS)\
998 $($(target)_$(source)_$(type)DEFS.$(bld_type))\
999 $($(target)_$(source)_$(type)DEFS.$(bld_trg))\
1000 $($(target)_$(source)_$(type)DEFS.$(bld_trg_arch))\
1001 $($(target)_$(source)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
1002 $($(target)_$(source)_$(type)DEFS.$(bld_trg_cpu))
1003*/
1004static struct variable *
1005kbuild_collect_source_prop(struct variable *pTarget, struct variable *pSource,
1006 struct variable *pTool, struct kbuild_sdks *pSdks,
1007 struct variable *pType, struct variable *pBldType,
1008 struct variable *pBldTrg, struct variable *pBldTrgArch, struct variable *pBldTrgCpu,
1009 struct variable *pDefPath,
1010 const char *pszProp, const char *pszVarName, int iDirection)
1011{
1012 struct variable *pVar;
1013 unsigned iSdk, iSdkEnd;
1014 int cVars, iVar, iVarEnd;
1015 size_t cchTotal;
1016 char *pszResult, *psz;
1017 struct
1018 {
1019 struct variable *pVar;
1020 int cchExp;
1021 char *pszExp;
1022 } *paVars;
1023
1024 struct variable Prop = {0};
1025 Prop.value = (char *)pszProp;
1026 Prop.value_length = strlen(pszProp);
1027
1028 assert(iDirection == 1 || iDirection == -1);
1029
1030 /*
1031 * Get the variables.
1032 */
1033 cVars = 12 * (pSdks->c + 5);
1034 paVars = alloca(cVars * sizeof(paVars[0]));
1035
1036 iVar = 0;
1037 /* the tool (lowest priority) */
1038 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%", pTool, &Prop);
1039 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%.%", pTool, &Prop, pBldType);
1040 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%.%", pTool, &Prop, pBldTrg);
1041 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%.%", pTool, &Prop, pBldTrgArch);
1042 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%.%.%", pTool, &Prop, pBldTrg, pBldTrgArch);
1043 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%.%", pTool, &Prop, pBldTrgCpu);
1044
1045 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%%", pTool, pType, &Prop);
1046 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%%.%", pTool, pType, &Prop, pBldType);
1047 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%%.%", pTool, pType, &Prop, pBldTrg);
1048 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%%.%", pTool, pType, &Prop, pBldTrgArch);
1049 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%%.%.%", pTool, pType, &Prop, pBldTrg, pBldTrgArch);
1050 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "TOOL_%_%%.%", pTool, pType, &Prop, pBldTrgCpu);
1051
1052 /* the global sdks */
1053 iSdkEnd = iDirection == 1 ? pSdks->iGlobal + pSdks->cGlobal : pSdks->iGlobal - 1;
1054 for (iSdk = iDirection == 1 ? pSdks->iGlobal : pSdks->iGlobal + pSdks->cGlobal - 1;
1055 iSdk != iSdkEnd;
1056 iSdk += iDirection)
1057 {
1058 struct variable *pSdk = &pSdks->pa[iSdk];
1059 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%", pSdk, &Prop);
1060 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldType);
1061 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrg);
1062 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
1063 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
1064 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
1065
1066 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%", pSdk, pType, &Prop);
1067 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
1068 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
1069 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
1070 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
1071 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
1072 }
1073
1074 /* the globals */
1075 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%", &Prop);
1076 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%.%", &Prop, pBldType);
1077 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%.%", &Prop, pBldTrg);
1078 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%.%", &Prop, pBldTrgArch);
1079 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%.%.%", &Prop, pBldTrg, pBldTrgArch);
1080 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%.%", &Prop, pBldTrgCpu);
1081
1082 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%%", pType, &Prop);
1083 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%%.%", pType, &Prop, pBldType);
1084 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%%.%", pType, &Prop, pBldTrg);
1085 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%%.%", pType, &Prop, pBldTrgArch);
1086 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%%.%.%", pType, &Prop, pBldTrg, pBldTrgArch);
1087 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "%%.%", pType, &Prop, pBldTrgCpu);
1088
1089 /* the target sdks */
1090 iSdkEnd = iDirection == 1 ? pSdks->iTarget + pSdks->cTarget : pSdks->iTarget - 1;
1091 for (iSdk = iDirection == 1 ? pSdks->iTarget : pSdks->iTarget + pSdks->cTarget - 1;
1092 iSdk != iSdkEnd;
1093 iSdk += iDirection)
1094 {
1095 struct variable *pSdk = &pSdks->pa[iSdk];
1096 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%", pSdk, &Prop);
1097 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldType);
1098 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrg);
1099 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
1100 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
1101 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
1102
1103 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%", pSdk, pType, &Prop);
1104 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
1105 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
1106 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
1107 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
1108 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
1109 }
1110
1111 /* the target */
1112 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%", pTarget, &Prop);
1113 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%.%", pTarget, &Prop, pBldType);
1114 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%.%", pTarget, &Prop, pBldTrg);
1115 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%.%", pTarget, &Prop, pBldTrgArch);
1116 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%.%.%", pTarget, &Prop, pBldTrg, pBldTrgArch);
1117 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%.%", pTarget, &Prop, pBldTrgCpu);
1118
1119 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%", pTarget, pType, &Prop);
1120 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%.%", pTarget, pType, &Prop, pBldType);
1121 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%.%", pTarget, pType, &Prop, pBldTrg);
1122 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%.%", pTarget, pType, &Prop, pBldTrgArch);
1123 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%.%.%", pTarget, pType, &Prop, pBldTrg, pBldTrgArch);
1124 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%.%", pTarget, pType, &Prop, pBldTrgCpu);
1125
1126 /* the source sdks */
1127 iSdkEnd = iDirection == 1 ? pSdks->iSource + pSdks->cSource : pSdks->iSource - 1;
1128 for (iSdk = iDirection == 1 ? pSdks->iSource : pSdks->iSource + pSdks->cSource - 1;
1129 iSdk != iSdkEnd;
1130 iSdk += iDirection)
1131 {
1132 struct variable *pSdk = &pSdks->pa[iSdk];
1133 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%", pSdk, &Prop);
1134 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldType);
1135 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrg);
1136 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
1137 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
1138 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
1139
1140 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%", pSdk, pType, &Prop);
1141 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
1142 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
1143 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
1144 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
1145 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
1146 }
1147
1148 /* the source */
1149 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%", pSource, &Prop);
1150 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%.%", pSource, &Prop, pBldType);
1151 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%.%", pSource, &Prop, pBldTrg);
1152 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%.%", pSource, &Prop, pBldTrgArch);
1153 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%.%.%", pSource, &Prop, pBldTrg, pBldTrgArch);
1154 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%.%", pSource, &Prop, pBldTrgCpu);
1155
1156 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%", pSource, pType, &Prop);
1157 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%.%", pSource, pType, &Prop, pBldType);
1158 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%.%", pSource, pType, &Prop, pBldTrg);
1159 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%.%", pSource, pType, &Prop, pBldTrgArch);
1160 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%.%.%", pSource, pType, &Prop, pBldTrg, pBldTrgArch);
1161 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%%.%", pSource, pType, &Prop, pBldTrgCpu);
1162
1163
1164 /* the target + source sdks */
1165 iSdkEnd = iDirection == 1 ? pSdks->iTargetSource + pSdks->cTargetSource : pSdks->iTargetSource - 1;
1166 for (iSdk = iDirection == 1 ? pSdks->iTargetSource : pSdks->iTargetSource + pSdks->cTargetSource - 1;
1167 iSdk != iSdkEnd;
1168 iSdk += iDirection)
1169 {
1170 struct variable *pSdk = &pSdks->pa[iSdk];
1171 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%", pSdk, &Prop);
1172 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldType);
1173 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrg);
1174 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrgArch);
1175 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%.%", pSdk, &Prop, pBldTrg, pBldTrgArch);
1176 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%.%", pSdk, &Prop, pBldTrgCpu);
1177
1178 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%", pSdk, pType, &Prop);
1179 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldType);
1180 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrg);
1181 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgArch);
1182 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%.%", pSdk, pType, &Prop, pBldTrg, pBldTrgArch);
1183 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(NULL, "SDK_%_%%.%", pSdk, pType, &Prop, pBldTrgCpu);
1184 }
1185
1186 /* the target + source */
1187 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%", pTarget, pSource, &Prop);
1188 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%.%", pTarget, pSource, &Prop, pBldType);
1189 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%.%", pTarget, pSource, &Prop, pBldTrg);
1190 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%.%", pTarget, pSource, &Prop, pBldTrgArch);
1191 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%.%.%", pTarget, pSource, &Prop, pBldTrg, pBldTrgArch);
1192 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%.%", pTarget, pSource, &Prop, pBldTrgCpu);
1193
1194 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%%", pTarget, pSource, pType, &Prop);
1195 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%%.%", pTarget, pSource, pType, &Prop, pBldType);
1196 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrg);
1197 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrgArch);
1198 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%%.%.%", pTarget, pSource, pType, &Prop, pBldTrg, pBldTrgArch);
1199 paVars[iVar++].pVar = kbuild_lookup_variable_fmt(pDefPath, "%_%_%%.%", pTarget, pSource, pType, &Prop, pBldTrgCpu);
1200
1201 assert(cVars == iVar);
1202
1203 /*
1204 * Expand the variables and calculate the total length.
1205 */
1206 cchTotal = 0;
1207 iVarEnd = iDirection == 1 ? cVars : 0;
1208 for (iVar = iDirection == 1 ? 0 : cVars - 1; iVar != iVarEnd; iVar += iDirection)
1209 {
1210 paVars[iVar].cchExp = 0;
1211 if (!paVars[iVar].pVar)
1212 continue;
1213 if ( paVars[iVar].pVar->flavor == f_simple
1214 || !strchr(paVars[iVar].pVar->value, '$'))
1215 {
1216 paVars[iVar].pszExp = paVars[iVar].pVar->value;
1217 paVars[iVar].cchExp = paVars[iVar].pVar->value_length;
1218 }
1219 else
1220 {
1221 paVars[iVar].pszExp = allocated_variable_expand(paVars[iVar].pVar->value);
1222 paVars[iVar].cchExp = strlen(paVars[iVar].pszExp);
1223 }
1224 if (pDefPath)
1225 kbuild_apply_defpath(pDefPath, &paVars[iVar].pszExp, &paVars[iVar].cchExp, NULL,
1226 paVars[iVar].pszExp != paVars[iVar].pVar->value);
1227 cchTotal += paVars[iVar].cchExp + 1;
1228 }
1229
1230 /*
1231 * Construct the result value.
1232 */
1233 psz = pszResult = xmalloc(cchTotal + 1);
1234 iVarEnd = iDirection == 1 ? cVars : 0;
1235 for (iVar = iDirection == 1 ? 0 : cVars - 1; iVar != iVarEnd; iVar += iDirection)
1236 {
1237 if (!paVars[iVar].cchExp)
1238 continue;
1239 memcpy(psz, paVars[iVar].pszExp, paVars[iVar].cchExp);
1240 psz += paVars[iVar].cchExp;
1241 *psz++ = ' ';
1242 if (paVars[iVar].pszExp != paVars[iVar].pVar->value)
1243 free(paVars[iVar].pszExp);
1244 }
1245 if (psz != pszResult)
1246 psz--;
1247 *psz = '\0';
1248 cchTotal = psz - pszResult;
1249
1250 pVar = define_variable_vl(pszVarName, strlen(pszVarName), pszResult, cchTotal,
1251 0 /* take pszResult */ , o_file, 0 /* !recursive */);
1252 return pVar;
1253}
1254
1255/* get a source property. Doesn't respect the default path. */
1256char *
1257func_kbuild_source_prop(char *o, char **argv, const char *pszFuncName)
1258{
1259 struct variable *pTarget = kbuild_get_variable("target");
1260 struct variable *pSource = kbuild_get_variable("source");
1261 struct variable *pDefPath = NULL;
1262 struct variable *pType = kbuild_get_variable("type");
1263 struct variable *pTool = kbuild_get_variable("tool");
1264 struct variable *pBldType = kbuild_get_variable("bld_type");
1265 struct variable *pBldTrg = kbuild_get_variable("bld_trg");
1266 struct variable *pBldTrgArch = kbuild_get_variable("bld_trg_arch");
1267 struct variable *pBldTrgCpu = kbuild_get_variable("bld_trg_cpu");
1268 struct variable *pVar;
1269 struct kbuild_sdks Sdks;
1270 int iDirection;
1271 if (!strcmp(argv[2], "left-to-right"))
1272 iDirection = 1;
1273 else if (!strcmp(argv[2], "right-to-left"))
1274 iDirection = -1;
1275 else
1276 fatal(NILF, _("incorrect direction argument `%s'!"), argv[2]);
1277 if (argv[3])
1278 pDefPath = kbuild_get_variable("defpath");
1279
1280 kbuild_get_sdks(&Sdks, pTarget, pSource, pBldType, pBldTrg, pBldTrgArch);
1281
1282 pVar = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType,
1283 pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu,
1284 pDefPath,
1285 argv[0], argv[1], iDirection);
1286 if (pVar)
1287 o = variable_buffer_output(o, pVar->value, pVar->value_length);
1288
1289 kbuild_put_sdks(&Sdks);
1290 return o;
1291
1292}
1293
1294/*
1295dep := $(obj)$(SUFF_DEP)
1296obj := $(outbase)$(objsuff)
1297dirdep := $(call DIRDEP,$(dir $(outbase)))
1298PATH_$(target)_$(source) := $(patsubst %/,%,$(dir $(outbase)))
1299*/
1300static struct variable *
1301kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(struct variable *pTarget, struct variable *pSource,
1302 struct variable *pOutBase, struct variable *pObjSuff,
1303 const char *pszVarName, struct variable **ppDep,
1304 struct variable **ppDirDep)
1305{
1306 struct variable *pDepSuff = kbuild_get_variable("SUFF_DEP");
1307 struct variable *pObj;
1308 size_t cch = pOutBase->value_length + pObjSuff->value_length + pDepSuff->value_length + 1;
1309 char *pszResult = alloca(cch);
1310 char *pszName, *psz;
1311
1312 /*
1313 * dep.
1314 */
1315 psz = pszResult;
1316 memcpy(psz, pOutBase->value, pOutBase->value_length); psz += pOutBase->value_length;
1317 memcpy(psz, pObjSuff->value, pObjSuff->value_length); psz += pObjSuff->value_length;
1318 memcpy(psz, pDepSuff->value, pDepSuff->value_length + 1);
1319 *ppDep = define_variable_vl("dep", 3, pszResult, cch - 1, 1 /*dup*/, o_file, 0 /* !recursive */);
1320
1321 /*
1322 * obj
1323 */
1324 *psz = '\0';
1325 pObj = define_variable_vl(pszVarName, strlen(pszVarName), pszResult, psz - pszResult,
1326 1/* dup */, o_file, 0 /* !recursive */);
1327
1328 /*
1329 * PATH_$(target)_$(source) - this is global!
1330 */
1331 /* calc variable name. */
1332 cch = sizeof("PATH_")-1 + pTarget->value_length + sizeof("_")-1 + pSource->value_length;
1333 psz = pszName = alloca(cch + 1);
1334 memcpy(psz, "PATH_", sizeof("PATH_") - 1); psz += sizeof("PATH_") - 1;
1335 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
1336 *psz++ = '_';
1337 memcpy(psz, pSource->value, pSource->value_length + 1);
1338
1339 /* strip off the filename. */
1340 psz = pszResult + pOutBase->value_length;
1341 for (;;)
1342 {
1343 psz--;
1344 if (psz <= pszResult)
1345 fatal(NULL, "whut!?! no path? result=`%s'", pszResult);
1346#ifdef HAVE_DOS_PATHS
1347 if (*psz == ':')
1348 {
1349 psz++;
1350 break;
1351 }
1352#endif
1353 if ( *psz == '/'
1354#ifdef HAVE_DOS_PATHS
1355 || *psz == '\\'
1356#endif
1357 )
1358 {
1359 while ( psz - 1 > pszResult
1360 && psz[-1] == '/'
1361#ifdef HAVE_DOS_PATHS
1362 || psz[-1] == '\\'
1363#endif
1364 )
1365 psz--;
1366#ifdef HAVE_DOS_PATHS
1367 if (psz == pszResult + 2 && pszResult[1] == ':')
1368 psz++;
1369#endif
1370 break;
1371 }
1372 }
1373 *psz = '\0';
1374
1375 /* set global variable */
1376 define_variable_vl_global(pszName, cch, pszResult, psz - pszResult, 1/*dup*/, o_file, 0 /* !recursive */, NILF);
1377
1378 /*
1379 * dirdep
1380 */
1381 if ( psz[-1] != '/'
1382#ifdef HAVE_DOS_PATHS
1383 && psz[-1] != '\\'
1384 && psz[-1] != ':'
1385#endif
1386 )
1387 {
1388 *psz++ = '/';
1389 *psz = '\0';
1390 }
1391 *ppDirDep = define_variable_vl("dirdep", 6, pszResult, psz - pszResult, 1/*dup*/, o_file, 0 /* !recursive */);
1392
1393 return pObj;
1394}
1395
1396
1397/* setup the base variables for def_target_source_c_cpp_asm_new:
1398
1399X := $(kb-src-tool tool)
1400x := $(kb-obj-base outbase)
1401x := $(kb-obj-suff objsuff)
1402obj := $(outbase)$(objsuff)
1403PATH_$(target)_$(source) := $(patsubst %/,%,$(dir $(outbase)))
1404
1405x := $(kb-src-prop DEFS,defs,left-to-right)
1406x := $(kb-src-prop INCS,incs,right-to-left)
1407x := $(kb-src-prop FLAGS,flags,right-to-left)
1408
1409x := $(kb-src-prop DEPS,deps,left-to-right)
1410dirdep := $(call DIRDEP,$(dir $(outbase)))
1411dep := $(obj)$(SUFF_DEP)
1412*/
1413char *
1414func_kbuild_source_one(char *o, char **argv, const char *pszFuncName)
1415{
1416 static int s_fNoCompileCmdsDepsDefined = -1;
1417 struct variable *pTarget = kbuild_get_variable("target");
1418 struct variable *pSource = kbuild_get_variable("source");
1419 struct variable *pDefPath = kbuild_get_variable("defpath");
1420 struct variable *pType = kbuild_get_variable("type");
1421 struct variable *pBldType = kbuild_get_variable("bld_type");
1422 struct variable *pBldTrg = kbuild_get_variable("bld_trg");
1423 struct variable *pBldTrgArch= kbuild_get_variable("bld_trg_arch");
1424 struct variable *pBldTrgCpu = kbuild_get_variable("bld_trg_cpu");
1425 struct variable *pTool = kbuild_get_source_tool(pTarget, pSource, pType, pBldTrg, pBldTrgArch, "tool");
1426 struct variable *pOutBase = kbuild_get_object_base(pTarget, pSource, "outbase");
1427 struct variable *pObjSuff = kbuild_get_object_suffix(pTarget, pSource, pTool, pType, pBldTrg, pBldTrgArch, "objsuff");
1428 struct variable *pDefs, *pIncs, *pFlags, *pDeps, *pOrderDeps, *pDirDep, *pDep, *pVar, *pOutput;
1429 struct variable *pObj = kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(pTarget, pSource, pOutBase, pObjSuff, "obj", &pDep, &pDirDep);
1430 char *pszDstVar, *pszDst, *pszSrcVar, *pszSrc, *pszVal, *psz;
1431 char *pszSavedVarBuf;
1432 unsigned cchSavedVarBuf;
1433 size_t cch;
1434 struct kbuild_sdks Sdks;
1435
1436 /*
1437 * Gather properties.
1438 */
1439 kbuild_get_sdks(&Sdks, pTarget, pSource, pBldType, pBldTrg, pBldTrgArch);
1440
1441 if (pDefPath && !pDefPath->value_length)
1442 pDefPath = NULL;
1443 pDefs = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, NULL,
1444 "DEFS", "defs", 1/* left-to-right */);
1445 pIncs = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, pDefPath,
1446 "INCS", "incs", -1/* right-to-left */);
1447 pFlags = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, NULL,
1448 "FLAGS", "flags", 1/* left-to-right */);
1449 pDeps = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, pDefPath,
1450 "DEPS", "deps", 1/* left-to-right */);
1451 pOrderDeps = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, pDefPath,
1452 "ORDERDEPS", "orderdeps", 1/* left-to-right */);
1453
1454 /*
1455 * If we've got a default path, we must expand the source now.
1456 * If we do this too early, "<source>_property = stuff" won't work becuase
1457 * our 'source' value isn't what the user expects.
1458 */
1459 if (pDefPath)
1460 kbuild_apply_defpath(pDefPath, &pSource->value, &pSource->value_length, &pSource->value_alloc_len, 1 /* can free */);
1461
1462 /*
1463 # dependencies
1464 ifndef NO_COMPILE_CMDS_DEPS
1465 _DEPFILES_INCLUDED += $(dep)
1466 $(if $(wildcard $(dep)),$(eval include $(dep)))
1467 endif
1468 */
1469 if (s_fNoCompileCmdsDepsDefined == -1)
1470 s_fNoCompileCmdsDepsDefined = kbuild_lookup_variable("NO_COMPILE_CMDS_DEPS") != NULL;
1471 if (!s_fNoCompileCmdsDepsDefined)
1472 {
1473 do_variable_definition(NILF, "_DEPFILES_INCLUDED", pDep->value, o_file, f_append, 0 /* !target_var */);
1474 eval_include_dep(pDep->value, NILF);
1475 }
1476
1477 /*
1478 # call the tool
1479 $(target)_$(source)_CMDS_ := $(TOOL_$(tool)_COMPILE_$(type)_CMDS)
1480 $(target)_$(source)_OUTPUT_ := $(TOOL_$(tool)_COMPILE_$(type)_OUTPUT)
1481 $(target)_$(source)_DEPEND_ := $(TOOL_$(tool)_COMPILE_$(type)_DEPEND) $(deps) $(source)
1482 $(target)_$(source)_DEPORD_ := $(TOOL_$(tool)_COMPILE_$(type)_DEPORD) $(dirdep)
1483 */
1484 cch = sizeof("TOOL_") + pTool->value_length + sizeof("_COMPILE_") + pType->value_length + sizeof("_OUTPUT");
1485 psz = pszSrcVar = alloca(cch);
1486 memcpy(psz, "TOOL_", sizeof("TOOL_") - 1); psz += sizeof("TOOL_") - 1;
1487 memcpy(psz, pTool->value, pTool->value_length); psz += pTool->value_length;
1488 memcpy(psz, "_COMPILE_", sizeof("_COMPILE_") - 1); psz += sizeof("_COMPILE_") - 1;
1489 memcpy(psz, pType->value, pType->value_length); psz += pType->value_length;
1490 pszSrc = psz;
1491
1492 cch = pTarget->value_length + 1 + pSource->value_length + sizeof("_OUTPUT_");
1493 psz = pszDstVar = alloca(cch);
1494 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length;
1495 *psz++ = '_';
1496 memcpy(psz, pSource->value, pSource->value_length); psz += pSource->value_length;
1497 pszDst = psz;
1498
1499 memcpy(pszSrc, "_CMDS", sizeof("_CMDS"));
1500 memcpy(pszDst, "_CMDS_", sizeof("_CMDS_"));
1501 pVar = kbuild_get_recursive_variable(pszSrcVar);
1502 do_variable_definition(NILF, pszDstVar, pVar->value, o_file, f_simple, 0 /* !target_var */);
1503
1504 memcpy(pszSrc, "_OUTPUT", sizeof("_OUTPUT"));
1505 memcpy(pszDst, "_OUTPUT_", sizeof("_OUTPUT_"));
1506 pVar = kbuild_get_recursive_variable(pszSrcVar);
1507 pOutput = do_variable_definition(NILF, pszDstVar, pVar->value, o_file, f_simple, 0 /* !target_var */);
1508
1509 memcpy(pszSrc, "_DEPEND", sizeof("_DEPEND"));
1510 memcpy(pszDst, "_DEPEND_", sizeof("_DEPEND_"));
1511 pVar = kbuild_get_recursive_variable(pszSrcVar);
1512 psz = pszVal = xmalloc(pVar->value_length + 1 + pDeps->value_length + 1 + pSource->value_length + 1);
1513 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1514 *psz++ = ' ';
1515 memcpy(psz, pDeps->value, pDeps->value_length); psz += pDeps->value_length;
1516 *psz++ = ' ';
1517 memcpy(psz, pSource->value, pSource->value_length + 1);
1518 do_variable_definition(NILF, pszDstVar, pszVal, o_file, f_simple, 0 /* !target_var */);
1519 free(pszVal);
1520
1521 memcpy(pszSrc, "_DEPORD", sizeof("_DEPORD"));
1522 memcpy(pszDst, "_DEPORD_", sizeof("_DEPORD_"));
1523 pVar = kbuild_get_recursive_variable(pszSrcVar);
1524 psz = pszVal = xmalloc(pVar->value_length + 1 + pDirDep->value_length + 1 + pOrderDeps->value_length + 1);
1525 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1526 *psz++ = ' ';
1527 memcpy(psz, pDirDep->value, pDirDep->value_length); psz += pDirDep->value_length;
1528 *psz++ = ' ';
1529 memcpy(psz, pOrderDeps->value, pOrderDeps->value_length + 1);
1530 do_variable_definition(NILF, pszDstVar, pszVal, o_file, f_simple, 0 /* !target_var */);
1531 free(pszVal);
1532
1533 /*
1534 _OUT_FILES += $($(target)_$(source)_OUTPUT_)
1535 */
1536 pVar = kbuild_get_variable("_OUT_FILES");
1537 psz = pszVal = xmalloc(pVar->value_length + 1 + pOutput->value_length + 1);
1538 memcpy(psz, pVar->value, pVar->value_length); psz += pVar->value_length;
1539 *psz++ = ' ';
1540 memcpy(psz, pOutput->value, pOutput->value_length + 1);
1541 do_variable_definition(NILF, "_OUT_FILES", pszVal, o_file, f_simple, 0 /* !target_var */);
1542 free(pszVal);
1543
1544 /*
1545 $(target)_OBJS_ += $(obj)
1546 */
1547 memcpy(pszDstVar + pTarget->value_length, "_OBJS_", sizeof("_OBJS_"));
1548 do_variable_definition(NILF, pszDstVar, pObj->value, o_file, f_append, 0 /* !target_var */);
1549
1550 /*
1551 $(eval $(def_target_source_rule))
1552 */
1553 pVar = kbuild_get_recursive_variable("def_target_source_rule");
1554 pszVal = allocated_variable_expand(pVar->value);
1555
1556 install_variable_buffer(&pszSavedVarBuf, &cchSavedVarBuf);
1557 eval_buffer(pszVal);
1558 restore_variable_buffer(pszSavedVarBuf, cchSavedVarBuf);
1559
1560 free(pszVal);
1561
1562 kbuild_put_sdks(&Sdks);
1563 return variable_buffer_output(o, "", 1);
1564}
1565
1566
1567#endif /* KMK_HELPERS */
1568
Note: See TracBrowser for help on using the repository browser.