3 * kBuild specific make functionality.
7 * Copyright (c) 2006-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
9 * This file is part of kBuild.
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 3 of the License, or
14 * (at your option) any later version.
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.
21 * You should have received a copy of the GNU General Public License
22 * along with kBuild. If not, see <http://www.gnu.org/licenses/>
26 /* No GNU coding style here! */
28 /*******************************************************************************
30 *******************************************************************************/
31 #define NO_MEMCOPY_HACK
38 # include "pathstuff.h"
41 #if defined(__APPLE__)
42 # include <mach-o/dyld.h>
44 #if defined(__FreeBSD__)
46 # include <sys/link_elf.h>
55 /*******************************************************************************
56 * Defined Constants And Macros *
57 *******************************************************************************/
58 /** Helper for passing a string constant to kbuild_get_variable_n. */
59 #define ST(strconst) strconst, sizeof(strconst) - 1
62 # define my_memcpy(dst, src, len) \
65 memcpy(dst, src, len); \
69 case 8: dst[7] = src[7]; /* fall thru */ \
70 case 7: dst[6] = src[6]; /* fall thru */ \
71 case 6: dst[5] = src[5]; /* fall thru */ \
72 case 5: dst[4] = src[4]; /* fall thru */ \
73 case 4: dst[3] = src[3]; /* fall thru */ \
74 case 3: dst[2] = src[2]; /* fall thru */ \
75 case 2: dst[1] = src[1]; /* fall thru */ \
76 case 1: dst[0] = src[0]; /* fall thru */ \
80 #elif defined(__GNUC__)
81 # define my_memcpy __builtin_memcpy
82 #elif defined(_MSC_VER)
83 # pragma instrinic(memcpy)
84 # define my_memcpy memcpy
88 /*******************************************************************************
90 *******************************************************************************/
91 /** The argv[0] passed to main. */
92 static const char *g_pszExeName
;
93 /** The initial working directory. */
94 static char *g_pszInitialCwd
;
98 * Initialize kBuild stuff.
100 * @param argc Number of arguments to main().
101 * @param argv The main() argument vector.
103 void init_kbuild(int argc
, char **argv
)
109 * Get the initial cwd for use in my_abspath.
112 if (getcwd_fs(szTmp
, GET_PATH_MAX
) != 0)
114 if (getcwd(szTmp
, GET_PATH_MAX
) != 0)
116 g_pszInitialCwd
= xstrdup(szTmp
);
118 O(fatal
, NILF
, _("getcwd failed"));
121 * Determin the executable name.
124 #if defined(__APPLE__)
126 const char *pszImageName
= _dyld_get_image_name(0);
129 size_t cchImageName
= strlen(pszImageName
);
130 if (cchImageName
< GET_PATH_MAX
)
132 memcpy(szTmp
, pszImageName
, cchImageName
+ 1);
138 #elif defined(__FreeBSD__)
139 rc
= readlink("/proc/curproc/file", szTmp
, GET_PATH_MAX
- 1);
140 if (rc
< 0 || rc
== GET_PATH_MAX
- 1)
143 # if 0 /* doesn't work because l_name isn't always absolute, it's just argv0 from exec or something. */
144 /* /proc is optional, try rtdl. */
145 void *hExe
= dlopen(NULL
, 0);
149 struct link_map
const *pLinkMap
= 0;
150 if (dlinfo(hExe
, RTLD_DI_LINKMAP
, &pLinkMap
) == 0)
152 const char *pszImageName
= pLinkMap
->l_name
;
153 size_t cchImageName
= strlen(pszImageName
);
154 if (cchImageName
< GET_PATH_MAX
)
156 memcpy(szTmp
, pszImageName
, cchImageName
+ 1);
167 #elif defined(__gnu_linux__) || defined(__linux__)
168 rc
= readlink("/proc/self/exe", szTmp
, GET_PATH_MAX
- 1);
169 if (rc
< 0 || rc
== GET_PATH_MAX
- 1)
174 #elif defined(__OS2__)
175 _execname(szTmp
, GET_PATH_MAX
);
178 #elif defined(__sun__)
181 snprintf(szTmp2
, sizeof(szTmp2
), "/proc/%ld/path/a.out", (long)getpid());
182 rc
= readlink(szTmp2
, szTmp
, GET_PATH_MAX
- 1);
183 if (rc
< 0 || rc
== GET_PATH_MAX
- 1)
189 #elif defined(WINDOWS32)
190 if (GetModuleFileName(GetModuleHandle(NULL
), szTmp
, GET_PATH_MAX
))
195 #if !defined(__OS2__) && !defined(WINDOWS32)
196 /* fallback, try use the path to locate the binary. */
198 && access(argv
[0], X_OK
))
200 size_t cchArgv0
= strlen(argv
[0]);
201 const char *pszPath
= getenv("PATH");
202 char *pszCopy
= xstrdup(pszPath
? pszPath
: ".");
207 char *pszEnd
= strchr(psz
, PATH_SEPARATOR_CHAR
);
209 pszEnd
= strchr(psz
, '\0');
211 if (cch
+ cchArgv0
+ 2 <= GET_PATH_MAX
)
213 memcpy(szTmp
, psz
, cch
);
215 memcpy(&szTmp
[cch
+ 1], argv
[0], cchArgv0
+ 1);
216 if (!access(szTmp
, X_OK
))
225 while (*psz
== PATH_SEPARATOR_CHAR
)
233 g_pszExeName
= argv
[0];
235 g_pszExeName
= xstrdup(szTmp
);
242 * Wrapper that ensures correct starting_directory.
244 static char *my_abspath(const char *pszIn
, char *pszOut
)
246 char *pszSaved
, *pszRet
;
248 pszSaved
= starting_directory
;
249 starting_directory
= g_pszInitialCwd
;
250 pszRet
= abspath(pszIn
, pszOut
);
251 starting_directory
= pszSaved
;
258 * Determin the KBUILD_PATH value.
260 * @returns Pointer to static a buffer containing the value (consider it read-only).
262 const char *get_kbuild_path(void)
264 static const char *s_pszPath
= NULL
;
268 const char *pszEnvVar
= getenv("KBUILD_PATH");
270 || !my_abspath(pszEnvVar
, szTmpPath
))
272 pszEnvVar
= getenv("PATH_KBUILD");
274 || !my_abspath(pszEnvVar
, szTmpPath
))
277 return s_pszPath
= KBUILD_PATH
;
279 /* $(abspath $(KBUILD_BIN_PATH)/../..)*/
280 size_t cch
= strlen(get_kbuild_bin_path());
281 char *pszTmp2
= alloca(cch
+ sizeof("/../.."));
282 strcat(strcpy(pszTmp2
, get_kbuild_bin_path()), "/../..");
283 if (!my_abspath(pszTmp2
, szTmpPath
))
284 O(fatal
, NILF
, _("failed to determin KBUILD_PATH"));
288 s_pszPath
= xstrdup(szTmpPath
);
295 * Determin the KBUILD_BIN_PATH value.
297 * @returns Pointer to static a buffer containing the value (consider it read-only).
299 const char *get_kbuild_bin_path(void)
301 static const char *s_pszPath
= NULL
;
306 const char *pszEnvVar
= getenv("KBUILD_BIN_PATH");
308 || !my_abspath(pszEnvVar
, szTmpPath
))
310 pszEnvVar
= getenv("PATH_KBUILD_BIN");
312 || !my_abspath(pszEnvVar
, szTmpPath
))
315 return s_pszPath
= KBUILD_BIN_PATH
;
317 /* $(abspath $(dir $(ARGV0)).) */
318 size_t cch
= strlen(g_pszExeName
);
319 char *pszTmp2
= alloca(cch
+ sizeof("."));
320 char *pszSep
= pszTmp2
+ cch
- 1;
321 memcpy(pszTmp2
, g_pszExeName
, cch
);
322 # ifdef HAVE_DOS_PATHS
323 while (pszSep
>= pszTmp2
&& *pszSep
!= '/' && *pszSep
!= '\\' && *pszSep
!= ':')
325 while (pszSep
>= pszTmp2
&& *pszSep
!= '/')
328 if (pszSep
>= pszTmp2
)
329 strcpy(pszSep
+ 1, ".");
331 strcpy(pszTmp2
, ".");
333 if (!my_abspath(pszTmp2
, szTmpPath
))
334 OSS(fatal
, NILF
, _("failed to determin KBUILD_BIN_PATH (pszTmp2=%s szTmpPath=%s)"), pszTmp2
, szTmpPath
);
335 #endif /* !KBUILD_PATH */
338 s_pszPath
= xstrdup(szTmpPath
);
345 * Determin the location of default kBuild shell.
347 * @returns Pointer to static a buffer containing the location (consider it read-only).
349 const char *get_default_kbuild_shell(void)
351 static char *s_pszDefaultShell
= NULL
;
352 if (!s_pszDefaultShell
)
354 #if defined(__OS2__) || defined(_WIN32) || defined(WINDOWS32)
355 static const char s_szShellName
[] = "/kmk_ash.exe";
357 static const char s_szShellName
[] = "/kmk_ash";
359 const char *pszBin
= get_kbuild_bin_path();
360 size_t cchBin
= strlen(pszBin
);
361 s_pszDefaultShell
= xmalloc(cchBin
+ sizeof(s_szShellName
));
362 memcpy(s_pszDefaultShell
, pszBin
, cchBin
);
363 memcpy(&s_pszDefaultShell
[cchBin
], s_szShellName
, sizeof(s_szShellName
));
365 return s_pszDefaultShell
;
371 * Applies the specified default path to any relative paths in *ppsz.
373 * @param pDefPath The default path.
374 * @param ppsz Pointer to the string pointer. If we expand anything, *ppsz
375 * will be replaced and the caller is responsible for calling free() on it.
376 * @param pcch IN: *pcch contains the current string length.
377 * OUT: *pcch contains the new string length.
378 * @param pcchAlloc *pcchAlloc contains the length allocated for the string. Can be NULL.
379 * @param fCanFree Whether *ppsz should be freed when we replace it.
382 kbuild_apply_defpath(struct variable
*pDefPath
, char **ppsz
, unsigned int *pcch
, unsigned int *pcchAlloc
, int fCanFree
)
384 unsigned int cchInCur
;
385 unsigned int cchMaxRelative
= 0;
386 const char *pszInCur
;
389 * The first pass, count the relative paths.
391 const char *pszIterator
= *ppsz
;
392 const char * const pszEos
= pszIterator
+ *pcch
;
393 unsigned int cRelativePaths
= 0;
394 assert(*pszEos
== '\0');
395 while ((pszInCur
= find_next_file_token(&pszIterator
, pszEos
, &cchInCur
)) != NULL
)
398 #ifdef HAVE_DOS_PATHS
399 if (pszInCur
[0] != '/' && pszInCur
[0] != '\\' && (cchInCur
< 2 || pszInCur
[1] != ':'))
401 if (pszInCur
[0] != '/')
405 if (cchInCur
> cchMaxRelative
)
406 cchMaxRelative
= cchInCur
;
411 * The second pass construct the new string.
415 size_t const cchAbsPathBuf
= MAX(GET_PATH_MAX
, pDefPath
->value_length
+ cchInCur
+ 1 + 16);
416 char *pszAbsPathOut
= (char *)alloca(cchAbsPathBuf
);
417 char *pszAbsPathIn
= (char *)alloca(cchAbsPathBuf
);
418 size_t cchAbsDefPath
;
422 const char *pszInNextCopy
= *ppsz
;
424 /* make defpath absolute and have a trailing slash first. */
425 if (abspath(pDefPath
->value
, pszAbsPathIn
) == NULL
)
426 memcpy(pszAbsPathIn
, pDefPath
->value
, pDefPath
->value_length
);
427 cchAbsDefPath
= strlen(pszAbsPathIn
);
428 #ifdef HAVE_DOS_PATHS
429 if (pszAbsPathIn
[cchAbsDefPath
- 1] != '/' && pszAbsPathIn
[cchAbsDefPath
- 1] != '\\')
431 if (pszAbsPathIn
[cchAbsDefPath
- 1] != '/')
433 pszAbsPathIn
[cchAbsDefPath
++] = '/';
435 cchOut
= *pcch
+ cRelativePaths
* cchAbsDefPath
+ 1;
436 pszOutCur
= pszOut
= xmalloc(cchOut
);
440 while ((pszInCur
= find_next_file_token(&pszIterator
, pszEos
, &cchInCur
)))
443 #ifdef HAVE_DOS_PATHS
444 if (pszInCur
[0] != '/' && pszInCur
[0] != '\\' && (cchInCur
< 2 || pszInCur
[1] != ':'))
446 if (pszInCur
[0] != '/')
449 const char *pszToCopy
;
452 /* Create the abspath input. */
453 memcpy(&pszAbsPathIn
[cchAbsDefPath
], pszInCur
, cchInCur
);
454 pszAbsPathIn
[cchAbsDefPath
+ cchInCur
] = '\0';
456 pszToCopy
= abspath(pszAbsPathIn
, pszAbsPathOut
);
458 pszToCopy
= pszAbsPathIn
;
460 /* copy leading input */
461 if (pszInCur
!= pszInNextCopy
)
463 const size_t cchCopy
= pszInCur
- pszInNextCopy
;
464 memcpy(pszOutCur
, pszInNextCopy
, cchCopy
);
465 pszOutCur
+= cchCopy
;
467 pszInNextCopy
= pszInCur
+ cchInCur
;
469 /* copy out the abspath. */
470 cchToCopy
= strlen(pszToCopy
);
471 assert(cchToCopy
<= cchAbsDefPath
+ cchInCur
);
472 memcpy(pszOutCur
, pszToCopy
, cchToCopy
);
473 pszOutCur
+= cchToCopy
;
475 /* else: Copy absolute paths as bulk when we hit then next relative one or the end. */
478 /* the final copy (includes the nil). */
479 cchInCur
= *ppsz
+ *pcch
- pszInNextCopy
;
480 memcpy(pszOutCur
, pszInNextCopy
, cchInCur
);
481 pszOutCur
+= cchInCur
;
483 assert((size_t)(pszOutCur
- pszOut
) < cchOut
);
485 /* set return values */
489 *pcch
= pszOutCur
- pszOut
;
496 * Gets a variable that must exist.
497 * Will cause a fatal failure if the variable doesn't exist.
499 * @returns Pointer to the variable.
500 * @param pszName The variable name.
501 * @param cchName The name length.
503 MY_INLINE
struct variable
*
504 kbuild_get_variable_n(const char *pszName
, size_t cchName
)
506 struct variable
*pVar
= lookup_variable(pszName
, cchName
);
508 fatal(NILF
, cchName
, _("variable `%.*s' isn't defined!"), (int)cchName
, pszName
);
510 fatal(NILF
, cchName
, _("variable `%.*s' is defined as `recursive' instead of `simple'!"), (int)cchName
, pszName
);
512 MY_ASSERT_MSG(strlen(pVar
->value
) == pVar
->value_length
,
513 ("%u != %u %.*s\n", pVar
->value_length
, (unsigned int)strlen(pVar
->value
), (int)cchName
, pVar
->name
));
519 * Gets a variable that must exist and can be recursive.
520 * Will cause a fatal failure if the variable doesn't exist.
522 * @returns Pointer to the variable.
523 * @param pszName The variable name.
525 static struct variable
*
526 kbuild_get_recursive_variable(const char *pszName
)
528 struct variable
*pVar
= lookup_variable(pszName
, strlen(pszName
));
530 OS(fatal
, NILF
, _("variable `%s' isn't defined!"), pszName
);
532 MY_ASSERT_MSG(strlen(pVar
->value
) == pVar
->value_length
,
533 ("%u != %u %s\n", pVar
->value_length
, (unsigned int)strlen(pVar
->value
), pVar
->name
));
539 * Gets a variable that doesn't have to exit, but if it does can be recursive.
541 * @returns Pointer to the variable.
543 * @param pszName The variable name. Doesn't need to be terminated.
544 * @param cchName The name length.
546 static struct variable
*
547 kbuild_query_recursive_variable_n(const char *pszName
, size_t cchName
)
549 struct variable
*pVar
= lookup_variable(pszName
, cchName
);
550 MY_ASSERT_MSG(!pVar
|| strlen(pVar
->value
) == pVar
->value_length
,
551 ("%u != %u %.*s\n", pVar
->value_length
, (unsigned int)strlen(pVar
->value
), (int)cchName
, pVar
->name
));
557 * Gets a variable that doesn't have to exit, but if it does can be recursive.
559 * @returns Pointer to the variable.
561 * @param pszName The variable name.
563 static struct variable
*
564 kbuild_query_recursive_variable(const char *pszName
)
566 return kbuild_query_recursive_variable_n(pszName
, strlen(pszName
));
571 * Converts the specified variable into a 'simple' one.
573 * @param pVar The variable.
575 static struct variable
*
576 kbuild_simplify_variable(struct variable
*pVar
)
578 if (memchr(pVar
->value
, '$', pVar
->value_length
))
580 unsigned int value_len
;
581 char *pszExpanded
= allocated_variable_expand_2(pVar
->value
, pVar
->value_length
, &value_len
);
582 #ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
583 if (pVar
->rdonly_val
)
584 pVar
->rdonly_val
= 0;
588 assert(pVar
->origin
!= o_automatic
);
589 pVar
->value
= pszExpanded
;
590 pVar
->value_length
= value_len
;
591 pVar
->value_alloc_len
= value_len
+ 1;
594 VARIABLE_CHANGED(pVar
);
600 * Looks up a variable.
601 * The value_length field is valid upon successful return.
603 * @returns Pointer to the variable. NULL if not found.
604 * @param pszName The variable name.
605 * @param cchName The name length.
607 MY_INLINE
struct variable
*
608 kbuild_lookup_variable_n(const char *pszName
, size_t cchName
)
610 struct variable
*pVar
= lookup_variable(pszName
, cchName
);
613 MY_ASSERT_MSG(strlen(pVar
->value
) == pVar
->value_length
,
614 ("%u != %u %.*s\n", pVar
->value_length
, (unsigned int)strlen(pVar
->value
), (int)cchName
, pVar
->name
));
616 /* Make sure the variable is simple, convert it if necessary.
617 Note! Must NOT do this for the dynamic INCS of sdks/ReorderCompilerIncs.kmk */
618 if (!pVar
->recursive
)
620 else if ( cchName
< sizeof("SDK_ReorderCompilerIncs_INCS.") - 1U
623 || memcmp(pszName
, "SDK_ReorderCompilerIncs_INCS.", sizeof("SDK_ReorderCompilerIncs_INCS.") - 1U) == 0)
624 kbuild_simplify_variable(pVar
);
631 * Looks up an non-empty variable when simplified and spaces skipped.
633 * This handy when emulating $(firstword )/$(lastword ) behaviour.
635 * @returns Pointer to the variable. NULL if not found.
636 * @param pszName The variable name.
637 * @param cchName The name length.
639 MY_INLINE
struct variable
*
640 kbuild_lookup_not_empty_variable_n(const char *pszName
, size_t cchName
)
642 struct variable
*pVar
= kbuild_lookup_variable_n(pszName
, cchName
);
643 if (pVar
&& !pVar
->recursive
)
646 * Skip spaces and make sure it's non-zero.
648 char *psz
= pVar
->value
;
650 { /* kind of likely */ }
654 while (ISSPACE(*psz
));
657 { /*kind of likely */ }
666 * Looks up a variable.
667 * The value_length field is valid upon successful return.
669 * @returns Pointer to the variable. NULL if not found.
670 * @param pszName The variable name.
672 MY_INLINE
struct variable
*
673 kbuild_lookup_variable(const char *pszName
)
675 return kbuild_lookup_variable_n(pszName
, strlen(pszName
));
680 * Looks up a variable and applies default a path to all relative paths.
681 * The value_length field is valid upon successful return.
683 * @returns Pointer to the variable. NULL if not found.
684 * @param pDefPath The default path.
685 * @param pszName The variable name.
686 * @param cchName The name length.
688 MY_INLINE
struct variable
*
689 kbuild_lookup_variable_defpath_n(struct variable
*pDefPath
, const char *pszName
, size_t cchName
)
691 struct variable
*pVar
= kbuild_lookup_variable_n(pszName
, cchName
);
692 if (pVar
&& pDefPath
)
694 assert(pVar
->origin
!= o_automatic
);
695 #ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
696 assert(!pVar
->rdonly_val
);
698 kbuild_apply_defpath(pDefPath
, &pVar
->value
, &pVar
->value_length
, &pVar
->value_alloc_len
, 1);
705 * Looks up a variable and applies default a path to all relative paths.
706 * The value_length field is valid upon successful return.
708 * @returns Pointer to the variable. NULL if not found.
709 * @param pDefPath The default path.
710 * @param pszName The variable name.
712 MY_INLINE
struct variable
*
713 kbuild_lookup_variable_defpath(struct variable
*pDefPath
, const char *pszName
)
715 struct variable
*pVar
= kbuild_lookup_variable(pszName
);
716 if (pVar
&& pDefPath
)
718 assert(pVar
->origin
!= o_automatic
);
719 #ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
720 assert(!pVar
->rdonly_val
);
722 kbuild_apply_defpath(pDefPath
, &pVar
->value
, &pVar
->value_length
, &pVar
->value_alloc_len
, 1);
729 * Gets the first defined property variable.
731 * When pBldType is given, additional property variations are consulted.
732 * See _TARGET_TOOL/r2433 in footer.kmk for the target-level difference.
733 * Similar extended property lookup is applied to the source part if the
734 * fExtendedSource parameter is non-zero (not done yet as it'll be expensive).
736 * Since r3415 this function will use $(target)_2_$(type)TOOL to cache the
737 * result of the target specific part of the lookup (_TARGET_TOOL).
739 static struct variable
*
740 kbuild_first_prop(struct variable
*pTarget
, struct variable
*pSource
,
741 struct variable
*pTool
, struct variable
*pType
,
742 struct variable
*pBldTrg
, struct variable
*pBldTrgArch
, struct variable
*pBldType
,
743 const char *pszPropF1
, char cchPropF1
,
744 const char *pszPropF2
, char cchPropF2
,
746 const char *pszVarName
)
748 struct variable
*pVar
;
751 char *psz
, *psz1
, *psz2
, *psz3
, *psz4
, *pszEnd
;
754 fExtendedSource
= fExtendedSource
&& pBldType
!= NULL
;
756 /* calc and allocate a too big name buffer. */
757 cchBuf
= cchPropF2
+ 1
759 + pTarget
->value_length
+ 1
760 + pSource
->value_length
+ 1
761 + (pTool
? pTool
->value_length
+ 1 : 0)
762 + pType
->value_length
+ 1
763 + pBldTrg
->value_length
+ 1
764 + pBldTrgArch
->value_length
+ 1
765 + (pBldType
? pBldType
->value_length
+ 1 : 0);
766 pszBuf
= xmalloc(cchBuf
);
768 #define ADD_VAR(pVar) do { my_memcpy(psz, (pVar)->value, (pVar)->value_length); psz += (pVar)->value_length; } while (0)
769 #define ADD_STR(pszStr, cchStr) do { my_memcpy(psz, (pszStr), (cchStr)); psz += (cchStr); } while (0)
770 #define ADD_CSTR(pszStr) do { my_memcpy(psz, pszStr, sizeof(pszStr) - 1); psz += sizeof(pszStr) - 1; } while (0)
771 #define ADD_CH(ch) do { *psz++ = (ch); } while (0)
774 * $(target)_$(source)_$(type)$(propf2).$(bld_trg).$(bld_trg_arch).$(bld_type)
776 * $(target)_$(source)_$(type)$(propf2)
785 ADD_STR(pszPropF2
, cchPropF2
);
786 #define DO_VARIATIONS(a_fExtended) do { \
792 ADD_VAR(pBldTrgArch); \
794 if ((a_fExtended) && pBldType) \
798 pVar = kbuild_lookup_not_empty_variable_n(pszBuf, psz - pszBuf); \
800 /* <lead>.$(bld_trg).$(bld_trg_arch) */ \
802 pVar = kbuild_lookup_not_empty_variable_n(pszBuf, psz4 - pszBuf); \
804 /* <lead>.$(bld_trg).$(bld_type) */ \
809 pVar = kbuild_lookup_not_empty_variable_n(pszBuf, psz - pszBuf); \
812 /* <lead>.$(bld_trg_arch) */ \
816 ADD_VAR(pBldTrgArch); \
817 pVar = kbuild_lookup_not_empty_variable_n(pszBuf, psz - pszBuf); \
820 /* <lead>.$(bld_trg) */ \
825 pVar = kbuild_lookup_not_empty_variable_n(pszBuf, psz - pszBuf); \
828 /* <lead>.$(bld_type) */ \
833 pVar = kbuild_lookup_not_empty_variable_n(pszBuf, psz - pszBuf); \
838 /* <lead>.$(bld_trg).$(bld_trg_arch) */ \
839 pVar = kbuild_lookup_not_empty_variable_n(pszBuf, psz4 - pszBuf); \
841 /* <lead>.$(bld_trg) */ \
843 pVar = kbuild_lookup_not_empty_variable_n(pszBuf, psz3 - pszBuf); \
848 pVar = kbuild_lookup_not_empty_variable_n(pszBuf, psz2 - pszBuf); \
850 DO_VARIATIONS(fExtendedSource
);
853 * $(target)_$(source)_$(propf2).$(bld_trg).$(bld_trg_arch).$(bld_type) [omit $(type) prefix to $(propf2)]
855 * $(target)_$(source)_$(propf2)
859 psz
= psz1
; /* rewind to '$(target)_$(source)_' */
860 ADD_STR(pszPropF2
, cchPropF2
);
861 DO_VARIATIONS(fExtendedSource
);
865 * $(source)_$(type)$(propf2).$(bld_trg).$(bld_trg_arch).$(bld_type)
867 * $(source)_$(type)$(propf2)
876 ADD_STR(pszPropF2
, cchPropF2
);
877 DO_VARIATIONS(fExtendedSource
);
880 * $(source)_$(propf2).$(bld_trg).$(bld_trg_arch).$(bld_type) [omit $(type) prefix to $(propf2)]
882 * $(source)_$(propf2)
886 psz
= psz1
; /* rewind to '$(source)_' */
887 ADD_STR(pszPropF2
, cchPropF2
);
888 DO_VARIATIONS(fExtendedSource
);
893 * Check the cache: $(target)_2_$(type)$(propf2)
903 ADD_STR(pszPropF2
, cchPropF2
);
904 pVar
= kbuild_lookup_variable_n(pszBuf
, psz
- pszBuf
);
906 /* If found, this can be duplicated and returned directly. No value stripping
907 needed as we defined it (or at least should have) ourselves. */
910 pVar
= define_variable_vl(pszVarName
, strlen(pszVarName
), pVar
->value
, pVar
->value_length
,
911 1 /* duplicate */, o_local
, 0 /* !recursive */);
918 * $(target)_$(type)$(propf2).$(bld_trg).$(bld_trg_arch).$(bld_type)
920 * $(target)_$(type)$(propf2)
929 ADD_STR(pszPropF2
, cchPropF2
);
933 * $(target)_$(propf2).$(bld_trg).$(bld_trg_arch).$(bld_type) [omit $(type) prefix to $(propf2)]
935 * $(target)_$(propf2)
939 psz
= psz1
; /* rewind to '$(target)_' */
940 ADD_STR(pszPropF2
, cchPropF2
);
946 * TOOL_$(tool)_$(type)$(propf2).$(bld_trg).$(bld_trg_arch).$(bld_type)
948 * TOOL_$(tool)_$(type)$(propf2)
958 ADD_STR(pszPropF2
, cchPropF2
);
962 * TOOL_$(tool)_$(propf2).$(bld_trg).$(bld_trg_arch).$(bld_type) [omit $(type) prefix to $(propf2)]
964 * TOOL_$(tool)_$(propf2)
968 psz
= psz1
; /* rewind to 'TOOL_$(tool)_' */
969 ADD_STR(pszPropF2
, cchPropF2
);
975 * $(type)$(propf1).$(bld_trg).$(bld_trg_arch).$(bld_type)
983 ADD_STR(pszPropF1
, cchPropF1
);
987 * $(propf1).$(bld_trg).$(bld_trg_arch).$(bld_type)
994 ADD_STR(pszPropF1
, cchPropF1
);
1006 pszEnd
= psz
+ pVar
->value_length
;
1007 while (ISBLANK(*psz
))
1009 while (pszEnd
> psz
&& ISBLANK(pszEnd
[-1]))
1013 char chSaved
= *pszEnd
;
1015 pVar
= define_variable_vl(pszVarName
, strlen(pszVarName
), psz
, pszEnd
- psz
,
1016 1 /* duplicate */, o_local
, 0 /* !recursive */);
1023 /* Cache the result if needed. */
1030 ADD_STR(pszPropF2
, cchPropF2
);
1031 define_variable_vl_global(pszBuf
, psz
- pszBuf
, pVar
? pVar
->value
: "", pVar
? pVar
->value_length
: 0,
1032 1 /* duplicate */, o_file
, 0 /* !recursive */, NILF
);
1046 _SOURCE_TOOL = $(strip $(firstword \
1047 $($(target)_$(source)_$(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
1048 $($(target)_$(source)_$(type)TOOL.$(bld_trg)) \
1049 $($(target)_$(source)_$(type)TOOL) \
1050 $($(target)_$(source)_TOOL.$(bld_trg).$(bld_trg_arch)) \
1051 $($(target)_$(source)_TOOL.$(bld_trg)) \
1052 $($(target)_$(source)_TOOL) \
1053 $($(source)_$(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
1054 $($(source)_$(type)TOOL.$(bld_trg)) \
1055 $($(source)_$(type)TOOL) \
1056 $($(source)_TOOL.$(bld_trg).$(bld_trg_arch)) \
1057 $($(source)_TOOL.$(bld_trg)) \
1059 $($(target)_$(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
1060 $($(target)_$(type)TOOL.$(bld_trg)) \
1061 $($(target)_$(type)TOOL) \
1062 $($(target)_TOOL.$(bld_trg).$(bld_trg_arch)) \
1063 $($(target)_TOOL.$(bld_trg)) \
1065 \ - the rest depends on pBldType, see _TARGET_TOOL and kbuild_first_prop.
1066 $($(type)TOOL.$(bld_trg).$(bld_trg_arch)) \
1067 $($(type)TOOL.$(bld_trg)) \
1069 $(TOOL.$(bld_trg).$(bld_trg_arch)) \
1070 $(TOOL.$(bld_trg)) \
1073 static struct variable
*
1074 kbuild_get_source_tool(struct variable
*pTarget
, struct variable
*pSource
, struct variable
*pType
,
1075 struct variable
*pBldTrg
, struct variable
*pBldTrgArch
, struct variable
*pBldType
,
1076 const char *pszVarName
)
1078 struct variable
*pVar
= kbuild_first_prop(pTarget
, pSource
, NULL
, pType
, pBldTrg
, pBldTrgArch
, pBldType
,
1079 "TOOL", sizeof("TOOL") - 1,
1080 "TOOL", sizeof("TOOL") - 1,
1081 0 /*fExtendedSource*/, pszVarName
);
1083 OSS(fatal
, NILF
, _("no tool for source `%s' in target `%s'!"), pSource
->value
, pTarget
->value
);
1089 * Helper for func_kbuild_source_tool, func_kbuild_source_one, ++.
1091 static int kbuild_version_to_int(const char *pszVersion
, int fStrict
)
1094 if (pszVersion
&& pszVersion
[0])
1096 switch (pszVersion
[0] | (pszVersion
[1] << 8))
1098 case '2': iVer
= 2; break;
1099 case '3': iVer
= 3; break;
1100 case '4': iVer
= 4; break;
1101 case '5': iVer
= 5; break;
1102 case '6': iVer
= 6; break;
1103 case '7': iVer
= 7; break;
1104 case '8': iVer
= 8; break;
1105 case '9': iVer
= 9; break;
1106 case '0': iVer
= 0; break;
1107 case '1': iVer
= 1; break;
1109 while (ISBLANK(*pszVersion
))
1113 char *pszEnd
= NULL
;
1116 lVer
= strtol(pszVersion
, &pszEnd
, 10);
1120 if (lVer
== 0 && errno
!= 0)
1121 OSN(fatal
, NILF
, _("invalid version argument '%s': errno=%d"), pszVersion
, errno
);
1122 else if (iVer
!= (int)lVer
|| iVer
< 0)
1123 OS(fatal
, NILF
, _("version argument out of range '%s'"), pszVersion
);
1126 while (ISBLANK(*pszEnd
))
1129 OS(fatal
, NILF
, _("version is not numerical '%s'"), pszVersion
);
1141 * "kb-src-tool <varname> [ver=0]" - implements _SOURCE_TOOL.
1143 * Since r3415 an extended set of keyword variations is used on the target, tool
1144 * and global properties.
1147 func_kbuild_source_tool(char *o
, char **argv
, const char *pszFuncName
)
1149 const int iVer
= kbuild_version_to_int(argv
[1], 1 /*strict*/);
1150 struct variable
*pVar
= kbuild_get_source_tool(kbuild_get_variable_n(ST("target")),
1151 kbuild_get_variable_n(ST("source")),
1152 kbuild_get_variable_n(ST("type")),
1153 kbuild_get_variable_n(ST("bld_trg")),
1154 kbuild_get_variable_n(ST("bld_trg_arch")),
1155 kbuild_get_variable_n(ST("bld_type")),
1158 o
= variable_buffer_output(o
, pVar
->value
, pVar
->value_length
);
1159 (void)pszFuncName
; (void)iVer
;
1165 * Similar to _TARGET_TOOL since r3415.
1167 static struct variable
*
1168 kbuild_get_object_suffix(struct variable
*pTarget
, struct variable
*pSource
,
1169 struct variable
*pTool
, struct variable
*pType
,
1170 struct variable
*pBldTrg
, struct variable
*pBldTrgArch
, struct variable
*pBldType
,
1171 const char *pszVarName
)
1173 struct variable
*pVar
= kbuild_first_prop(pTarget
, pSource
, pTool
, pType
, pBldTrg
, pBldTrgArch
, pBldType
,
1174 "SUFF_OBJ", sizeof("SUFF_OBJ") - 1,
1175 "OBJSUFF", sizeof("OBJSUFF") - 1,
1176 0 /*fExtendedSource*/, pszVarName
);
1178 OSS(fatal
, NILF
, _("no OBJSUFF attribute or SUFF_OBJ default for source `%s' in target `%s'!"),
1179 pSource
->value
, pTarget
->value
);
1185 * "kb-obj-suff <varname> [ver=0]"
1187 * Since r3415 an extended set of keyword variations is used on the target, tool
1188 * and global properties.
1191 func_kbuild_object_suffix(char *o
, char **argv
, const char *pszFuncName
)
1193 const int iVer
= kbuild_version_to_int(argv
[1], 1 /*strict*/);
1194 struct variable
*pVar
= kbuild_get_object_suffix(kbuild_get_variable_n(ST("target")),
1195 kbuild_get_variable_n(ST("source")),
1196 kbuild_get_variable_n(ST("tool")),
1197 kbuild_get_variable_n(ST("type")),
1198 kbuild_get_variable_n(ST("bld_trg")),
1199 kbuild_get_variable_n(ST("bld_trg_arch")),
1200 kbuild_get_variable_n(ST("bld_type")),
1203 o
= variable_buffer_output(o
, pVar
->value
, pVar
->value_length
);
1204 (void)pszFuncName
; (void)iVer
;
1211 ## Figure out where to put object files.
1212 # @param $1 source file
1213 # @param $2 normalized main target
1214 # @remark There are two major hacks here:
1215 # 1. Source files in the output directory are translated into a gen/ subdir.
1216 # 2. Catch anyone specifying $(PATH_SUB_CURRENT)/sourcefile.c.
1217 _OBJECT_BASE = $(PATH_TARGET)/$(2)/$(call no-root-slash,$(call no-drive,$(basename \
1218 $(patsubst $(PATH_ROOT)/%,%,$(patsubst $(PATH_SUB_CURRENT)/%,%,$(patsubst $(PATH_TARGET)/$(2)/%,gen/%,$(1)))))))
1220 static struct variable
*
1221 kbuild_get_object_base(struct variable
*pTarget
, struct variable
*pSource
, const char *pszVarName
)
1223 struct variable
*pPathTarget
= kbuild_get_variable_n(ST("PATH_TARGET"));
1224 struct variable
*pPathRoot
= kbuild_get_variable_n(ST("PATH_ROOT"));
1225 struct variable
*pPathSubCur
= kbuild_get_variable_n(ST("PATH_SUB_CURRENT"));
1226 const char *pszSrcPrefix
= NULL
;
1227 size_t cchSrcPrefix
= 0;
1229 const char *pszSrcEnd
;
1237 * Strip the source filename of any unnecessary leading path and root specs.
1239 if ( pSource
->value_length
> pPathTarget
->value_length
1240 && !strncmp(pSource
->value
, pPathTarget
->value
, pPathTarget
->value_length
))
1242 pszSrc
= pSource
->value
+ pPathTarget
->value_length
;
1243 pszSrcPrefix
= "gen/";
1244 cchSrcPrefix
= sizeof("gen/") - 1;
1246 && !strncmp(pszSrc
+ 1, pTarget
->value
, pTarget
->value_length
)
1247 && ( pszSrc
[pTarget
->value_length
+ 1] == '/'
1248 || pszSrc
[pTarget
->value_length
+ 1] == '\0'))
1249 pszSrc
+= 1 + pTarget
->value_length
;
1251 else if ( pSource
->value_length
> pPathRoot
->value_length
1252 && !strncmp(pSource
->value
, pPathRoot
->value
, pPathRoot
->value_length
))
1254 pszSrc
= pSource
->value
+ pPathRoot
->value_length
;
1256 && !strncmp(pszSrc
+ 1, pPathSubCur
->value
, pPathSubCur
->value_length
)
1257 && ( pszSrc
[pPathSubCur
->value_length
+ 1] == '/'
1258 || pszSrc
[pPathSubCur
->value_length
+ 1] == '\0'))
1259 pszSrc
+= 1 + pPathSubCur
->value_length
;
1262 pszSrc
= pSource
->value
;
1264 /* skip root specification */
1265 #ifdef HAVE_DOS_PATHS
1266 if (isalpha(pszSrc
[0]) && pszSrc
[1] == ':')
1269 while (*pszSrc
== '/'
1270 #ifdef HAVE_DOS_PATHS
1276 /* drop the source extension. */
1277 pszSrcEnd
= pSource
->value
+ pSource
->value_length
;
1281 if ( pszSrcEnd
<= pszSrc
1282 || *pszSrcEnd
== '/'
1283 #ifdef HAVE_DOS_PATHS
1284 || *pszSrcEnd
== '\\'
1285 || *pszSrcEnd
== ':'
1289 pszSrcEnd
= pSource
->value
+ pSource
->value_length
;
1292 if (*pszSrcEnd
== '.')
1297 * Assemble the string on the heap and define the objbase variable
1298 * which we then return.
1300 cchSrc
= pszSrcEnd
- pszSrc
;
1301 cch
= pPathTarget
->value_length
1303 + pTarget
->value_length
1308 psz
= pszResult
= xmalloc(cch
);
1310 memcpy(psz
, pPathTarget
->value
, pPathTarget
->value_length
); psz
+= pPathTarget
->value_length
;
1312 memcpy(psz
, pTarget
->value
, pTarget
->value_length
); psz
+= pTarget
->value_length
;
1316 memcpy(psz
, pszSrcPrefix
, cchSrcPrefix
);
1317 psz
+= cchSrcPrefix
;
1320 memcpy(psz
, pszSrc
, cchSrc
); psz
+= cchSrc
;
1323 /* convert '..' path elements in the source to 'dt'. */
1324 while ((pszDot
= memchr(pszDot
, '.', psz
- pszDot
)) != NULL
)
1326 if ( pszDot
[1] == '.'
1328 || pszDot
[-1] == '/'
1329 #ifdef HAVE_DOS_PATHS
1330 || pszDot
[-1] == '\\'
1331 || pszDot
[-1] == ':'
1336 #ifdef HAVE_DOS_PATHS
1337 || pszDot
[2] == '\\'
1351 * Define the variable in the current set and return it.
1353 return define_variable_vl(pszVarName
, strlen(pszVarName
), pszResult
, cch
- 1,
1354 0 /* use pszResult */, o_local
, 0 /* !recursive */);
1359 * "kb-obj-base <var> [ver]" Implements _OBJECT_BASE.
1362 func_kbuild_object_base(char *o
, char **argv
, const char *pszFuncName
)
1364 const int iVer
= kbuild_version_to_int(argv
[1], 1 /*strict*/);
1365 struct variable
*pVar
= kbuild_get_object_base(kbuild_lookup_variable("target"),
1366 kbuild_lookup_variable("source"),
1369 o
= variable_buffer_output(o
, pVar
->value
, pVar
->value_length
);
1370 (void)pszFuncName
; (void)iVer
;
1378 struct variable
*pa
;
1386 unsigned iTargetSource
;
1387 unsigned cTargetSource
;
1388 unsigned int cchMax
;
1392 /* Fills in the SDK struct (remember to free it). */
1394 kbuild_get_sdks(struct kbuild_sdks
*pSdks
, struct variable
*pTarget
, struct variable
*pSource
,
1395 struct variable
*pBldType
, struct variable
*pBldTrg
, struct variable
*pBldTrgArch
)
1403 const char *pszIterator
;
1405 /** @todo rewrite this to avoid sprintf and allocated_varaible_expand_2. */
1413 /* determin required tmp variable name space. */
1414 cchTmp
= sizeof("$(__SDKS) $(__SDKS.) $(__SDKS.) $(__SDKS.) $(__SDKS..)")
1415 + (pTarget
->value_length
+ pSource
->value_length
) * 5
1416 + pBldType
->value_length
1417 + pBldTrg
->value_length
1418 + pBldTrgArch
->value_length
1419 + pBldTrg
->value_length
+ pBldTrgArch
->value_length
;
1420 pszTmp
= alloca(cchTmp
);
1422 /* the global sdks. */
1425 cch
= sprintf(pszTmp
, "$(SDKS) $(SDKS.%s) $(SDKS.%s) $(SDKS.%s) $(SDKS.%s.%s)",
1429 pBldTrg
->value
, pBldTrgArch
->value
);
1430 pszIterator
= pSdks
->apsz
[0] = allocated_variable_expand_2(pszTmp
, cch
, NULL
);
1431 while ((pszCur
= find_next_token(&pszIterator
, &cchCur
)) != 0)
1433 i
+= pSdks
->cGlobal
;
1435 /* the target sdks.*/
1438 cch
= sprintf(pszTmp
, "$(%s_SDKS) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s.%s)",
1440 pTarget
->value
, pBldType
->value
,
1441 pTarget
->value
, pBldTrg
->value
,
1442 pTarget
->value
, pBldTrgArch
->value
,
1443 pTarget
->value
, pBldTrg
->value
, pBldTrgArch
->value
);
1444 pszIterator
= pSdks
->apsz
[1] = allocated_variable_expand_2(pszTmp
, cch
, NULL
);
1445 while ((pszCur
= find_next_token(&pszIterator
, &cchCur
)) != 0)
1447 i
+= pSdks
->cTarget
;
1449 /* the source sdks.*/
1452 cch
= sprintf(pszTmp
, "$(%s_SDKS) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s) $(%s_SDKS.%s.%s)",
1454 pSource
->value
, pBldType
->value
,
1455 pSource
->value
, pBldTrg
->value
,
1456 pSource
->value
, pBldTrgArch
->value
,
1457 pSource
->value
, pBldTrg
->value
, pBldTrgArch
->value
);
1458 pszIterator
= pSdks
->apsz
[2] = allocated_variable_expand_2(pszTmp
, cch
, NULL
);
1459 while ((pszCur
= find_next_token(&pszIterator
, &cchCur
)) != 0)
1461 i
+= pSdks
->cSource
;
1463 /* the target + source sdks. */
1464 pSdks
->iTargetSource
= i
;
1465 pSdks
->cTargetSource
= 0;
1466 cch
= sprintf(pszTmp
, "$(%s_%s_SDKS) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s) $(%s_%s_SDKS.%s.%s)",
1467 pTarget
->value
, pSource
->value
,
1468 pTarget
->value
, pSource
->value
, pBldType
->value
,
1469 pTarget
->value
, pSource
->value
, pBldTrg
->value
,
1470 pTarget
->value
, pSource
->value
, pBldTrgArch
->value
,
1471 pTarget
->value
, pSource
->value
, pBldTrg
->value
, pBldTrgArch
->value
);
1472 assert(cch
< cchTmp
); (void)cch
;
1473 pszIterator
= pSdks
->apsz
[3] = allocated_variable_expand_2(pszTmp
, cch
, NULL
);
1474 while ((pszCur
= find_next_token(&pszIterator
, &cchCur
)) != 0)
1475 pSdks
->cTargetSource
++;
1476 i
+= pSdks
->cTargetSource
;
1483 * Allocate the variable array and create the variables.
1485 pSdks
->pa
= (struct variable
*)xmalloc(sizeof(pSdks
->pa
[0]) * i
);
1486 memset(pSdks
->pa
, 0, sizeof(pSdks
->pa
[0]) * i
);
1487 for (i
= j
= 0; j
< sizeof(pSdks
->apsz
) / sizeof(pSdks
->apsz
[0]); j
++)
1489 pszIterator
= pSdks
->apsz
[j
];
1490 while ((pszCur
= find_next_token(&pszIterator
, &cchCur
)) != 0)
1492 pSdks
->pa
[i
].value
= pszCur
;
1493 pSdks
->pa
[i
].value_length
= cchCur
;
1497 assert(i
== pSdks
->c
);
1499 /* terminate them (find_next_token won't work if we terminate them in the previous loop). */
1502 pSdks
->pa
[i
].value
[pSdks
->pa
[i
].value_length
] = '\0';
1504 /* calc the max variable length too. */
1505 if (pSdks
->cchMax
< (unsigned int)pSdks
->pa
[i
].value_length
)
1506 pSdks
->cchMax
= pSdks
->pa
[i
].value_length
;
1511 /* releases resources allocated in the kbuild_get_sdks. */
1513 kbuild_put_sdks(struct kbuild_sdks
*pSdks
)
1516 for (j
= 0; j
< sizeof(pSdks
->apsz
) / sizeof(pSdks
->apsz
[0]); j
++)
1517 free(pSdks
->apsz
[j
]);
1521 /** Per variable struct used by kbuild_collect_source_prop and helpers. */
1522 struct kbuild_collect_variable
1524 struct variable
*pVar
;
1525 unsigned int cchExp
;
1530 * Helper for kbuild_collect_source_prop.
1532 * Frees up any memory we've allocated for the variable values.
1534 static struct variable
*
1535 kbuild_collect_source_prop_create_var(size_t cchTotal
, int cVars
, struct kbuild_collect_variable
*paVars
, int iDirection
,
1536 const char *pszVarName
, size_t cchVarName
, enum variable_origin enmVarOrigin
)
1539 struct variable
*pVar
;
1540 if (!cVars
|| !cchTotal
)
1542 pszResult
= xmalloc(1);
1548 char *psz
= pszResult
= xmalloc(cchTotal
+ 1);
1549 if (iDirection
== 1)
1551 for (iVar
= 0; iVar
< cVars
; iVar
++)
1553 my_memcpy(psz
, paVars
[iVar
].pszExp
, paVars
[iVar
].cchExp
);
1554 psz
+= paVars
[iVar
].cchExp
;
1556 if (paVars
[iVar
].pszExp
!= paVars
[iVar
].pVar
->value
)
1557 free(paVars
[iVar
].pszExp
);
1565 my_memcpy(psz
, paVars
[iVar
].pszExp
, paVars
[iVar
].cchExp
);
1566 psz
+= paVars
[iVar
].cchExp
;
1568 if (paVars
[iVar
].pszExp
!= paVars
[iVar
].pVar
->value
)
1569 free(paVars
[iVar
].pszExp
);
1573 assert(psz
!= pszResult
);
1574 assert(cchTotal
== (size_t)(psz
- pszResult
));
1579 if (enmVarOrigin
== o_local
)
1580 pVar
= define_variable_vl(pszVarName
, cchVarName
, pszResult
, cchTotal
,
1581 0 /* take pszResult */ , enmVarOrigin
, 0 /* !recursive */);
1583 pVar
= define_variable_vl_global(pszVarName
, cchVarName
, pszResult
, cchTotal
,
1584 0 /* take pszResult */ , enmVarOrigin
, 0 /* !recursive */, NILF
);
1588 /* this kind of stuff:
1590 defs := $(kb-src-exp defs)
1591 $(TOOL_$(tool)_DEFS)\
1592 $(TOOL_$(tool)_DEFS.$(bld_type))\
1593 $(TOOL_$(tool)_DEFS.$(bld_trg))\
1594 $(TOOL_$(tool)_DEFS.$(bld_trg_arch))\
1595 $(TOOL_$(tool)_DEFS.$(bld_trg).$(bld_trg_arch))\
1596 $(TOOL_$(tool)_DEFS.$(bld_trg_cpu))\
1597 $(TOOL_$(tool)_$(type)DEFS)\
1598 $(TOOL_$(tool)_$(type)DEFS.$(bld_type))\
1599 $(foreach sdk, $(SDKS.$(bld_trg)) \
1600 $(SDKS.$(bld_trg).$(bld_trg_arch)) \
1601 $(SDKS.$(bld_type)) \
1604 $(SDK_$(sdk)_DEFS.$(bld_type))\
1605 $(SDK_$(sdk)_DEFS.$(bld_trg))\
1606 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
1607 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
1608 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
1609 $(SDK_$(sdk)_$(type)DEFS)\
1610 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
1611 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
1612 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
1613 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
1614 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
1616 $(DEFS.$(bld_type))\
1618 $(DEFS.$(bld_trg_arch))\
1619 $(DEFS.$(bld_trg).$(bld_trg_arch))\
1620 $(DEFS.$(bld_trg_cpu))\
1622 $($(type)DEFS.$(bld_type))\
1623 $($(type)DEFS.$(bld_trg))\
1624 $($(type)DEFS.$(bld_trg_arch))\
1625 $($(type)DEFS.$(bld_trg).$(bld_trg_arch))\
1626 $($(type)DEFS.$(bld_trg_cpu))\
1627 $(foreach sdk, $($(target)_SDKS.$(bld_trg)) \
1628 $($(target)_SDKS.$(bld_trg).$(bld_trg_arch)) \
1629 $($(target)_SDKS.$(bld_type)) \
1632 $(SDK_$(sdk)_DEFS.$(bld_type))\
1633 $(SDK_$(sdk)_DEFS.$(bld_trg))\
1634 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
1635 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
1636 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
1637 $(SDK_$(sdk)_$(type)DEFS)\
1638 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
1639 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
1640 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
1641 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
1642 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
1644 $($(target)_DEFS.$(bld_type))\
1645 $($(target)_DEFS.$(bld_trg))\
1646 $($(target)_DEFS.$(bld_trg_arch))\
1647 $($(target)_DEFS.$(bld_trg).$(bld_trg_arch))\
1648 $($(target)_DEFS.$(bld_trg_cpu))\
1649 $($(target)_$(type)DEFS)\
1650 $($(target)_$(type)DEFS.$(bld_type))\
1651 $($(target)_$(type)DEFS.$(bld_trg))\
1652 $($(target)_$(type)DEFS.$(bld_trg_arch))\
1653 $($(target)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
1654 $($(target)_$(type)DEFS.$(bld_trg_cpu))\
1655 $(foreach sdk, $($(source)_SDKS.$(bld_trg)) \
1656 $($(source)_SDKS.$(bld_trg).$(bld_trg_arch)) \
1657 $($(source)_SDKS.$(bld_type)) \
1660 $(SDK_$(sdk)_DEFS.$(bld_type))\
1661 $(SDK_$(sdk)_DEFS.$(bld_trg))\
1662 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
1663 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
1664 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
1665 $(SDK_$(sdk)_$(type)DEFS)\
1666 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
1667 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
1668 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
1669 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
1670 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
1672 $($(source)_DEFS.$(bld_type))\
1673 $($(source)_DEFS.$(bld_trg))\
1674 $($(source)_DEFS.$(bld_trg_arch))\
1675 $($(source)_DEFS.$(bld_trg).$(bld_trg_arch))\
1676 $($(source)_DEFS.$(bld_trg_cpu))\
1677 $($(source)_$(type)DEFS)\
1678 $($(source)_$(type)DEFS.$(bld_type))\
1679 $($(source)_$(type)DEFS.$(bld_trg))\
1680 $($(source)_$(type)DEFS.$(bld_trg_arch))\
1681 $($(source)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
1682 $($(source)_$(type)DEFS.$(bld_trg_cpu))\
1683 $(foreach sdk, $($(target)_$(source)_SDKS.$(bld_trg)) \
1684 $($(target)_$(source)_SDKS.$(bld_trg).$(bld_trg_arch)) \
1685 $($(target)_$(source)_SDKS.$(bld_type)) \
1686 $($(target)_$(source)_SDKS),\
1688 $(SDK_$(sdk)_DEFS.$(bld_type))\
1689 $(SDK_$(sdk)_DEFS.$(bld_trg))\
1690 $(SDK_$(sdk)_DEFS.$(bld_trg_arch))\
1691 $(SDK_$(sdk)_DEFS.$(bld_trg).$(bld_trg_arch))\
1692 $(SDK_$(sdk)_DEFS.$(bld_trg_cpu))\
1693 $(SDK_$(sdk)_$(type)DEFS)\
1694 $(SDK_$(sdk)_$(type)DEFS.$(bld_type))\
1695 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg))\
1696 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_arch))\
1697 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
1698 $(SDK_$(sdk)_$(type)DEFS.$(bld_trg_cpu)))\
1699 $($(target)_$(source)_DEFS)\
1700 $($(target)_$(source)_DEFS.$(bld_type))\
1701 $($(target)_$(source)_DEFS.$(bld_trg))\
1702 $($(target)_$(source)_DEFS.$(bld_trg_arch))\
1703 $($(target)_$(source)_DEFS.$(bld_trg).$(bld_trg_arch))\
1704 $($(target)_$(source)_DEFS.$(bld_trg_cpu))\
1705 $($(target)_$(source)_$(type)DEFS)\
1706 $($(target)_$(source)_$(type)DEFS.$(bld_type))\
1707 $($(target)_$(source)_$(type)DEFS.$(bld_trg))\
1708 $($(target)_$(source)_$(type)DEFS.$(bld_trg_arch))\
1709 $($(target)_$(source)_$(type)DEFS.$(bld_trg).$(bld_trg_arch))\
1710 $($(target)_$(source)_$(type)DEFS.$(bld_trg_cpu))
1712 static struct variable
*
1713 kbuild_collect_source_prop(struct variable
*pTarget
, struct variable
*pSource
,
1714 struct variable
*pTool
, struct kbuild_sdks
*pSdks
,
1715 struct variable
*pType
, struct variable
*pBldType
,
1716 struct variable
*pBldTrg
, struct variable
*pBldTrgArch
, struct variable
*pBldTrgCpu
,
1717 struct variable
*pDefPath
,
1718 const char *pszProp
, size_t cchProp
,
1719 const char *pszVarName
, size_t cchVarName
,
1722 struct variable
*pVar
;
1723 unsigned iSdk
, iSdkEnd
;
1725 size_t cchTotal
, cchBuf
;
1726 char *pszBuf
, *psz
, *psz2
, *psz3
;
1727 struct kbuild_collect_variable
*paVars
;
1729 assert(iDirection
== 1 || iDirection
== -1);
1732 * Calc and allocate a too big name buffer.
1734 cchBuf
= cchProp
+ 1
1735 + pTarget
->value_length
+ 1
1736 + pSource
->value_length
+ 1
1738 + (pTool
? pTool
->value_length
+ 1 : 0)
1739 + pType
->value_length
+ 1
1740 + pBldTrg
->value_length
+ 1
1741 + pBldTrgArch
->value_length
+ 1
1742 + pBldTrgCpu
->value_length
+ 1
1743 + pBldType
->value_length
+ 1
1745 pszBuf
= xmalloc(cchBuf
);
1748 * Get the variables.
1750 * The compiler will get a heart attack when it sees this code ... ;-)
1752 cVars
= 12 * (pSdks
->c
+ 5);
1753 paVars
= (struct kbuild_collect_variable
*)alloca(cVars
* sizeof(paVars
[0]));
1758 #define ADD_VAR(pVar) do { my_memcpy(psz, (pVar)->value, (pVar)->value_length); psz += (pVar)->value_length; } while (0)
1759 #define ADD_STR(pszStr, cchStr) do { my_memcpy(psz, (pszStr), (cchStr)); psz += (cchStr); } while (0)
1760 #define ADD_CSTR(pszStr) do { my_memcpy(psz, pszStr, sizeof(pszStr) - 1); psz += sizeof(pszStr) - 1; } while (0)
1761 #define ADD_CH(ch) do { *psz++ = (ch); } while (0)
1762 #define DO_VAR_LOOKUP() \
1764 pVar = kbuild_lookup_variable_n(pszBuf, psz - pszBuf); \
1767 paVars[iVar].pVar = pVar; \
1768 if ( !pVar->recursive \
1769 || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(pVar)) \
1771 paVars[iVar].pszExp = pVar->value; \
1772 paVars[iVar].cchExp = pVar->value_length; \
1773 if (pDefPath && paVars[iVar].cchExp) \
1774 kbuild_apply_defpath(pDefPath, &paVars[iVar].pszExp, &paVars[iVar].cchExp, NULL, 0); \
1775 if (paVars[iVar].cchExp) \
1777 cchTotal += paVars[iVar].cchExp + 1; \
1783 paVars[iVar].pszExp = allocated_variable_expand_2(pVar->value, pVar->value_length, &paVars[iVar].cchExp); \
1784 if (pDefPath && paVars[iVar].cchExp) \
1785 kbuild_apply_defpath(pDefPath, &paVars[iVar].pszExp, &paVars[iVar].cchExp, NULL, 1); \
1786 if (paVars[iVar].cchExp) \
1788 cchTotal += paVars[iVar].cchExp + 1; \
1792 free(paVars[iVar].pszExp); \
1796 #define DO_SINGLE_PSZ3_VARIATION() \
1802 ADD_VAR(pBldType); \
1810 ADD_VAR(pBldTrgArch); \
1816 ADD_VAR(pBldTrgArch); \
1820 ADD_VAR(pBldTrgCpu); \
1824 #define DO_DOUBLE_PSZ2_VARIATION() \
1827 ADD_STR(pszProp, cchProp); \
1828 DO_SINGLE_PSZ3_VARIATION(); \
1830 /* add prop before type */ \
1833 ADD_STR(pszProp, cchProp); \
1834 DO_SINGLE_PSZ3_VARIATION(); \
1838 * The first bunch part may be cached on the target already, check that first:
1844 ADD_STR(pszProp
, cchProp
);
1848 pVar
= kbuild_lookup_variable_n(pszBuf
, psz
- pszBuf
);
1853 /* the tool (lowest priority). */
1858 DO_DOUBLE_PSZ2_VARIATION();
1860 /* the global sdks. */
1861 iSdkEnd
= iDirection
== 1 ? pSdks
->iGlobal
+ pSdks
->cGlobal
: pSdks
->iGlobal
- 1;
1862 for (iSdk
= iDirection
== 1 ? pSdks
->iGlobal
: pSdks
->iGlobal
+ pSdks
->cGlobal
- 1;
1866 struct variable
*pSdk
= &pSdks
->pa
[iSdk
];
1871 DO_DOUBLE_PSZ2_VARIATION();
1876 DO_DOUBLE_PSZ2_VARIATION();
1878 /* the target sdks. */
1879 iSdkEnd
= iDirection
== 1 ? pSdks
->iTarget
+ pSdks
->cTarget
: pSdks
->iTarget
- 1;
1880 for (iSdk
= iDirection
== 1 ? pSdks
->iTarget
: pSdks
->iTarget
+ pSdks
->cTarget
- 1;
1884 struct variable
*pSdk
= &pSdks
->pa
[iSdk
];
1889 DO_DOUBLE_PSZ2_VARIATION();
1896 DO_DOUBLE_PSZ2_VARIATION();
1899 * Cache the result thus far (frees up anything we might've allocated above).
1905 ADD_STR(pszProp
, cchProp
);
1909 assert(iVar
<= cVars
);
1910 pVar
= kbuild_collect_source_prop_create_var(cchTotal
, iVar
, paVars
, iDirection
, pszBuf
, psz
- pszBuf
, o_file
);
1914 /* Now we use the cached target variable. */
1915 paVars
[0].pVar
= pVar
;
1916 paVars
[0].pszExp
= pVar
->value
;
1917 paVars
[0].cchExp
= pVar
->value_length
;
1918 cchTotal
= paVars
[0].cchExp
+ 1;
1921 /* the source sdks. */
1922 iSdkEnd
= iDirection
== 1 ? pSdks
->iSource
+ pSdks
->cSource
: pSdks
->iSource
- 1;
1923 for (iSdk
= iDirection
== 1 ? pSdks
->iSource
: pSdks
->iSource
+ pSdks
->cSource
- 1;
1927 struct variable
*pSdk
= &pSdks
->pa
[iSdk
];
1932 DO_DOUBLE_PSZ2_VARIATION();
1939 DO_DOUBLE_PSZ2_VARIATION();
1941 /* the target + source sdks. */
1942 iSdkEnd
= iDirection
== 1 ? pSdks
->iTargetSource
+ pSdks
->cTargetSource
: pSdks
->iTargetSource
- 1;
1943 for (iSdk
= iDirection
== 1 ? pSdks
->iTargetSource
: pSdks
->iTargetSource
+ pSdks
->cTargetSource
- 1;
1947 struct variable
*pSdk
= &pSdks
->pa
[iSdk
];
1952 DO_DOUBLE_PSZ2_VARIATION();
1955 /* the target + source. */
1961 DO_DOUBLE_PSZ2_VARIATION();
1966 * Construct the result value (frees up anything we might've allocated above).
1968 assert(iVar
<= cVars
);
1969 return kbuild_collect_source_prop_create_var(cchTotal
, iVar
, paVars
, iDirection
, pszVarName
, cchVarName
, o_local
);
1975 #undef DO_VAR_LOOKUP
1976 #undef DO_DOUBLE_PSZ2_VARIATION
1977 #undef DO_SINGLE_PSZ3_VARIATION
1981 /* "kb-src-prop <prop> <var> <dir> [defpath] [ver]"
1982 get a source property. */
1984 func_kbuild_source_prop(char *o
, char **argv
, const char *pszFuncName
)
1986 struct variable
*pTarget
= kbuild_get_variable_n(ST("target"));
1987 struct variable
*pSource
= kbuild_get_variable_n(ST("source"));
1988 struct variable
*pDefPath
= NULL
;
1989 struct variable
*pType
= kbuild_get_variable_n(ST("type"));
1990 struct variable
*pTool
= kbuild_get_variable_n(ST("tool"));
1991 struct variable
*pBldType
= kbuild_get_variable_n(ST("bld_type"));
1992 struct variable
*pBldTrg
= kbuild_get_variable_n(ST("bld_trg"));
1993 struct variable
*pBldTrgArch
= kbuild_get_variable_n(ST("bld_trg_arch"));
1994 struct variable
*pBldTrgCpu
= kbuild_get_variable_n(ST("bld_trg_cpu"));
1995 struct variable
*pVar
;
1996 struct kbuild_sdks Sdks
;
1999 if (!strcmp(argv
[2], "left-to-right"))
2001 else if (!strcmp(argv
[2], "right-to-left"))
2004 OS(fatal
, NILF
, _("incorrect direction argument `%s'!"), argv
[2]);
2007 const char *psz
= argv
[3];
2008 while (ISSPACE(*psz
))
2011 pDefPath
= kbuild_get_variable_n(ST("defpath"));
2013 iVer
= kbuild_version_to_int(argv
[4], 1 /*strict*/);
2016 kbuild_get_sdks(&Sdks
, pTarget
, pSource
, pBldType
, pBldTrg
, pBldTrgArch
);
2018 pVar
= kbuild_collect_source_prop(pTarget
, pSource
, pTool
, &Sdks
, pType
,
2019 pBldType
, pBldTrg
, pBldTrgArch
, pBldTrgCpu
,
2021 argv
[0], strlen(argv
[0]),
2022 argv
[1], strlen(argv
[1]),
2025 o
= variable_buffer_output(o
, pVar
->value
, pVar
->value_length
);
2027 kbuild_put_sdks(&Sdks
);
2028 (void)pszFuncName
; (void)iVer
;
2034 dep := $(obj)$(SUFF_DEP)
2035 obj := $(outbase)$(objsuff)
2036 dirdep := $(call DIRDEP,$(dir $(outbase)))
2037 PATH_$(target)_$(source) := $(patsubst %/,%,$(dir $(outbase)))
2039 static struct variable
*
2040 kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(struct variable
*pTarget
, struct variable
*pSource
,
2041 struct variable
*pOutBase
, struct variable
*pObjSuff
,
2042 const char *pszVarName
, struct variable
**ppDep
,
2043 struct variable
**ppDirDep
)
2045 struct variable
*pDepSuff
= kbuild_get_variable_n(ST("SUFF_DEP"));
2046 struct variable
*pObj
;
2047 size_t cch
= pOutBase
->value_length
+ pObjSuff
->value_length
+ pDepSuff
->value_length
+ 1;
2048 char *pszResult
= alloca(cch
);
2049 char *pszName
, *psz
;
2055 memcpy(psz
, pOutBase
->value
, pOutBase
->value_length
); psz
+= pOutBase
->value_length
;
2056 memcpy(psz
, pObjSuff
->value
, pObjSuff
->value_length
); psz
+= pObjSuff
->value_length
;
2057 memcpy(psz
, pDepSuff
->value
, pDepSuff
->value_length
+ 1);
2058 *ppDep
= define_variable_vl("dep", 3, pszResult
, cch
- 1, 1 /*dup*/, o_local
, 0 /* !recursive */);
2064 pObj
= define_variable_vl(pszVarName
, strlen(pszVarName
), pszResult
, psz
- pszResult
,
2065 1/* dup */, o_local
, 0 /* !recursive */);
2068 * PATH_$(target)_$(source) - this is global!
2070 /* calc variable name. */
2071 cch
= sizeof("PATH_")-1 + pTarget
->value_length
+ sizeof("_")-1 + pSource
->value_length
;
2072 psz
= pszName
= alloca(cch
+ 1);
2073 memcpy(psz
, "PATH_", sizeof("PATH_") - 1); psz
+= sizeof("PATH_") - 1;
2074 memcpy(psz
, pTarget
->value
, pTarget
->value_length
); psz
+= pTarget
->value_length
;
2076 memcpy(psz
, pSource
->value
, pSource
->value_length
+ 1);
2078 /* strip off the filename. */
2079 psz
= pszResult
+ pOutBase
->value_length
;
2083 if (psz
<= pszResult
)
2084 OS(fatal
, NULL
, "whut!?! no path? result=`%s'", pszResult
);
2085 #ifdef HAVE_DOS_PATHS
2093 #ifdef HAVE_DOS_PATHS
2098 while ( psz
- 1 > pszResult
2100 #ifdef HAVE_DOS_PATHS
2105 #ifdef HAVE_DOS_PATHS
2106 if (psz
== pszResult
+ 2 && pszResult
[1] == ':')
2114 /* set global variable */
2115 define_variable_vl_global(pszName
, cch
, pszResult
, psz
- pszResult
, 1/*dup*/, o_file
, 0 /* !recursive */, NILF
);
2121 #ifdef HAVE_DOS_PATHS
2130 *ppDirDep
= define_variable_vl("dirdep", 6, pszResult
, psz
- pszResult
, 1/*dup*/, o_local
, 0 /* !recursive */);
2139 * Setup the base variables for def_target_source_c_cpp_asm_new:
2142 X := $(kb-src-tool tool)
2143 x := $(kb-obj-base outbase)
2144 x := $(kb-obj-suff objsuff)
2145 obj := $(outbase)$(objsuff)
2146 PATH_$(target)_$(source) := $(patsubst %/,%,$(dir $(outbase)))
2148 x := $(kb-src-prop DEFS,defs,left-to-right)
2149 x := $(kb-src-prop INCS,incs,right-to-left)
2150 x := $(kb-src-prop FLAGS,flags,right-to-left)
2152 x := $(kb-src-prop DEPS,deps,left-to-right)
2153 dirdep := $(call DIRDEP,$(dir $(outbase)))
2154 dep := $(obj)$(SUFF_DEP)
2157 * argv[0] is the function version. Prior to r1792 (early 0.1.5) this
2158 * was undefined and footer.kmk always passed an empty string.
2160 * Version 2, as implemented in r1797, will make use of the async
2161 * includedep queue feature. This means the files will be read by one or
2162 * more background threads, leaving the eval'ing to be done later on by
2163 * the main thread (in snap_deps).
2165 * Version 3, as implemented in rXXXX, will check
2166 * TOOL_$(tool)_COMPILE_$(type)_USES_KOBJCACHE and use
2167 * def_target_source_rule_v3plus_objcache if it's non-empty or
2168 * def_target_source_rule_v3plus if it's empty (version 2 and older will use
2169 * def_target_source_rule). Version 3 will also skip defining several
2170 * properties that it considers legacy (todo: which).
2172 * Version 4, as implemented in r3415, will use the extended tool resolution at
2173 * the target level (not source) as implemented by the _TARGET_TOOL update in
2176 * With r3415 the $(target)_2_$(type)TOOL will be used for caching purposes
2177 * regardless of version.
2180 func_kbuild_source_one(char *o
, char **argv
, const char *pszFuncName
)
2182 static int s_fNoCompileDepsDefined
= -1;
2183 struct variable
*pTarget
= kbuild_get_variable_n(ST("target"));
2184 struct variable
*pSource
= kbuild_get_variable_n(ST("source"));
2185 struct variable
*pDefPath
= kbuild_get_variable_n(ST("defpath"));
2186 struct variable
*pType
= kbuild_get_variable_n(ST("type"));
2187 struct variable
*pBldType
= kbuild_get_variable_n(ST("bld_type"));
2188 struct variable
*pBldTrg
= kbuild_get_variable_n(ST("bld_trg"));
2189 struct variable
*pBldTrgArch
= kbuild_get_variable_n(ST("bld_trg_arch"));
2190 struct variable
*pBldTrgCpu
= kbuild_get_variable_n(ST("bld_trg_cpu"));
2191 const int iVer
= kbuild_version_to_int(argv
[0], 0 /*strict*/);
2192 struct variable
*pTool
= kbuild_get_source_tool(pTarget
, pSource
, pType
, pBldTrg
, pBldTrgArch
,
2193 iVer
>= 4 ? pBldType
: NULL
, "tool");
2194 struct variable
*pOutBase
= kbuild_get_object_base(pTarget
, pSource
, "outbase");
2195 struct variable
*pObjSuff
= kbuild_get_object_suffix(pTarget
, pSource
, pTool
, pType
, pBldTrg
, pBldTrgArch
,
2196 iVer
>= 4 ? pBldType
: NULL
, "objsuff");
2197 struct variable
*pDeps
, *pOrderDeps
, *pDirDep
, *pDep
, *pVar
, *pOutput
, *pOutputMaybe
;
2198 #if 0 /* not used */
2199 struct variable
*pDefs
, *pIncs
, *pFlags
;
2201 struct variable
*pObj
= kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(pTarget
, pSource
, pOutBase
, pObjSuff
, "obj", &pDep
, &pDirDep
);
2202 int fInstallOldObjsVar
= 0;
2203 char *pszDstVar
, *pszDst
, *pszSrcVar
, *pszSrc
, *pszVal
, *psz
;
2204 char *pszSavedVarBuf
;
2205 unsigned cchSavedVarBuf
;
2207 struct kbuild_sdks Sdks
;
2210 * Gather properties.
2212 kbuild_get_sdks(&Sdks
, pTarget
, pSource
, pBldType
, pBldTrg
, pBldTrgArch
);
2214 if (pDefPath
&& !pDefPath
->value_length
)
2218 /*pDefs =*/ kbuild_collect_source_prop(pTarget
, pSource
, pTool
, &Sdks
, pType
, pBldType
, pBldTrg
, pBldTrgArch
, pBldTrgCpu
, NULL
,
2219 ST("DEFS"), ST("defs"), 1 /* left-to-right */);
2220 /*pIncs =*/ kbuild_collect_source_prop(pTarget
, pSource
, pTool
, &Sdks
, pType
, pBldType
, pBldTrg
, pBldTrgArch
, pBldTrgCpu
, pDefPath
,
2221 ST("INCS"), ST("incs"), -1 /* right-to-left */);
2222 /*pFlags =*/ kbuild_collect_source_prop(pTarget
, pSource
, pTool
, &Sdks
, pType
, pBldType
, pBldTrg
, pBldTrgArch
, pBldTrgCpu
, NULL
,
2223 ST("FLAGS"), ST("flags"), 1 /* left-to-right */);
2224 pDeps
= kbuild_collect_source_prop(pTarget
, pSource
, pTool
, &Sdks
, pType
, pBldType
, pBldTrg
, pBldTrgArch
, pBldTrgCpu
, pDefPath
,
2225 ST("DEPS"), ST("deps"), 1 /* left-to-right */);
2226 pOrderDeps
= kbuild_collect_source_prop(pTarget
, pSource
, pTool
, &Sdks
, pType
, pBldType
, pBldTrg
, pBldTrgArch
, pBldTrgCpu
, pDefPath
,
2227 ST("ORDERDEPS"), ST("orderdeps"), 1 /* left-to-right */);
2230 * If we've got a default path, we must expand the source now.
2231 * If we do this too early, "<source>_property = stuff" won't work becuase
2232 * our 'source' value isn't what the user expects.
2236 /** @todo assert(pSource->origin != o_automatic); We're changing 'source'
2237 * from the foreach loop! */
2238 #ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
2239 assert(!pSource
->rdonly_val
);
2241 kbuild_apply_defpath(pDefPath
, &pSource
->value
, &pSource
->value_length
, &pSource
->value_alloc_len
, 1 /* can free */);
2246 ifndef NO_COMPILE_DEPS
2247 _DEPFILES_INCLUDED += $(dep)
2248 $(if $(wildcard $(dep)),$(eval include $(dep)))
2251 if (s_fNoCompileDepsDefined
== -1)
2252 s_fNoCompileDepsDefined
= kbuild_lookup_variable_n(ST("NO_COMPILE_DEPS")) != NULL
;
2253 if (!s_fNoCompileDepsDefined
)
2255 pVar
= kbuild_query_recursive_variable_n("_DEPFILES_INCLUDED", sizeof("_DEPFILES_INCLUDED") - 1);
2258 if (pVar
->recursive
)
2259 pVar
= kbuild_simplify_variable(pVar
);
2260 append_string_to_variable(pVar
, pDep
->value
, pDep
->value_length
, 1 /* append */);
2263 define_variable_vl_global("_DEPFILES_INCLUDED", sizeof("_DEPFILES_INCLUDED") - 1,
2264 pDep
->value
, pDep
->value_length
,
2265 1 /* duplicate_value */,
2270 eval_include_dep(pDep
->value
, NILF
, iVer
>= 2 ? incdep_queue
: incdep_read_it
);
2275 $(target)_$(source)_CMDS_ := $(TOOL_$(tool)_COMPILE_$(type)_CMDS)
2276 $(target)_$(source)_OUTPUT_ := $(TOOL_$(tool)_COMPILE_$(type)_OUTPUT)
2277 $(target)_$(source)_OUTPUT_MAYBE_ := $(TOOL_$(tool)_COMPILE_$(type)_OUTPUT_MAYBE)
2278 $(target)_$(source)_DEPEND_ := $(TOOL_$(tool)_COMPILE_$(type)_DEPEND) $(deps) $(source)
2279 $(target)_$(source)_DEPORD_ := $(TOOL_$(tool)_COMPILE_$(type)_DEPORD) $(dirdep)
2281 /** @todo Make all these local variables, if someone needs the info later it
2282 * can be recalculated. (Ticket #80.) */
2283 cch
= sizeof("TOOL_") + pTool
->value_length
+ sizeof("_COMPILE_") + pType
->value_length
+ sizeof("_USES_KOBJCACHE");
2284 if (cch
< pTarget
->value_length
+ sizeof("$(_2_OBJS)"))
2285 cch
= pTarget
->value_length
+ sizeof("$(_2_OBJS)");
2286 psz
= pszSrcVar
= alloca(cch
);
2287 memcpy(psz
, "TOOL_", sizeof("TOOL_") - 1); psz
+= sizeof("TOOL_") - 1;
2288 memcpy(psz
, pTool
->value
, pTool
->value_length
); psz
+= pTool
->value_length
;
2289 memcpy(psz
, "_COMPILE_", sizeof("_COMPILE_") - 1); psz
+= sizeof("_COMPILE_") - 1;
2290 memcpy(psz
, pType
->value
, pType
->value_length
); psz
+= pType
->value_length
;
2293 cch
= pTarget
->value_length
+ 1 + pSource
->value_length
+ sizeof("_OUTPUT_MAYBE_");
2294 psz
= pszDstVar
= alloca(cch
);
2295 memcpy(psz
, pTarget
->value
, pTarget
->value_length
); psz
+= pTarget
->value_length
;
2297 memcpy(psz
, pSource
->value
, pSource
->value_length
); psz
+= pSource
->value_length
;
2300 memcpy(pszSrc
, "_CMDS", sizeof("_CMDS"));
2301 memcpy(pszDst
, "_CMDS_", sizeof("_CMDS_"));
2302 pVar
= kbuild_get_recursive_variable(pszSrcVar
);
2304 do_variable_definition_2(NILF
, pszDstVar
, pVar
->value
, pVar
->value_length
,
2305 !pVar
->recursive
, 0, o_local
, f_simple
, 0 /* !target_var */);
2306 do_variable_definition_2(NILF
, "kbsrc_cmds", pVar
->value
, pVar
->value_length
,
2307 !pVar
->recursive
, 0, o_local
, f_simple
, 0 /* !target_var */);
2309 memcpy(pszSrc
, "_OUTPUT", sizeof("_OUTPUT"));
2310 memcpy(pszDst
, "_OUTPUT_", sizeof("_OUTPUT_"));
2311 pVar
= kbuild_get_recursive_variable(pszSrcVar
);
2313 pOutput
= do_variable_definition_2(NILF
, pszDstVar
, pVar
->value
, pVar
->value_length
,
2314 !pVar
->recursive
, 0, o_local
, f_simple
, 0 /* !target_var */);
2315 pOutput
= do_variable_definition_2(NILF
, "kbsrc_output", pVar
->value
, pVar
->value_length
,
2316 !pVar
->recursive
, 0, o_local
, f_simple
, 0 /* !target_var */);
2318 memcpy(pszSrc
, "_OUTPUT_MAYBE", sizeof("_OUTPUT_MAYBE"));
2319 memcpy(pszDst
, "_OUTPUT_MAYBE_", sizeof("_OUTPUT_MAYBE_"));
2320 pVar
= kbuild_query_recursive_variable(pszSrcVar
);
2324 pOutputMaybe
= do_variable_definition_2(NILF
, pszDstVar
, pVar
->value
, pVar
->value_length
,
2325 !pVar
->recursive
, 0, o_local
, f_simple
, 0 /* !target_var */);
2326 pOutputMaybe
= do_variable_definition_2(NILF
, "kbsrc_output_maybe", pVar
->value
, pVar
->value_length
,
2327 !pVar
->recursive
, 0, o_local
, f_simple
, 0 /* !target_var */);
2332 pOutputMaybe
= do_variable_definition_2(NILF
, pszDstVar
, "", 0, 1, 0, o_local
, f_simple
, 0 /* !target_var */);
2333 pOutputMaybe
= do_variable_definition_2(NILF
, "kbsrc_output_maybe", "", 0, 1, 0, o_local
, f_simple
, 0 /* !target_var */);
2336 memcpy(pszSrc
, "_DEPEND", sizeof("_DEPEND"));
2337 memcpy(pszDst
, "_DEPEND_", sizeof("_DEPEND_"));
2338 pVar
= kbuild_get_recursive_variable(pszSrcVar
);
2339 psz
= pszVal
= xmalloc(pVar
->value_length
+ 1 + pDeps
->value_length
+ 1 + pSource
->value_length
+ 1);
2340 memcpy(psz
, pVar
->value
, pVar
->value_length
); psz
+= pVar
->value_length
;
2342 memcpy(psz
, pDeps
->value
, pDeps
->value_length
); psz
+= pDeps
->value_length
;
2344 memcpy(psz
, pSource
->value
, pSource
->value_length
+ 1);
2346 do_variable_definition_2(NILF
, pszDstVar
, pszVal
, pVar
->value_length
+ 1 + pDeps
->value_length
+ 1 + pSource
->value_length
,
2347 !pVar
->recursive
&& !pDeps
->recursive
&& !pSource
->recursive
,
2348 NULL
, o_local
, f_simple
, 0 /* !target_var */);
2349 do_variable_definition_2(NILF
, "kbsrc_depend", pszVal
, pVar
->value_length
+ 1 + pDeps
->value_length
+ 1 + pSource
->value_length
,
2350 !pVar
->recursive
&& !pDeps
->recursive
&& !pSource
->recursive
,
2351 pszVal
, o_local
, f_simple
, 0 /* !target_var */);
2353 memcpy(pszSrc
, "_DEPORD", sizeof("_DEPORD"));
2354 memcpy(pszDst
, "_DEPORD_", sizeof("_DEPORD_"));
2355 pVar
= kbuild_get_recursive_variable(pszSrcVar
);
2356 psz
= pszVal
= xmalloc(pVar
->value_length
+ 1 + pDirDep
->value_length
+ 1 + pOrderDeps
->value_length
+ 1);
2357 memcpy(psz
, pVar
->value
, pVar
->value_length
); psz
+= pVar
->value_length
;
2359 memcpy(psz
, pDirDep
->value
, pDirDep
->value_length
); psz
+= pDirDep
->value_length
;
2361 memcpy(psz
, pOrderDeps
->value
, pOrderDeps
->value_length
+ 1);
2363 do_variable_definition_2(NILF
, pszDstVar
, pszVal
,
2364 pVar
->value_length
+ 1 + pDirDep
->value_length
+ 1 + pOrderDeps
->value_length
,
2365 !pVar
->recursive
&& !pDirDep
->recursive
&& !pOrderDeps
->recursive
,
2366 NULL
, o_local
, f_simple
, 0 /* !target_var */);
2367 do_variable_definition_2(NILF
, "kbsrc_depord", pszVal
,
2368 pVar
->value_length
+ 1 + pDirDep
->value_length
+ 1 + pOrderDeps
->value_length
,
2369 !pVar
->recursive
&& !pDirDep
->recursive
&& !pOrderDeps
->recursive
,
2370 pszVal
, o_local
, f_simple
, 0 /* !target_var */);
2373 _OUT_FILES += $($(target)_$(source)_OUTPUT_) $($(target)_$(source)_OUTPUT_MAYBE_)
2375 pVar
= kbuild_get_variable_n(ST("_OUT_FILES"));
2376 append_string_to_variable(pVar
, pOutput
->value
, pOutput
->value_length
, 1 /* append */);
2377 if (pOutputMaybe
->value_length
)
2378 append_string_to_variable(pVar
, pOutputMaybe
->value
, pOutputMaybe
->value_length
, 1 /* append */);
2381 $(target)_2_OBJS += $(obj)
2383 memcpy(pszDstVar
+ pTarget
->value_length
, "_2_OBJS", sizeof("_2_OBJS"));
2384 pVar
= kbuild_query_recursive_variable_n(pszDstVar
, pTarget
->value_length
+ sizeof("_2_OBJS") - 1);
2385 fInstallOldObjsVar
|= iVer
<= 2 && (!pVar
|| !pVar
->value_length
);
2388 if (pVar
->recursive
)
2389 pVar
= kbuild_simplify_variable(pVar
);
2390 append_string_to_variable(pVar
, pObj
->value
, pObj
->value_length
, 1 /* append */);
2393 define_variable_vl_global(pszDstVar
, pTarget
->value_length
+ sizeof("_2_OBJS") - 1,
2394 pObj
->value
, pObj
->value_length
,
2395 1 /* duplicate_value */,
2401 * Install legacy variable.
2403 if (fInstallOldObjsVar
)
2405 /* $(target)_OBJS_ = $($(target)_2_OBJS)*/
2406 memcpy(pszDstVar
+ pTarget
->value_length
, "_OBJS_", sizeof("_OBJS_"));
2410 memcpy(pszSrcVar
+ 2, pTarget
->value
, pTarget
->value_length
);
2411 psz
= pszSrcVar
+ 2 + pTarget
->value_length
;
2412 memcpy(psz
, "_2_OBJS)", sizeof("_2_OBJS)"));
2414 define_variable_vl_global(pszDstVar
, pTarget
->value_length
+ sizeof("_OBJS_") - 1,
2415 pszSrcVar
, pTarget
->value_length
+ sizeof("$(_2_OBJS)") - 1,
2416 1 /* duplicate_value */,
2423 $(eval $(def_target_source_rule))
2427 /*ifneq ($(TOOL_$(tool)_COMPILE_$(type)_USES_KOBJCACHE),)*/
2428 int fUsesObjCache
= 0;
2429 memcpy(pszSrc
, "_USES_KOBJCACHE", sizeof("_USES_KOBJCACHE"));
2430 pVar
= lookup_variable(pszSrcVar
, pszSrc
+ sizeof("_USES_KOBJCACHE") - 1 - pszSrcVar
);
2433 if ( !pVar
->recursive
2434 || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(pVar
))
2435 fUsesObjCache
= pVar
->value_length
> 0;
2438 unsigned int cchTmp
= 0;
2439 char *pszTmp
= allocated_variable_expand_2(pVar
->value
, pVar
->value_length
, &cchTmp
);
2441 fUsesObjCache
= cchTmp
> 0;
2445 pVar
= kbuild_get_recursive_variable("def_target_source_rule_v3plus");
2447 pVar
= kbuild_get_recursive_variable("def_target_source_rule_v3plus_objcache");
2450 pVar
= kbuild_get_recursive_variable("def_target_source_rule");
2451 pszVal
= variable_expand_string_2(o
, pVar
->value
, pVar
->value_length
, &psz
);
2452 assert(!((size_t)pszVal
& 3));
2454 install_variable_buffer(&pszSavedVarBuf
, &cchSavedVarBuf
);
2455 eval_buffer(pszVal
, NULL
, psz
);
2456 restore_variable_buffer(pszSavedVarBuf
, cchSavedVarBuf
);
2458 kbuild_put_sdks(&Sdks
);
2467 ## Inherit one template property in a non-accumulative manner.
2468 # @param $(prop) Property name
2469 # @param $(target) Target name
2470 # @todo fix the precedence order for some properties.
2471 define def_inherit_template_one
2472 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop)
2473 ifndef $(target)_$(prop)
2474 $(target)_$(prop) := $(TEMPLATE_$($(target)_TEMPLATE)_$(prop))
2477 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg)
2478 ifndef $(target)_$(prop).$(bld_trg)
2479 $(target)_$(prop).$(bld_trg) := $(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg))
2482 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch)
2483 ifndef $(target)_$(prop).$(bld_trg).$(bld_trg_arch)
2484 $(target)_$(prop).$(bld_trg).$(bld_trg_arch) := $(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch))
2487 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch)
2488 ifndef $(target)_$(prop).$(bld_trg_arch)
2489 $(target)_$(prop).$(bld_trg_arch) := $(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch))
2492 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu)
2493 ifndef $(target)_$(prop).$(bld_trg_cpu)
2494 $(target)_$(prop).$(bld_trg_cpu) := $(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu))
2499 ## Inherit one template property in a non-accumulative manner, deferred expansion.
2500 # @param 1: $(prop) Property name
2501 # @param 2: $(target) Target name
2502 # @todo fix the precedence order for some properties.
2503 # @remark this define relies on double evaluation
2504 define def_inherit_template_one_deferred
2505 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop)
2506 ifndef $(target)_$(prop)
2507 $(target)_$(prop) = $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop))
2510 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg)
2511 ifndef $(target)_$(prop).$(bld_trg)
2512 $(target)_$(prop).$(bld_trg) = $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg))
2515 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch)
2516 ifndef $(target)_$(prop).$(bld_trg).$(bld_trg_arch)
2517 $(target)_$(prop).$(bld_trg).$(bld_trg_arch) = $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch))
2520 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch)
2521 ifndef $(target)_$(prop).$(bld_trg_arch)
2522 $(target)_$(prop).$(bld_trg_arch) = $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch))
2525 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu)
2526 ifndef $(target)_$(prop).$(bld_trg_cpu)
2527 $(target)_$(prop).$(bld_trg_cpu) = $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu))
2532 ## Inherit one acculumlative template property where the 'most significant' items are at the left end.
2533 # @param $(prop) Property name
2534 # @param $(target) Target name
2535 define def_inherit_template_one_accumulate_l
2536 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop)
2537 ifeq ($$(flavor $(target)_$(prop)),simple)
2538 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop))
2540 $(target)_$(prop) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop))
2542 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(KBUILD_TYPE)
2543 ifeq ($$(flavor $(target)_$(prop).$(KBUILD_TYPE)),simple)
2544 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(KBUILD_TYPE))
2546 $(target)_$(prop).$(KBUILD_TYPE) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(KBUILD_TYPE))
2548 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg)
2549 ifeq ($$(flavor $(target)_$(prop).$(bld_trg)),simple)
2550 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg))
2552 $(target)_$(prop).$(bld_trg) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg))
2554 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch)
2555 ifeq ($$(flavor $(target)_$(prop).$(bld_trg).$(bld_trg_arch)),simple)
2556 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg).$(bld_trg_arch))
2558 $(target)_$(prop).$(bld_trg).$(bld_trg_arch) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch))
2560 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu)
2561 ifeq ($$(flavor $(target)_$(prop).$(bld_trg_cpu)),simple)
2562 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg_cpu))
2564 $(target)_$(prop).$(bld_trg_cpu) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu))
2566 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch)
2567 ifeq ($$(flavor $(target)_$(prop).$(bld_trg_arch)),simple)
2568 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg_arch))
2570 $(target)_$(prop).$(bld_trg_arch) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch))
2574 ## Inherit one acculumlative template property where the 'most significant' items are at the right end.
2575 # @param $(prop) Property name
2576 # @param $(target) Target name
2577 define def_inherit_template_one_accumulate_r
2578 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop)
2579 ifeq ($$(flavor $(target)_$(prop)),simple)
2580 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop))
2582 $(target)_$(prop) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop))
2584 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(KBUILD_TYPE)
2585 ifeq ($$(flavor $(target)_$(prop).$(KBUILD_TYPE)),simple)
2586 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(KBUILD_TYPE))
2588 $(target)_$(prop).$(KBUILD_TYPE) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(KBUILD_TYPE))
2590 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg)
2591 ifeq ($$(flavor $(target)_$(prop).$(bld_trg)),simple)
2592 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg))
2594 $(target)_$(prop).$(bld_trg) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg))
2596 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch)
2597 ifeq ($$(flavor $(target)_$(prop).$(bld_trg).$(bld_trg_arch)),simple)
2598 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg).$(bld_trg_arch))
2600 $(target)_$(prop).$(bld_trg).$(bld_trg_arch) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch))
2602 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu)
2603 ifeq ($$(flavor $(target)_$(prop).$(bld_trg_cpu)),simple)
2604 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg_cpu))
2606 $(target)_$(prop).$(bld_trg_cpu) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu))
2608 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch)
2609 ifeq ($$(flavor $(target)_$(prop).$(bld_trg_arch)),simple)
2610 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg_arch))
2612 $(target)_$(prop).$(bld_trg_arch) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch))
2617 ## Inherit template properties for on target.
2618 # @param $(target) Target name.
2619 define def_inherit_template
2621 ifdef _$(target)_ALREADY_PROCESSED
2622 $(error kBuild: The target $(target) appears more than once in the target lists! Please correct the makefile(s))
2624 _$(target)_ALREADY_PROCESSED := 1
2626 # Inherit any default template.
2628 ifeq ($($(target)_TEMPLATE),)
2629 $(eval $(target)_TEMPLATE:=$(TEMPLATE))
2632 # Expand the template if specified.
2633 ifneq ($($(target)_TEMPLATE),)
2634 $(foreach prop,$(PROPS_SINGLE),$(evalval def_inherit_template_one))
2635 $(foreach prop,$(PROPS_DEFERRED),$(eval $(def_inherit_template_one_deferred))) # exploits the 2 evaluation, so no value!
2636 $(foreach prop,$(PROPS_ACCUMULATE_L),$(eval $(def_inherit_template_one_accumulate_l))) # += works fine without value
2637 $(foreach prop,$(PROPS_ACCUMULATE_R),$(eval $(def_inherit_template_one_accumulate_r))) # use <= (kmk addition)
2643 $(kb-exp-tmpl 1,$(_ALL_TARGET_TARGETS),$(KBUILD_TARGET),$(KBUILD_TARGET_ARCH),$(KBUILD_TARGET_CPU),$(KBUILD_TYPE))
2646 func_kbuild_expand_template(char *o
, char **argv
, const char *pszFuncName
)
2648 const char *pszVersion
= argv
[0];
2649 const char *pszBldTrg
= argv
[2];
2650 const char *pszBldTrgArch
= argv
[3];
2651 const char *pszBldTrgCpu
= argv
[4];
2652 const char *pszBldType
= argv
[5];
2653 size_t cchBldTrg
= strlen(pszBldTrg
);
2654 size_t cchBldTrgArch
= strlen(pszBldTrgArch
);
2655 size_t cchBldTrgCpu
= strlen(pszBldTrgCpu
);
2656 size_t cchBldType
= strlen(pszBldType
);
2657 size_t cchMaxBld
= cchBldTrg
+ cchBldTrgArch
+ cchBldTrgCpu
+ cchBldType
; /* too big, but so what. */
2663 unsigned int const cKeys
= 6;
2665 struct variable
*pDefTemplate
;
2666 struct variable
*pProps
;
2671 enum kbet_prop_enum
{ kPropSingle
, kPropDeferred
, kPropAccumulateL
, kPropAccumulateR
}
2674 unsigned int cProps
;
2677 struct variable
*pVarTrg
;
2678 struct variable
*pVarSrc
;
2679 const char *pszIter
;
2680 const char *pszTarget
;
2681 unsigned int cchTarget
;
2683 char *pszSrcRef
= 0;
2684 char *pszSrcBuf
= 0;
2685 size_t cchSrcBuf
= 0;
2692 if (pszVersion
[0] != '1' || pszVersion
[1])
2693 OSS(fatal
, NULL
, "%s: Unsupported version `%s'", pszFuncName
, pszVersion
);
2696 OS(fatal
, NULL
, "%s: missing bldtrg", pszFuncName
);
2699 OS(fatal
, NULL
, "%s: missing bld_trg_arch", pszFuncName
);
2702 OS(fatal
, NULL
, "%s: missing bld_trg_cpu", pszFuncName
);
2705 OS(fatal
, NULL
, "%s: missing bld_type", pszFuncName
);
2708 * Prepare the keywords, prepending dots for quicker copying.
2709 * This allows for an inner loop when processing properties, saving code
2710 * at the expense of a few xmallocs.
2712 /* the first entry is empty. */
2714 aKeys
[0].psz
= NULL
;
2717 aKeys
[1].cch
= cchBldType
+ 1;
2718 aKeys
[1].psz
= xmalloc (aKeys
[1].cch
+ 1);
2719 aKeys
[1].psz
[0] = '.';
2720 memcpy(aKeys
[1].psz
+ 1, pszBldType
, cchBldType
+ 1);
2723 aKeys
[2].cch
= cchBldTrg
+ 1;
2724 aKeys
[2].psz
= xmalloc (aKeys
[2].cch
+ 1);
2725 aKeys
[2].psz
[0] = '.';
2726 memcpy(aKeys
[2].psz
+ 1, pszBldTrg
, cchBldTrg
+ 1);
2728 /* .$(bld_trg).$(bld_trg_arch) */
2729 aKeys
[3].cch
= cchBldTrg
+ 1 + cchBldTrgArch
+ 1;
2730 aKeys
[3].psz
= xmalloc (aKeys
[3].cch
+ 1);
2731 aKeys
[3].psz
[0] = '.';
2732 memcpy(aKeys
[3].psz
+ 1, pszBldTrg
, cchBldTrg
);
2733 aKeys
[3].psz
[1 + cchBldTrg
] = '.';
2734 memcpy(aKeys
[3].psz
+ 1 + cchBldTrg
+ 1, pszBldTrgArch
, cchBldTrgArch
+ 1);
2736 /* .$(bld_trg_cpu) */
2737 aKeys
[4].cch
= cchBldTrgCpu
+ 1;
2738 aKeys
[4].psz
= xmalloc (aKeys
[4].cch
+ 1);
2739 aKeys
[4].psz
[0] = '.';
2740 memcpy(aKeys
[4].psz
+ 1, pszBldTrgCpu
, cchBldTrgCpu
+ 1);
2742 /* .$(bld_trg_arch) */
2743 aKeys
[5].cch
= cchBldTrgArch
+ 1;
2744 aKeys
[5].psz
= xmalloc (aKeys
[5].cch
+ 1);
2745 aKeys
[5].psz
[0] = '.';
2746 memcpy(aKeys
[5].psz
+ 1, pszBldTrgArch
, cchBldTrgArch
+ 1);
2750 * Prepare the properties, folding them into an array.
2751 * This way we won't have to reparse them for each an every target, though
2752 * it comes at the expense of one or more heap calls.
2754 #define PROP_ALLOC_INC 128
2756 cProps
= PROP_ALLOC_INC
;
2757 paProps
= xmalloc(sizeof(*pProps
) * cProps
);
2759 pProps
= kbuild_get_variable_n(ST("PROPS_SINGLE"));
2760 pszIter
= pProps
->value
;
2761 while ((paProps
[iProp
].pch
= find_next_token(&pszIter
, &paProps
[iProp
].cch
)))
2763 paProps
[iProp
].enmType
= kPropSingle
;
2764 if (++iProp
>= cProps
)
2766 cProps
+= PROP_ALLOC_INC
;
2767 paProps
= xrealloc(paProps
, sizeof(*paProps
) * cProps
);
2772 pProps
= kbuild_get_variable_n(ST("PROPS_DEFERRED"));
2773 pszIter
= pProps
->value
;
2774 while ((paProps
[iProp
].pch
= find_next_token(&pszIter
, &paProps
[iProp
].cch
)))
2776 paProps
[iProp
].enmType
= kPropDeferred
;
2777 if (++iProp
>= cProps
)
2779 cProps
+= PROP_ALLOC_INC
;
2780 paProps
= xrealloc(paProps
, sizeof(*paProps
) * cProps
);
2784 pProps
= kbuild_get_variable_n(ST("PROPS_ACCUMULATE_L"));
2785 pszIter
= pProps
->value
;
2786 while ((paProps
[iProp
].pch
= find_next_token(&pszIter
, &paProps
[iProp
].cch
)))
2788 paProps
[iProp
].enmType
= kPropAccumulateL
;
2789 if (++iProp
>= cProps
)
2791 cProps
+= PROP_ALLOC_INC
;
2792 paProps
= xrealloc(paProps
, sizeof(*paProps
) * cProps
);
2796 pProps
= kbuild_get_variable_n(ST("PROPS_ACCUMULATE_R"));
2797 pszIter
= pProps
->value
;
2798 while ((paProps
[iProp
].pch
= find_next_token(&pszIter
, &paProps
[iProp
].cch
)))
2800 paProps
[iProp
].enmType
= kPropAccumulateR
;
2801 if (++iProp
>= cProps
)
2803 cProps
+= PROP_ALLOC_INC
;
2804 paProps
= xrealloc(paProps
, sizeof(*paProps
) * cProps
);
2807 #undef PROP_ALLOC_INC
2810 /* find the max prop length. */
2811 cchMaxProp
= paProps
[0].cch
;
2813 if (paProps
[iProp
].cch
> cchMaxProp
)
2814 cchMaxProp
= paProps
[iProp
].cch
;
2817 * Query and prepare (strip) the default template
2818 * (given by the TEMPLATE variable).
2820 pDefTemplate
= kbuild_lookup_variable_n(ST("TEMPLATE"));
2823 if ( pDefTemplate
->value_length
2824 && ( ISSPACE(pDefTemplate
->value
[0])
2825 || ISSPACE(pDefTemplate
->value
[pDefTemplate
->value_length
- 1])))
2828 if (pDefTemplate
->rdonly_val
)
2829 OS(fatal
, NULL
, "%s: TEMPLATE is read-only", pszFuncName
);
2832 for (off
= 0; ISSPACE(pDefTemplate
->value
[off
]); off
++)
2836 pDefTemplate
->value_length
-= off
;
2837 memmove(pDefTemplate
->value
, pDefTemplate
->value
+ off
, pDefTemplate
->value_length
+ 1);
2841 off
= pDefTemplate
->value_length
;
2842 while (off
> 0 && ISSPACE(pDefTemplate
->value
[off
- 1]))
2844 pDefTemplate
->value_length
= off
;
2845 pDefTemplate
->value
[off
] = '\0';
2847 VARIABLE_CHANGED(pDefTemplate
);
2850 if (!pDefTemplate
->value_length
)
2851 pDefTemplate
= NULL
;
2855 * Iterate the target list.
2858 while ((pszTarget
= find_next_token(&pszIter
, &cchTarget
)))
2860 char *pszTrgProp
, *pszSrcProp
;
2861 char *pszTrgKey
, *pszSrcKey
;
2862 struct variable
*pTmpl
;
2863 const char *pszTmpl
;
2864 size_t cchTmpl
, cchMax
;
2866 /* resize the target buffer. */
2867 cchMax
= cchTarget
+ cchMaxProp
+ cchMaxBld
+ 10;
2868 if (cchTrg
< cchMax
)
2870 cchTrg
= (cchMax
+ 31U) & ~(size_t)31;
2871 pszTrg
= xrealloc(pszTrg
, cchTrg
);
2875 * Query the TEMPLATE property, if not found or zero-length fall back on the default.
2877 memcpy(pszTrg
, pszTarget
, cchTarget
);
2878 pszTrgProp
= pszTrg
+ cchTarget
;
2879 memcpy(pszTrgProp
, "_TEMPLATE", sizeof("_TEMPLATE"));
2880 pszTrgProp
++; /* after '_'. */
2882 /** @todo Change this to a recursive lookup with simplification below. That
2883 * will allow target_TEMPLATE = $(NO_SUCH_TEMPLATE) instead of having
2884 * to use target_TEMPLATE = DUMMY */
2885 pTmpl
= kbuild_lookup_variable_n(pszTrg
, cchTarget
+ sizeof("_TEMPLATE") - 1);
2886 if (!pTmpl
|| !pTmpl
->value_length
)
2889 continue; /* no template */
2890 pszTmpl
= pDefTemplate
->value
;
2891 cchTmpl
= pDefTemplate
->value_length
;
2895 pszTmpl
= pTmpl
->value
;
2896 cchTmpl
= pTmpl
->value_length
;
2897 while (ISSPACE(*pszTmpl
))
2898 cchTmpl
--, pszTmpl
++;
2900 continue; /* no template */
2903 /* resize the source buffer. */
2904 cchMax
= sizeof("TEMPLATE_") + cchTmpl
+ cchMaxProp
+ cchMaxBld
+ 10 + sizeof(void *);
2905 if (cchSrcBuf
< cchMax
)
2907 cchSrcBuf
= (cchMax
+ 31U) & ~(size_t)31;
2908 pszSrcBuf
= xrealloc(pszSrcBuf
, cchSrcBuf
);
2909 pszSrc
= pszSrcBuf
+ sizeof(void *); assert(sizeof(void *) >= 2);
2910 pszSrcRef
= pszSrc
- 2;
2915 /* prepare the source buffer */
2916 memcpy(pszSrc
, "TEMPLATE_", sizeof("TEMPLATE_") - 1);
2917 pszSrcProp
= pszSrc
+ sizeof("TEMPLATE_") - 1;
2918 memcpy(pszSrcProp
, pszTmpl
, cchTmpl
);
2919 pszSrcProp
+= cchTmpl
;
2920 *pszSrcProp
++ = '_';
2923 * Process properties.
2924 * Note! The single and deferred are handled in the same way now.
2926 #define BY_REF_LIMIT 64 /*(cchSrcVar * 4 > 64 ? cchSrcVar * 4 : 64)*/
2928 for (iProp
= 0; iProp
< cProps
; iProp
++)
2930 memcpy(pszTrgProp
, paProps
[iProp
].pch
, paProps
[iProp
].cch
);
2931 pszTrgKey
= pszTrgProp
+ paProps
[iProp
].cch
;
2933 memcpy(pszSrcProp
, paProps
[iProp
].pch
, paProps
[iProp
].cch
);
2934 pszSrcKey
= pszSrcProp
+ paProps
[iProp
].cch
;
2936 for (iKey
= 0; iKey
< cKeys
; iKey
++)
2941 /* lookup source, skip ahead if it doesn't exist. */
2942 memcpy(pszSrcKey
, aKeys
[iKey
].psz
, aKeys
[iKey
].cch
);
2943 cchSrcVar
= pszSrcKey
- pszSrc
+ aKeys
[iKey
].cch
;
2944 pszSrc
[cchSrcVar
] = '\0';
2945 pVarSrc
= kbuild_query_recursive_variable_n(pszSrc
, cchSrcVar
);
2949 /* lookup target, skip ahead if it exists. */
2950 memcpy(pszTrgKey
, aKeys
[iKey
].psz
, aKeys
[iKey
].cch
);
2951 pszTrgEnd
= pszTrgKey
+ aKeys
[iKey
].cch
;
2953 pVarTrg
= kbuild_query_recursive_variable_n(pszTrg
, pszTrgEnd
- pszTrg
);
2955 switch (paProps
[iProp
].enmType
)
2957 case kPropAccumulateL
:
2958 case kPropAccumulateR
:
2961 /* Append to existing variable. If the source is recursive,
2962 or we append by reference, we'll have to make sure the
2963 target is recusive as well. */
2964 if ( !pVarTrg
->recursive
2965 && ( pVarSrc
->value_length
>= BY_REF_LIMIT
2966 || pVarSrc
->recursive
))
2967 pVarTrg
->recursive
= 1;
2969 if (pVarSrc
->value_length
< BY_REF_LIMIT
)
2970 append_string_to_variable(pVarTrg
, pVarSrc
->value
, pVarSrc
->value_length
,
2971 paProps
[iProp
].enmType
== kPropAccumulateL
/* append */);
2974 pszSrc
[cchSrcVar
] = ')';
2975 pszSrc
[cchSrcVar
+ 1] = '\0';
2976 append_string_to_variable(pVarTrg
, pszSrcRef
, 2 + cchSrcVar
+ 1,
2977 paProps
[iProp
].enmType
== kPropAccumulateL
/* append */);
2981 /* else: the target variable doesn't exist, create it. */
2987 continue; /* skip ahead if it already exists. */
2989 /* copy the variable if its short, otherwise reference it. */
2990 if (pVarSrc
->value_length
< BY_REF_LIMIT
)
2991 define_variable_vl_global(pszTrg
, pszTrgEnd
- pszTrg
,
2992 pVarSrc
->value
, pVarSrc
->value_length
,
2993 1 /* duplicate_value */,
2999 pszSrc
[cchSrcVar
] = ')';
3000 pszSrc
[cchSrcVar
+ 1] = '\0';
3001 define_variable_vl_global(pszTrg
, pszTrgEnd
- pszTrg
,
3002 pszSrcRef
, 2 + cchSrcVar
+ 1,
3003 1 /* duplicate_value */,
3013 } /* foreach prop */
3015 } /* foreach target */
3023 for (iKey
= 1; iKey
< cKeys
; iKey
++)
3024 free(aKeys
[iKey
].psz
);
3029 #endif /* KMK_HELPERS */