VirtualBox

source: kBuild/trunk/src/kmk/kbuild.c@ 948

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

oops.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette