VirtualBox

source: kBuild/trunk/src/gmake/kbuild.c@ 803

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

copyright and email updates.

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