Changeset 544
- Timestamp:
- Sep 20, 2006, 6:05:00 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gmake/kbuild.c
r543 r544 123 123 } 124 124 pVar->recursive = 0; 125 return pVar; 125 126 } 126 127 … … 221 222 } 222 223 224 /** 225 * Gets the first defined property variable. 226 */ 227 static struct variable * 228 kbuild_first_prop(struct variable *pTarget, struct variable *pSource, 229 struct variable *pTool, struct variable *pType, 230 struct variable *pBldTrg, struct variable *pBldTrgArch, 231 const char *pszPropF1, const char *pszPropF2, const char *pszVarName) 232 { 233 struct variable *pVar; 234 struct variable PropF1, PropF2; 235 236 PropF1.value = (char *)pszPropF1; 237 PropF1.value_length = strlen(pszPropF1); 238 239 PropF2.value = (char *)pszPropF2; 240 PropF2.value_length = strlen(pszPropF2); 241 242 if ( (pVar = kbuild_lookup_variable_fmt("%_%_%%.%.%",pTarget, pSource, pType, &PropF2, pBldTrg, pBldTrgArch)) 243 || (pVar = kbuild_lookup_variable_fmt("%_%_%%.%", pTarget, pSource, pType, &PropF2, pBldTrg)) 244 || (pVar = kbuild_lookup_variable_fmt("%_%_%%", pTarget, pSource, pType, &PropF2)) 245 || (pVar = kbuild_lookup_variable_fmt("%_%_%.%.%", pTarget, pSource, &PropF2, pBldTrg, pBldTrgArch)) 246 || (pVar = kbuild_lookup_variable_fmt("%_%_%.%", pTarget, pSource, &PropF2, pBldTrg)) 247 || (pVar = kbuild_lookup_variable_fmt("%_%_%", pTarget, pSource, &PropF2)) 248 || (pVar = kbuild_lookup_variable_fmt("%_%%.%.%", pSource, pType, &PropF2, pBldTrg, pBldTrgArch)) 249 || (pVar = kbuild_lookup_variable_fmt("%_%%.%", pSource, pType, &PropF2, pBldTrg)) 250 || (pVar = kbuild_lookup_variable_fmt("%_%%", pSource, pType, &PropF2)) 251 || (pVar = kbuild_lookup_variable_fmt("%_%.%.%", pSource, &PropF2, pBldTrg, pBldTrgArch)) 252 || (pVar = kbuild_lookup_variable_fmt("%_%.%", pSource, &PropF2, pBldTrg)) 253 || (pVar = kbuild_lookup_variable_fmt("%_%", pSource, &PropF2)) 254 || (pVar = kbuild_lookup_variable_fmt("%_%%.%.%", pTarget, pType, &PropF2, pBldTrg, pBldTrgArch)) 255 || (pVar = kbuild_lookup_variable_fmt("%_%%.%", pTarget, pType, &PropF2, pBldTrg)) 256 || (pVar = kbuild_lookup_variable_fmt("%_%%", pTarget, pType, &PropF2)) 257 || (pVar = kbuild_lookup_variable_fmt("%_%.%.%", pTarget, &PropF2, pBldTrg, pBldTrgArch)) 258 || (pVar = kbuild_lookup_variable_fmt("%_%.%", pTarget, &PropF2, pBldTrg)) 259 || (pVar = kbuild_lookup_variable_fmt("%_%", pTarget, &PropF2)) 260 261 || (pTool && (pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%.%", pTool, pType, &PropF2, pBldTrg, pBldTrgArch))) 262 || (pTool && (pVar = kbuild_lookup_variable_fmt("TOOL_%_%%.%", pTool, pType, &PropF2, pBldTrg))) 263 || (pTool && (pVar = kbuild_lookup_variable_fmt("TOOL_%_%%", pTool, pType, &PropF2))) 264 || (pTool && (pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%.%", pTool, &PropF2, pBldTrg, pBldTrgArch))) 265 || (pTool && (pVar = kbuild_lookup_variable_fmt("TOOL_%_%.%", pTool, &PropF2, pBldTrg))) 266 || (pTool && (pVar = kbuild_lookup_variable_fmt("TOOL_%_%", pTool, &PropF2))) 267 268 || (pVar = kbuild_lookup_variable_fmt("%%.%.%", pType, &PropF1, pBldTrg, pBldTrgArch)) 269 || (pVar = kbuild_lookup_variable_fmt("%%.%", pType, &PropF1, pBldTrg)) 270 || (pVar = kbuild_lookup_variable_fmt("%%", pType, &PropF1)) 271 || (pVar = kbuild_lookup_variable_fmt("%.%.%", &PropF1, pBldTrg, pBldTrgArch)) 272 || (pVar = kbuild_lookup_variable_fmt("%.%", &PropF1, pBldTrg)) 273 || (pVar = kbuild_lookup_variable(pszPropF1)) 274 ) 275 { 276 /* strip it */ 277 char *psz = pVar->value; 278 char *pszEnd = psz + pVar->value_length; 279 while (isblank((unsigned char)*psz)) 280 psz++; 281 while (pszEnd > psz && isblank((unsigned char)pszEnd[-1])) 282 pszEnd--; 283 if (pszEnd > psz) 284 { 285 char chSaved = *pszEnd; 286 *pszEnd = '\0'; 287 pVar = define_variable_vl(pszVarName, strlen(pszVarName), psz, pszEnd - psz, 288 1 /* duplicate */, o_file, 0 /* !recursive */); 289 *pszEnd = chSaved; 290 if (pVar) 291 return pVar; 292 } 293 } 294 return NULL; 295 } 223 296 224 297 /* … … 253 326 struct variable *pBldTrg, struct variable *pBldTrgArch, const char *pszVarName) 254 327 { 255 struct variable *pVar; 256 if ( (pVar = kbuild_lookup_variable_fmt("%_%_%TOOL.%.%", pTarget, pSource, pType, pBldTrg, pBldTrgArch)) 257 || (pVar = kbuild_lookup_variable_fmt("%_%_%TOOL.%", pTarget, pSource, pType, pBldTrg)) 258 || (pVar = kbuild_lookup_variable_fmt("%_%_%TOOL", pTarget, pSource, pType)) 259 || (pVar = kbuild_lookup_variable_fmt("%_%_TOOL.%.%", pTarget, pSource, pBldTrg, pBldTrgArch)) 260 || (pVar = kbuild_lookup_variable_fmt("%_%_TOOL.%", pTarget, pSource, pBldTrg)) 261 || (pVar = kbuild_lookup_variable_fmt("%_%_TOOL", pTarget, pSource)) 262 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL.%.%", pSource, pType, pBldTrg, pBldTrgArch)) 263 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL.%", pSource, pType, pBldTrg)) 264 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL", pSource, pType)) 265 || (pVar = kbuild_lookup_variable_fmt("%_TOOL.%.%", pSource, pBldTrg, pBldTrgArch)) 266 || (pVar = kbuild_lookup_variable_fmt("%_TOOL.%", pSource, pBldTrg)) 267 || (pVar = kbuild_lookup_variable_fmt("%_TOOL", pSource)) 268 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL.%.%", pTarget, pType, pBldTrg, pBldTrgArch)) 269 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL.%", pTarget, pType, pBldTrg)) 270 || (pVar = kbuild_lookup_variable_fmt("%_%TOOL", pTarget, pType)) 271 || (pVar = kbuild_lookup_variable_fmt("%_TOOL.%.%", pTarget, pBldTrg, pBldTrgArch)) 272 || (pVar = kbuild_lookup_variable_fmt("%_TOOL.%", pTarget, pBldTrg)) 273 || (pVar = kbuild_lookup_variable_fmt("%_TOOL", pTarget)) 274 || (pVar = kbuild_lookup_variable_fmt("%TOOL.%.%", pType, pBldTrg, pBldTrgArch)) 275 || (pVar = kbuild_lookup_variable_fmt("%TOOL.%", pType, pBldTrg)) 276 || (pVar = kbuild_lookup_variable_fmt("%TOOL", pType)) 277 || (pVar = kbuild_lookup_variable_fmt("TOOL.%.%", pBldTrg, pBldTrgArch)) 278 || (pVar = kbuild_lookup_variable_fmt("TOOL.%", pBldTrg)) 279 || (pVar = kbuild_lookup_variable("TOOL")) 280 ) 281 { 282 /* strip it */ 283 char *psz = pVar->value; 284 char *pszEnd = psz + pVar->value_length; 285 while (isblank((unsigned char)*psz)) 286 psz++; 287 while (pszEnd > psz && isblank((unsigned char)pszEnd[-1])) 288 pszEnd--; 289 if (pszEnd > psz) 290 { 291 char chSaved = *pszEnd; 292 *pszEnd = '\0'; 293 pVar = define_variable_vl(pszVarName, strlen(pszVarName), psz, pszEnd - psz, 294 1 /* duplicate */, o_file, 0 /* !recursive */); 295 *pszEnd = chSaved; 296 if (pVar) 297 return pVar; 298 } 299 } 300 301 fatal(NILF, _("no tool for source `%s' in target `%s'!"), pSource->value, pTarget->value); 302 return NULL; 328 struct variable *pVar = kbuild_first_prop(pTarget, pSource, NULL, pType, pBldTrg, pBldTrgArch, 329 "TOOL", "TOOL", pszVarName); 330 if (!pVar) 331 fatal(NILF, _("no tool for source `%s' in target `%s'!"), pSource->value, pTarget->value); 332 return pVar; 303 333 } 304 334 … … 319 349 } 320 350 321 /* 322 ## Figure out where to put object files. 323 # @param $1 source file 324 # @param $2 normalized main target 325 # @remark There are two major hacks here: 326 # 1. Source files in the output directory are translated into a gen/ subdir. 327 # 2. Catch anyone specifying $(PATH_SUB_CURRENT)/sourcefile.c. 328 _OBJECT_BASE = $(PATH_TARGET)/$(2)/$(call no-root-slash,$(call no-drive,$(basename \ 329 $(patsubst $(PATH_ROOT)/%,%,$(patsubst $(PATH_SUB_CURRENT)/%,%,$(patsubst $(PATH_TARGET)/$(2)/%,gen/%,$(1))))))) 330 */ 331 static struct variable * 332 kbuild_get_object_base(struct variable *pTarget, struct variable *pSource, const char *pszVarName) 333 { 334 struct variable *pPathTarget = kbuild_get_variable("PATH_TARGET"); 335 struct variable *pPathRoot = kbuild_get_variable("PATH_ROOT"); 336 struct variable *pPathSubCur = kbuild_get_variable("PATH_SUB_CURRENT"); 337 const char *pszSrcPrefix = NULL; 338 const char *pszSrcEnd; 339 char *pszSrc; 340 char *pszResult; 341 char *psz; 342 size_t cch; 343 344 /* 345 * Strip the source filename of any uncessary leading path and root specs. 346 */ 347 /* */ 348 if ( pSource->value_length > pPathTarget->value_length 349 && !strncmp(pSource->value, pPathTarget->value, pPathTarget->value_length)) 350 { 351 pszSrc = pSource->value + pPathTarget->value_length; 352 pszSrcPrefix = "gen/"; 353 } 354 else if ( pSource->value_length > pPathRoot->value_length 355 && !strncmp(pSource->value, pPathRoot->value, pPathRoot->value_length)) 356 { 357 pszSrc = pSource->value + pPathRoot->value_length; 358 if ( *pszSrc == '/' 359 && !strncmp(pszSrc, pPathSubCur->value, pPathSubCur->value_length)) 360 pszSrc += 1 + pPathSubCur->value_length; 361 } 362 else 363 pszSrc = pSource->value; 364 365 /* skip root specification */ 366 #ifdef HAVE_DOS_PATHS 367 if (isalpha(pszSrc[0]) && pszSrc[1] == ':') 368 pszSrc += 2; 369 #endif 370 while (*pszSrc == '/' 371 #ifdef HAVE_DOS_PATHS 372 || *pszSrc == '\\' 373 #endif 374 ) 375 pszSrc++; 376 377 /* drop the source extension. */ 378 pszSrcEnd = pSource->value + pSource->value_length; 379 for (;;) 380 { 381 pszSrcEnd--; 382 if ( pszSrcEnd <= pszSrc 383 || *pszSrcEnd == '/' 384 #ifdef HAVE_DOS_PATHS 385 || *pszSrcEnd == '\\' 386 || *pszSrcEnd == ':' 387 #endif 388 ) 389 { 390 pszSrcEnd = pSource->value + pSource->value_length; 391 break; 392 } 393 if (*pszSrcEnd == '.') 394 break; 395 } 396 397 /* 398 * Assemble the string on the stack and define the objbase variable 399 * which we then return. 400 */ 401 cch = pPathTarget->value_length 402 + 1 /* slash */ 403 + pTarget->value_length 404 + 1 /* slash */ 405 + pszSrcEnd - pszSrc 406 + 1; 407 psz = pszResult = xmalloc(cch); 408 409 memcpy(psz, pPathTarget->value, pPathTarget->value_length); psz += pPathTarget->value_length; 410 *psz++ = '/'; 411 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length; 412 *psz++ = '/'; 413 memcpy(psz, pszSrc, pszSrcEnd - pszSrc); psz += pszSrcEnd - pszSrc; 414 *psz = '\0'; 415 416 /* 417 * Define the variable in the current set and return it. 418 */ 419 return define_variable_vl(pszVarName, strlen(pszVarName), pszResult, cch - 1, 420 0 /* use pszResult */, o_file, 0 /* !recursive */); 421 } 422 423 /* Implements _OBJECT_BASE. */ 424 char * 425 func_kbuild_object_base(char *o, char **argv, const char *pszFuncName) 426 { 427 struct variable *pVar = kbuild_get_object_base(kbuild_lookup_variable("target"), 428 kbuild_lookup_variable("source"), 429 argv[0]); 430 if (pVar) 431 o = variable_buffer_output(o, pVar->value, pVar->value_length); 432 return o; 433 434 } 435 436 437 /* 351 /* This has been extended a bit, it's now identical to _SOURCE_TOOL. 438 352 $(firstword \ 439 353 $($(target)_$(source)_OBJSUFF.$(bld_trg).$(bld_trg_arch))\ … … 452 366 */ 453 367 static struct variable * 454 kbuild_get_object_suffix(struct variable *pTarget, struct variable *pSource, 455 struct variable *pBldTrg, struct variable *pBldTrgArch, 456 const char *pszVarName) 457 { 458 /** @todo ignore variables without content. Can generalize this and join with the tool getter. */ 459 struct variable *pVar; 460 if ( (pVar = kbuild_lookup_variable_fmt("%_%_OBJSUFF.%.%", pTarget, pSource, pBldTrg, pBldTrgArch)) 461 || (pVar = kbuild_lookup_variable_fmt("%_%_OBJSUFF.%", pTarget, pSource, pBldTrg)) 462 || (pVar = kbuild_lookup_variable_fmt("%_%_OBJSUFF", pTarget, pSource)) 463 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF.%.%", pSource, pBldTrg, pBldTrgArch)) 464 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF.%", pSource, pBldTrg)) 465 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF", pSource)) 466 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF.%.%", pTarget, pBldTrg, pBldTrgArch)) 467 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF.%", pTarget, pBldTrg)) 468 || (pVar = kbuild_lookup_variable_fmt("%_OBJSUFF", pTarget)) 469 || (pVar = kbuild_lookup_variable_fmt("OBJSUFF.%.%", pBldTrg, pBldTrgArch)) 470 || (pVar = kbuild_lookup_variable_fmt("OBJSUFF.%", pBldTrg)) 471 || (pVar = kbuild_lookup_variable("SUFF_OBJ")) 472 ) 473 { 474 /* strip it */ 475 char *psz = pVar->value; 476 char *pszEnd = psz + pVar->value_length; 477 while (isblank((unsigned char)*psz)) 478 psz++; 479 while (pszEnd > psz && isblank((unsigned char)pszEnd[-1])) 480 pszEnd--; 481 if (pszEnd > psz) 482 { 483 char chSaved = *pszEnd; 484 *pszEnd = '\0'; 485 pVar = define_variable_vl(pszVarName, strlen(pszVarName), psz, pszEnd - psz, 486 1 /* duplicate */, o_file, 0 /* !recursive */); 487 *pszEnd = chSaved; 488 if (pVar) 489 return pVar; 490 } 491 } 492 493 fatal(NILF, _("no tool for source `%s' in target `%s'!"), pSource->value, pTarget->value); 494 return NULL; 368 kbuild_get_object_suffix(struct variable *pTarget, struct variable *pSource, 369 struct variable *pTool, struct variable *pType, 370 struct variable *pBldTrg, struct variable *pBldTrgArch, const char *pszVarName) 371 { 372 struct variable *pVar = kbuild_first_prop(pTarget, pSource, pTool, pType, pBldTrg, pBldTrgArch, 373 "SUFF_OBJ", "OBJSUFF", pszVarName); 374 if (!pVar) 375 fatal(NILF, _("no OBJSUFF attribute or SUFF_OBJ default for source `%s' in target `%s'!"), pSource->value, pTarget->value); 376 return pVar; 495 377 } 496 378 … … 501 383 struct variable *pVar = kbuild_get_object_suffix(kbuild_get_variable("target"), 502 384 kbuild_get_variable("source"), 385 kbuild_get_variable("tool"), 386 kbuild_get_variable("type"), 503 387 kbuild_get_variable("bld_trg"), 504 388 kbuild_get_variable("bld_trg_arch"), … … 511 395 512 396 397 /* 398 ## Figure out where to put object files. 399 # @param $1 source file 400 # @param $2 normalized main target 401 # @remark There are two major hacks here: 402 # 1. Source files in the output directory are translated into a gen/ subdir. 403 # 2. Catch anyone specifying $(PATH_SUB_CURRENT)/sourcefile.c. 404 _OBJECT_BASE = $(PATH_TARGET)/$(2)/$(call no-root-slash,$(call no-drive,$(basename \ 405 $(patsubst $(PATH_ROOT)/%,%,$(patsubst $(PATH_SUB_CURRENT)/%,%,$(patsubst $(PATH_TARGET)/$(2)/%,gen/%,$(1))))))) 406 */ 407 static struct variable * 408 kbuild_get_object_base(struct variable *pTarget, struct variable *pSource, const char *pszVarName) 409 { 410 struct variable *pPathTarget = kbuild_get_variable("PATH_TARGET"); 411 struct variable *pPathRoot = kbuild_get_variable("PATH_ROOT"); 412 struct variable *pPathSubCur = kbuild_get_variable("PATH_SUB_CURRENT"); 413 const char *pszSrcPrefix = NULL; 414 const char *pszSrcEnd; 415 char *pszSrc; 416 char *pszResult; 417 char *psz; 418 size_t cch; 419 420 /* 421 * Strip the source filename of any uncessary leading path and root specs. 422 */ 423 /* */ 424 if ( pSource->value_length > pPathTarget->value_length 425 && !strncmp(pSource->value, pPathTarget->value, pPathTarget->value_length)) 426 { 427 pszSrc = pSource->value + pPathTarget->value_length; 428 pszSrcPrefix = "gen/"; 429 } 430 else if ( pSource->value_length > pPathRoot->value_length 431 && !strncmp(pSource->value, pPathRoot->value, pPathRoot->value_length)) 432 { 433 pszSrc = pSource->value + pPathRoot->value_length; 434 if ( *pszSrc == '/' 435 && !strncmp(pszSrc, pPathSubCur->value, pPathSubCur->value_length)) 436 pszSrc += 1 + pPathSubCur->value_length; 437 } 438 else 439 pszSrc = pSource->value; 440 441 /* skip root specification */ 442 #ifdef HAVE_DOS_PATHS 443 if (isalpha(pszSrc[0]) && pszSrc[1] == ':') 444 pszSrc += 2; 445 #endif 446 while (*pszSrc == '/' 447 #ifdef HAVE_DOS_PATHS 448 || *pszSrc == '\\' 449 #endif 450 ) 451 pszSrc++; 452 453 /* drop the source extension. */ 454 pszSrcEnd = pSource->value + pSource->value_length; 455 for (;;) 456 { 457 pszSrcEnd--; 458 if ( pszSrcEnd <= pszSrc 459 || *pszSrcEnd == '/' 460 #ifdef HAVE_DOS_PATHS 461 || *pszSrcEnd == '\\' 462 || *pszSrcEnd == ':' 463 #endif 464 ) 465 { 466 pszSrcEnd = pSource->value + pSource->value_length; 467 break; 468 } 469 if (*pszSrcEnd == '.') 470 break; 471 } 472 473 /* 474 * Assemble the string on the stack and define the objbase variable 475 * which we then return. 476 */ 477 cch = pPathTarget->value_length 478 + 1 /* slash */ 479 + pTarget->value_length 480 + 1 /* slash */ 481 + pszSrcEnd - pszSrc 482 + 1; 483 psz = pszResult = xmalloc(cch); 484 485 memcpy(psz, pPathTarget->value, pPathTarget->value_length); psz += pPathTarget->value_length; 486 *psz++ = '/'; 487 memcpy(psz, pTarget->value, pTarget->value_length); psz += pTarget->value_length; 488 *psz++ = '/'; 489 memcpy(psz, pszSrc, pszSrcEnd - pszSrc); psz += pszSrcEnd - pszSrc; 490 *psz = '\0'; 491 492 /* 493 * Define the variable in the current set and return it. 494 */ 495 return define_variable_vl(pszVarName, strlen(pszVarName), pszResult, cch - 1, 496 0 /* use pszResult */, o_file, 0 /* !recursive */); 497 } 498 499 /* Implements _OBJECT_BASE. */ 500 char * 501 func_kbuild_object_base(char *o, char **argv, const char *pszFuncName) 502 { 503 struct variable *pVar = kbuild_get_object_base(kbuild_lookup_variable("target"), 504 kbuild_lookup_variable("source"), 505 argv[0]); 506 if (pVar) 507 o = variable_buffer_output(o, pVar->value, pVar->value_length); 508 return o; 509 510 } 513 511 514 512 … … 1156 1154 struct variable *pTool = kbuild_get_source_tool(pTarget, pSource, pType, pBldTrg, pBldTrgArch, "tool"); 1157 1155 struct variable *pOutBase = kbuild_get_object_base(pTarget, pSource, "outbase"); 1158 struct variable *pObjSuff = kbuild_get_object_suffix(pTarget, pSource, p BldTrg, pBldTrgArch, "objsuff");1156 struct variable *pObjSuff = kbuild_get_object_suffix(pTarget, pSource, pTool, pType, pBldTrg, pBldTrgArch, "objsuff"); 1159 1157 struct variable *pDefs, *pIncs, *pFlags, *pDeps, *pDirDep, *pDep, *pVar, *pOutput; 1160 1158 struct variable *pObj = kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(pTarget, pSource, pOutBase, pObjSuff, "obj", &pDep, &pDirDep);
Note:
See TracChangeset
for help on using the changeset viewer.