VirtualBox

Changeset 2720 in kBuild


Ignore:
Timestamp:
Jan 1, 2014 10:59:50 PM (11 years ago)
Author:
bird
Message:

kBuild objects: Implemented the special variable accessor [@super] and [@self].

Location:
trunk/src/kmk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kbuild-object.c

    r2719 r2720  
    11/* $Id$ */
    22/** @file
    3  * kBuild specific make functionality related to read.c.
     3 * kBuild objects.
    44 */
    55
    66/*
    7  * Copyright (c) 2011-2013 knut st. osmundsen <[email protected]>
     7 * Copyright (c) 2011-2014 knut st. osmundsen <[email protected]>
    88 *
    99 * This file is part of kBuild.
     
    125125
    126126/*******************************************************************************
    127 *   Header Files                                                               *
     127*   Global Variables                                                           *
    128128*******************************************************************************/
    129129/** Linked list (LIFO) of kBuild defines.
     
    147147*******************************************************************************/
    148148static struct kbuild_object *
    149 eval_kbuild_resolve_parent(struct kbuild_object *pObj, int fQuiet);
     149resolve_kbuild_object_parent(struct kbuild_object *pObj, int fQuiet);
     150static struct kbuild_object *
     151get_kbuild_object_parent(struct kbuild_object *pObj, enum kBuildSeverity enmSeverity);
    150152
    151153static struct kbuild_object *
     
    204206
    205207
     208static const char *
     209eval_kbuild_type_to_string(enum kBuildType enmType)
     210{
     211    switch (enmType)
     212    {
     213        case kBuildType_Target:      return "target";
     214        case kBuildType_Template:    return "template";
     215        case kBuildType_Tool:        return "tool";
     216        case kBuildType_Sdk:         return "sdk";
     217        case kBuildType_Unit:        return "unit";
     218        default:
     219        case kBuildType_Invalid:     return "invalid";
     220    }
     221}
     222
     223/**
     224 * Gets the length of the string representation of the given type.
     225 *
     226 * @returns The string length.
     227 * @param   enmType             The kBuild object type in question.
     228 */
     229static unsigned
     230eval_kbuild_type_to_string_length(enum kBuildType enmType)
     231{
     232    switch (enmType)
     233    {
     234        case kBuildType_Target:      return sizeof("target") - 1;
     235        case kBuildType_Template:    return sizeof("template") - 1;
     236        case kBuildType_Tool:        return sizeof("tool") - 1;
     237        case kBuildType_Sdk:         return sizeof("sdk") - 1;
     238        case kBuildType_Unit:        return sizeof("unit") - 1;
     239        default:
     240        case kBuildType_Invalid:     return sizeof("invalid") - 1;
     241    }
     242}
     243
     244/**
     245 * Converts a string into an kBuild object type.
     246 *
     247 * @returns The type on success, kBuildType_Invalid on failure.
     248 * @param   pchWord             The pchWord.  Not necessarily zero terminated.
     249 * @param   cchWord             The length of the word.
     250 */
     251static enum kBuildType
     252eval_kbuild_type_from_string(const char *pchWord, size_t cchWord)
     253{
     254    if (cchWord >= 3)
     255    {
     256        if (*pchWord == 't')
     257        {
     258            if (WORD_IS(pchWord, cchWord, "target"))
     259                return kBuildType_Target;
     260            if (WORD_IS(pchWord, cchWord, "template"))
     261                return kBuildType_Template;
     262            if (WORD_IS(pchWord, cchWord, "tool"))
     263                return kBuildType_Tool;
     264        }
     265        else
     266        {
     267            if (WORD_IS(pchWord, cchWord, "sdk"))
     268                return kBuildType_Sdk;
     269            if (WORD_IS(pchWord, cchWord, "unit"))
     270                return kBuildType_Unit;
     271        }
     272    }
     273
     274    return kBuildType_Invalid;
     275}
     276
     277
     278
    206279/**
    207280 * Helper function for caching variable name strings.
     
    263336}
    264337
     338static const char *
     339kbuild_replace_special_accessors(const char *pchValue, size_t *pcchValue, int *pfDuplicateValue,
     340                                 const struct floc *pFileLoc)
     341{
     342    size_t      cchValue    = *pcchValue;
     343    size_t      cbAllocated = *pfDuplicateValue ? 0 : cchValue + 1;
     344
     345    /*
     346     * Loop thru each potential special accessor occurance in the string.
     347     *
     348     * Unfortunately, we don't have a strnstr function in the C library, so
     349     * we'll using memchr and doing a few more rounds in this loop.
     350     */
     351    size_t  cchLeft  = cchValue;
     352    char   *pchLeft  = (char *)pchValue;
     353    for (;;)
     354    {
     355        int     fSuper;
     356        char   *pch = (char *)memchr(pchLeft, '$', cchLeft);
     357        if (!pch)
     358            break;
     359
     360        pch++;
     361        cchLeft -= pch - pchLeft;
     362        pchLeft  = pch;
     363
     364        /* [@self] is the shorter, quit if there isn't enough room for even it. */
     365        if (cchLeft < sizeof("([@self]") - 1)
     366            break;
     367
     368        /* We don't care how many dollars there are in front of a special accessor. */
     369        if (*pchLeft == '$')
     370        {
     371            do
     372            {
     373                cchLeft--;
     374                pchLeft++;
     375            } while (cchLeft >= sizeof("([@self]") - 1 && *pchLeft == '$');
     376            if (cchLeft < sizeof("([@self]") - 1)
     377                break;
     378        }
     379
     380        /* Is it a special accessor? */
     381        if (   pchLeft[2] != '@'
     382            || pchLeft[1] != '['
     383            || pchLeft[0] != '(')
     384            continue;
     385        pchLeft += 2;
     386        cchLeft -= 2;
     387        if (!memcmp(pchLeft, STRING_SIZE_TUPLE("@self]")))
     388            fSuper = 0;
     389        else if (   cchLeft >= sizeof("@super]")
     390                 && !memcmp(pchLeft, STRING_SIZE_TUPLE("@super]")))
     391            fSuper = 1;
     392        else
     393            continue;
     394
     395        /*
     396         * We've got something to replace. First figure what with and then
     397         * resize the value buffer.
     398         */
     399        if (g_pTopKbEvalData)
     400        {
     401            struct kbuild_object   *pObj       = g_pTopKbEvalData->pObj;
     402            size_t const            cchSpecial = fSuper ? sizeof("@super") - 1 : sizeof("@self") - 1;
     403            size_t                  cchName;
     404            size_t                  cchType;
     405            long                    cchDelta;
     406            const char             *pszName;
     407
     408            if (fSuper)
     409            {
     410                pObj = get_kbuild_object_parent(pObj, kBuildSeverity_Error);
     411                if (!pObj)
     412                    continue;
     413            }
     414            pszName = pObj->pszName;
     415            cchName = pObj->cchName;
     416            cchType = eval_kbuild_type_to_string_length(pObj->enmType);
     417            cchDelta = cchType + 1 + cchName - cchSpecial;
     418
     419            if (cchValue + cchDelta >= cbAllocated)
     420            {
     421                size_t  offLeft = pchLeft - pchValue;
     422                char   *pszNewValue;
     423
     424                cbAllocated = cchValue + cchDelta + 1;
     425                if (cchValue < 1024)
     426                    cbAllocated = (cbAllocated + 31) & ~(size_t)31;
     427                else
     428                    cbAllocated = (cbAllocated + 255) & ~(size_t)255;
     429                pszNewValue = (char *)xmalloc(cbAllocated);
     430
     431                memcpy(pszNewValue, pchValue, offLeft);
     432                memcpy(pszNewValue + offLeft + cchSpecial + cchDelta,
     433                       pchLeft + cchSpecial,
     434                       cchLeft - cchSpecial + 1);
     435
     436                if (*pfDuplicateValue == 0)
     437                    free((char *)pchValue);
     438                else
     439                    *pfDuplicateValue = 0;
     440
     441                pchValue = pszNewValue;
     442                pchLeft  = pszNewValue + offLeft;
     443            }
     444            else
     445            {
     446                assert(*pfDuplicateValue == 0);
     447                memmove(pchLeft + cchSpecial + cchDelta,
     448                        pchLeft + cchSpecial,
     449                        cchLeft - cchSpecial + 1);
     450            }
     451
     452            cchLeft  += cchDelta;
     453            cchValue += cchDelta;
     454            *pcchValue = cchValue;
     455
     456            memcpy(pchLeft, eval_kbuild_type_to_string(pObj->enmType), cchType);
     457            pchLeft += cchType;
     458            *pchLeft++ = '@';
     459            memcpy(pchLeft, pszName, cchName);
     460            pchLeft += cchName;
     461            cchLeft -= cchType + 1 + cchName;
     462        }
     463        else
     464            error(pFileLoc, _("The '$([%.*s...' accessor can only be used in the context of a kBuild object"),
     465                  MAX(cchLeft, 20), pchLeft);
     466    }
     467
     468    return pchValue;
     469}
     470
    265471static struct variable *
    266472define_kbuild_object_variable_cached(struct kbuild_object *pObj, const char *pszName,
    267473                                     const char *pchValue, size_t cchValue,
    268474                                     int fDuplicateValue, enum variable_origin enmOrigin,
    269                                      int fRecursive, const struct floc *pFileLoc)
     475                                     int fRecursive, int fNoSpecialAccessors, const struct floc *pFileLoc)
    270476{
    271477    struct variable *pVar;
    272478    size_t cchName = strcache2_get_len(&variable_strcache, pszName);
    273479
     480    if (fRecursive && !fNoSpecialAccessors)
     481        pchValue = kbuild_replace_special_accessors(pchValue, &cchValue, &fDuplicateValue, pFileLoc);
    274482
    275483    pVar = define_variable_in_set(pszName, cchName,
     
    354562                  (int)cchVarNm, pchVarNm, (int)cchName, pchName);
    355563        return define_kbuild_object_variable_cached(pObj, strcache2_add(&variable_strcache, pchVarNm, cchVarNm),
    356                                                     pszValue, cchValue, fDuplicateValue, enmOrigin, fRecursive, pFileLoc);
     564                                                    pszValue, cchValue, fDuplicateValue, enmOrigin, fRecursive,
     565                                                    0 /*fNoSpecialAccessors*/, pFileLoc);
    357566    }
    358567
     
    393602
    394603    return define_kbuild_object_variable_cached(g_pTopKbEvalData->pObj, strcache2_add(&variable_strcache, pchName, cchName),
    395                                                 pszValue, cchValue, fDuplicateValue, enmOrigin, fRecursive, pFileLoc);
     604                                                pszValue, cchValue, fDuplicateValue, enmOrigin, fRecursive,
     605                                                0 /*fNoSpecialAccessors*/, pFileLoc);
    396606}
    397607
     
    463673        {
    464674            /* Append/prepend to existing variable. */
    465             return do_variable_definition_append(pFileLoc, pVar, pchValue, cchValue, fSimpleValue, enmOrigin, fAppend);
     675            int fDuplicateValue = 1;
     676            if (pVar->recursive && !fSimpleValue)
     677                pchValue = kbuild_replace_special_accessors(pchValue, &cchValue, &fDuplicateValue, pFileLoc);
     678
     679            pVar = do_variable_definition_append(pFileLoc, pVar, pchValue, cchValue, fSimpleValue, enmOrigin, fAppend);
     680
     681            if (fDuplicateValue == 0)
     682                free((char *)pchValue);
     683            return pVar;
    466684        }
    467685
     
    474692            for (;;)
    475693            {
    476                 pParent = eval_kbuild_resolve_parent(pParent, 0 /*fQuiet*/);
     694                pParent = resolve_kbuild_object_parent(pParent, 0 /*fQuiet*/);
    477695                if (!pParent)
    478696                    break;
     
    496714                        || memchr(pchValue, '$', cchValue) == NULL )
    497715                    {
     716                        int     fDuplicateValue = 1;
    498717                        size_t  cchNewValue;
    499718                        char   *pszNewValue;
     
    501720
    502721                        /* Just join up the two values. */
     722                        if (pVar->recursive && !fSimpleValue)
     723                            pchValue = kbuild_replace_special_accessors(pchValue, &cchValue, &fDuplicateValue, pFileLoc);
    503724                        if (pVar->value_length == 0)
    504725                        {
     
    535756
    536757                        /* Define the new variable in the child. */
    537                         return define_kbuild_object_variable_cached(pObj, VarKey.name,
     758                        pVar = define_kbuild_object_variable_cached(pObj, VarKey.name,
    538759                                                                    pszNewValue, cchNewValue, 0 /*fDuplicateValue*/,
    539                                                                     enmOrigin, pVar->recursive, pFileLoc);
    540 
     760                                                                    enmOrigin, pVar->recursive, 1 /*fNoSpecialAccessors*/,
     761                                                                    pFileLoc);
     762                        if (fDuplicateValue == 0)
     763                            free((char *)pchValue);
    541764                    }
    542765                    else
     
    546769                        pVar = define_kbuild_object_variable_cached(pObj, VarKey.name,
    547770                                                                    pVar->value, pVar->value_length, 1 /*fDuplicateValue*/,
    548                                                                     enmOrigin, pVar->recursive, pFileLoc);
     771                                                                    enmOrigin, pVar->recursive, 1 /*fNoSpecialAccessors*/,
     772                                                                    pFileLoc);
    549773                        append_expanded_string_to_variable(pVar, pchValue, cchValue, fAppend);
    550                         return pVar;
    551774                    }
     775                    return pVar;
    552776                }
    553777            }
     
    560784    return define_kbuild_object_variable_cached(pObj, VarKey.name,
    561785                                                pchValue, cchValue, 1 /*fDuplicateValue*/, enmOrigin,
    562                                                 1 /*fRecursive */, pFileLoc);
     786                                                1 /*fRecursive */, 0 /*fNoSpecialAccessors*/, pFileLoc);
    563787}
    564788
    565789/** @} */
    566 
    567 
    568 static const char *
    569 eval_kbuild_type_to_string(enum kBuildType enmType)
    570 {
    571     switch (enmType)
    572     {
    573         case kBuildType_Target:      return "target";
    574         case kBuildType_Template:    return "template";
    575         case kBuildType_Tool:        return "tool";
    576         case kBuildType_Sdk:         return "sdk";
    577         case kBuildType_Unit:        return "unit";
    578         default:
    579         case kBuildType_Invalid:     return "invalid";
    580     }
    581 }
    582 
    583 /**
    584  * Converts a string into an kBuild object type.
    585  *
    586  * @returns The type on success, kBuildType_Invalid on failure.
    587  * @param   pchWord             The pchWord.  Not necessarily zero terminated.
    588  * @param   cchWord             The length of the word.
    589  */
    590 static enum kBuildType
    591 eval_kbuild_type_from_string(const char *pchWord, size_t cchWord)
    592 {
    593     if (cchWord >= 3)
    594     {
    595         if (*pchWord == 't')
    596         {
    597             if (WORD_IS(pchWord, cchWord, "target"))
    598                 return kBuildType_Target;
    599             if (WORD_IS(pchWord, cchWord, "template"))
    600                 return kBuildType_Template;
    601             if (WORD_IS(pchWord, cchWord, "tool"))
    602                 return kBuildType_Tool;
    603         }
    604         else
    605         {
    606             if (WORD_IS(pchWord, cchWord, "sdk"))
    607                 return kBuildType_Sdk;
    608             if (WORD_IS(pchWord, cchWord, "unit"))
    609                 return kBuildType_Unit;
    610         }
    611     }
    612 
    613     return kBuildType_Invalid;
    614 }
    615790
    616791
     
    653828
    654829static struct kbuild_object *
    655 eval_kbuild_resolve_parent(struct kbuild_object *pObj, int fQuiet)
     830resolve_kbuild_object_parent(struct kbuild_object *pObj, int fQuiet)
    656831{
    657832    if (   !pObj->pParent
     
    685860}
    686861
     862/**
     863 * Get the parent of the given object, it is expected to have one.
     864 *
     865 * @returns Pointer to the parent. NULL if we survive failure.
     866 * @param   pObj                The kBuild object.
     867 * @param   enmSeverity         The severity of a missing parent.
     868 */
     869static struct kbuild_object *
     870get_kbuild_object_parent(struct kbuild_object *pObj, enum kBuildSeverity enmSeverity)
     871{
     872    struct kbuild_object *pParent = pObj->pParent;
     873    if (pParent)
     874        return pParent;
     875
     876    pParent = resolve_kbuild_object_parent(pObj, 1 /*fQuiet - complain below */);
     877    if (pParent)
     878        return pParent;
     879
     880    if (pObj->pszParent)
     881        kbuild_report_problem(enmSeverity, &pObj->FileLoc,
     882                              _("Could not local parent '%s' for kBuild object '%s'"),
     883                              pObj->pszParent, pObj->pszName);
     884    else
     885        kbuild_report_problem(enmSeverity, &pObj->FileLoc,
     886                              _("kBuild object '%s' has no parent ([@super])"),
     887                              pObj->pszName);
     888    return NULL;
     889}
     890
    687891static int
    688892eval_kbuild_define_xxxx(struct kbuild_eval_data **ppData, const struct floc *pFileLoc,
     
    789993
    790994            define_kbuild_object_variable_cached(pObj, g_pszVarNmTemplate, pszTemplate, cchTemplate,
    791                                                  0 /*fDuplicateValue*/, o_default, 0 /*fRecursive*/, pFileLoc),
    792 
    793             /* next token */
    794             psz = find_next_token_eos(&pszLine, pszEos, &cch);
     995                                                 0 /*fDuplicateValue*/, o_default, 0 /*fRecursive*/,
     996                                                 1 /*fNoSpecialAccessors*/, pFileLoc);
     997
    795998        }
    796999        else
    7971000            fatal(pFileLoc, _("Don't know what '%.*s' means"), (int)cch, psz);
     1001
     1002        /* next token */
     1003        psz = find_next_token_eos(&pszLine, pszEos, &cch);
    7981004    }
    7991005
     
    8011007     * Try resolve the parent.
    8021008     */
    803     eval_kbuild_resolve_parent(pObj, 1 /*fQuiet*/);
     1009    resolve_kbuild_object_parent(pObj, 1 /*fQuiet*/);
    8041010
    8051011    /*
     
    10181224                if (cchExpr > 0)
    10191225                {
    1020                     enum kBuildType enmType;
    1021 
    1022                     *pcchVarNm = cchExpr;
    1023                     *ppchVarNm = pchExpr;
    10241226
    10251227                    /*
    10261228                     * It's an kBuild define variable accessor, alright.
    10271229                     */
    1028                     enmType = eval_kbuild_type_from_string(pchType, cchType);
    1029                     if (penmType)
    1030                         *penmType = enmType;
    1031                     if (enmType != kBuildType_Invalid)
     1230                    *pcchVarNm = cchExpr;
     1231                    *ppchVarNm = pchExpr;
     1232
     1233                    /* Deal with known special accessors: [@self]VAR, [@super]VAR. */
     1234                    if (cchType == 0)
    10321235                    {
    1033                         struct kbuild_object *pObj = lookup_kbuild_object(enmType, pchObjName, cchObjName);
    1034                         if (pObj)
    1035                             return pObj;
    1036 
    1037                         /* failed. */
    1038                         kbuild_report_problem(enmSeverity, pFileLoc,
    1039                                               _("kBuild object '%s' not found in kBuild variable accessor '%.*s'"),
    1040                                               (int)cchObjName, pchObjName, (int)cchOrgExpr, pchOrgExpr);
     1236                        int fSuper;
     1237
     1238                        if (WORD_IS(pchObjName, cchObjName, "self"))
     1239                            fSuper = 0;
     1240                        else if (WORD_IS(pchObjName, cchObjName, "super"))
     1241                            fSuper = 1;
     1242                        else
     1243                        {
     1244                            kbuild_report_problem(MAX(enmSeverity, kBuildSeverity_Error), pFileLoc,
     1245                                                  _("Invalid special kBuild object accessor: '%.*s'"),
     1246                                                  (int)cchOrgExpr, pchOrgExpr);
     1247                            if (penmType)
     1248                                *penmType = kBuildType_Invalid;
     1249                            return NULL;
     1250                        }
     1251                        if (g_pTopKbEvalData)
     1252                        {
     1253                            struct kbuild_object *pObj = g_pTopKbEvalData->pObj;
     1254                            struct kbuild_object *pParent;
     1255
     1256                            if (penmType)
     1257                                *penmType = pObj->enmType;
     1258
     1259                            if (!fSuper)
     1260                                return pObj;
     1261
     1262                            pParent = get_kbuild_object_parent(pObj, MAX(enmSeverity, kBuildSeverity_Error));
     1263                            if (pParent)
     1264                                return pParent;
     1265                        }
     1266                        else
     1267                            kbuild_report_problem(MAX(enmSeverity, kBuildSeverity_Error), pFileLoc,
     1268                                                  _("The '%.*s' accessor can only be used in the context of a kBuild object"),
     1269                                                  (int)cchOrgExpr, pchOrgExpr);
     1270                        if (penmType)
     1271                            *penmType = kBuildType_Invalid;
    10411272                    }
    10421273                    else
    1043                         kbuild_report_problem(MAX(enmSeverity, kBuildSeverity_Error), pFileLoc,
    1044                                               _("Invalid type '%.*s' specified in kBuild variable accessor '%.*s'"),
    1045                                               (int)cchType, pchType, (int)cchOrgExpr, pchOrgExpr);
     1274                    {
     1275                        /* Genric accessor. Check the type and look up the object. */
     1276                        enum kBuildType enmType = eval_kbuild_type_from_string(pchType, cchType);
     1277                        if (penmType)
     1278                            *penmType = enmType;
     1279                        if (enmType != kBuildType_Invalid)
     1280                        {
     1281                            struct kbuild_object *pObj = lookup_kbuild_object(enmType, pchObjName, cchObjName);
     1282                            if (pObj)
     1283                                return pObj;
     1284
     1285                            /* failed. */
     1286                            kbuild_report_problem(enmSeverity, pFileLoc,
     1287                                                  _("kBuild object '%s' not found in kBuild variable accessor '%.*s'"),
     1288                                                  (int)cchObjName, pchObjName, (int)cchOrgExpr, pchOrgExpr);
     1289                        }
     1290                        else
     1291                            kbuild_report_problem(MAX(enmSeverity, kBuildSeverity_Error), pFileLoc,
     1292                                                  _("Invalid type '%.*s' specified in kBuild variable accessor '%.*s'"),
     1293                                                  (int)cchType, pchType, (int)cchOrgExpr, pchOrgExpr);
     1294                    }
    10461295                    return NULL;
    10471296                }
     
    11071356                    for (;;)
    11081357                    {
    1109                         pParent = eval_kbuild_resolve_parent(pParent, 0 /*fQuiet*/);
     1358                        pParent = resolve_kbuild_object_parent(pParent, 0 /*fQuiet*/);
    11101359                        if (!pParent)
    11111360                            break;
  • trunk/src/kmk/testcase-kBuild-define.kmk

    r2718 r2720  
    2626#DEPTH = ../..
    2727#include $(PATH_KBUILD)/header.kmk
     28
     29##
     30# Test if $($1) == $2 and raises an error if it isn't.
     31#
     32# @param   1   Something to apply '$' to.
     33# @param   2   The expected value.
     34TEST_EQ = $(if-expr "$($1)" == "$2",,$(error $1 is '$($1)' not '$2'))
    2835
    2936if 0
     
    97104$(if-expr "$(OutsideMod_OTHER)"          == "outside-value",,$(error OutsideMod_OTHER is '$(OutsideMod_OTHER)' not 'outside-value'))
    98105
     106# Test #4
     107kBuild-define-target SpecialBase
     108_SOURCES = file1.c file2.c
     109_DEFS.win.x86 = XXX YYY
     110_DEFS.win.amd64 = $(filter-out YYY,$([@self]_DEFS.win.x86))
     111# Unnecessary use of [@self].
     112[@self]_LIBS = MyLib
     113kBuild-endef-target
     114
     115kBuild-define-target SpecialChild extending SpecialBase
     116_SOURCES = file1-child.c $(filter-out file1.c,$([@super]_SOURCES))
     117# Rare use of [@super].
     118[@super]_SET_BY_CHILD = 42
     119kBuild-endef-target
     120
     121$(call TEST_EQ,[target@SpecialBase]_LIBS,MyLib)
     122$(call TEST_EQ,SpecialBase_LIBS,MyLib)
     123
     124$(call TEST_EQ,[target@SpecialBase]_SET_BY_CHILD,42)
     125$(call TEST_EQ,SpecialBase_SET_BY_CHILD,42)
     126$(call TEST_EQ,[target@SpecialChild]_SET_BY_CHILD,42)
     127#$(call TEST_EQ,SpecialChild_SET_BY_CHILD,42) ## @todo
     128
     129$(call TEST_EQ,[target@SpecialBase]_DEFS.win.x86,XXX YYY)
     130$(call TEST_EQ,[target@SpecialBase]_DEFS.win.amd64,XXX)
     131$(call TEST_EQ,SpecialBase_DEFS.win.amd64,XXX)
     132$(call TEST_EQ,[target@SpecialChild]_DEFS.win.x86,XXX YYY)
     133$(call TEST_EQ,[target@SpecialChild]_DEFS.win.amd64,XXX)
     134#$(call TEST_EQ,SpecialChild_DEFS.win.amd64,XXX) ## @todo
     135
     136$(call TEST_EQ,[target@SpecialChild]_SOURCES,file1-child.c file2.c)
     137$(call TEST_EQ,SpecialChild_SOURCES,file1-child.c file2.c)
     138
    99139all_recursive:
    100140        @kmk_echo "kBuild-define-xxxx works fine"
Note: See TracChangeset for help on using the changeset viewer.

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