VirtualBox

source: kBuild/trunk/src/gmakenew/kbuild.c@ 932

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

Fixed warnings.

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