- Timestamp:
- Jun 5, 2007 8:31:14 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kObjCache/kObjCache.c
r1036 r1038 41 41 #ifndef PATH_MAX 42 42 # define PATH_MAX _MAX_PATH /* windows */ 43 #endif 43 #endif 44 44 #if defined(__OS2__) || defined(__WIN__) 45 45 # include <process.h> … … 47 47 # ifdef __OS2__ 48 48 # include <unistd.h> 49 # endif 49 # endif 50 50 #else 51 51 # include <unistd.h> … … 54 54 # define O_BINARY 0 55 55 # endif 56 #endif 56 #endif 57 57 #include "crc32.h" 58 58 #include "md5.h" … … 67 67 #else 68 68 # define PATH_SLASH '/' 69 #endif 69 #endif 70 70 #if defined(__OS2__) || defined(__WIN__) 71 71 # define IS_SLASH(ch) ((ch) == '/' || (ch) == '\\') … … 74 74 # define IS_SLASH(ch) ((ch) == '/') 75 75 # define IS_SLASH_DRV(ch) ((ch) == '/') 76 #endif 76 #endif 77 77 /** Use pipe instead of temp files when possible (speed). */ 78 78 #define USE_PIPE 1 … … 84 84 *******************************************************************************/ 85 85 /** A checksum list entry. 86 * We keep a list checksums (of precompiler output) that matches, The planned 87 * matching algorithm doesn't require the precompiler output to be indentical, 86 * We keep a list checksums (of precompiler output) that matches, The planned 87 * matching algorithm doesn't require the precompiler output to be indentical, 88 88 * only to produce the same object files. 89 89 */ … … 111 111 /** Set if the object needs to be (re)compiled. */ 112 112 unsigned fNeedCompiling; 113 /** Whether the precompiler runs in piped mode. If clear it's file 114 * mode (it could be redirected stdout, but that's essentially the 113 /** Whether the precompiler runs in piped mode. If clear it's file 114 * mode (it could be redirected stdout, but that's essentially the 115 115 * same from our point of view). */ 116 116 unsigned fPiped; … … 172 172 173 173 /** 174 * Compares two check sum entries. 175 * 176 * @returns 1 if equal, 0 if not equal. 177 * 174 * Compares two check sum entries. 175 * 176 * @returns 1 if equal, 0 if not equal. 177 * 178 178 * @param pSum1 The first checksum. 179 179 * @param pSum2 The second checksum. … … 195 195 /** 196 196 * Print a fatal error message and exit with rc=1. 197 * 197 * 198 198 * @param pEntry The cache entry. 199 199 * @param pszFormat The message to print. … … 215 215 /** 216 216 * Print a verbose message if verbosisty is enabled. 217 * 217 * 218 218 * @param pEntry The cache entry. 219 219 * @param pszFormat The message to print. … … 225 225 { 226 226 va_list va; 227 227 228 228 fprintf(stdout, "kObjCache %s - info: ", pEntry->pszName); 229 229 va_start(va, pszFormat); … … 236 236 /** 237 237 * Creates a cache entry for the given cache file name. 238 * 238 * 239 239 * @returns Pointer to a cache entry. 240 240 * @param pszFilename The cache file name. … … 265 265 #if 0 /* don't bother. */ 266 266 /** 267 * Destroys the cache entry freeing up all it's resources. 268 * 267 * Destroys the cache entry freeing up all it's resources. 268 * 269 269 * @param pEntry The entry to free. 270 270 */ … … 287 287 /** 288 288 * Reads and parses the cache file. 289 * 289 * 290 290 * @param pEntry The entry to read it into. 291 291 */ … … 299 299 kObjCacheVerbose(pEntry, "reading cache file...\n"); 300 300 301 /* 301 /* 302 302 * Check the magic. 303 303 */ … … 404 404 if (fBad) 405 405 break; 406 406 407 407 if (fFirstSum) 408 408 { … … 419 419 } 420 420 else 421 { 421 { 422 422 fBad = 1; 423 423 break; … … 457 457 /** 458 458 * Writes the cache file. 459 * 459 * 460 460 * @param pEntry The entry to write. 461 461 */ … … 469 469 pFile = FOpenFileInDir(pEntry->pszName, pEntry->pszDir, "wb"); 470 470 if (!pFile) 471 kObjCacheFatal(pEntry, "Failed to open '%s' in '%s': %s\n", 471 kObjCacheFatal(pEntry, "Failed to open '%s' in '%s': %s\n", 472 472 pEntry->pszName, pEntry->pszDir, strerror(errno)); 473 473 … … 485 485 pSum; 486 486 pSum = pSum->pNext) 487 fprintf(pFile, "sum=%#x:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", 487 fprintf(pFile, "sum=%#x:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", 488 488 pSum->crc32, 489 489 pSum->md5[0], pSum->md5[1], pSum->md5[2], pSum->md5[3], … … 491 491 pSum->md5[8], pSum->md5[9], pSum->md5[10], pSum->md5[11], 492 492 pSum->md5[12], pSum->md5[13], pSum->md5[14], pSum->md5[15]); 493 493 494 494 if ( fflush(pFile) < 0 495 495 || ferror(pFile)) … … 498 498 fclose(pFile); 499 499 UnlinkFileInDir(pEntry->pszName, pEntry->pszDir); 500 kObjCacheFatal(pEntry, "Stream error occured while writing '%s' in '%s': %d (?)\n", 500 kObjCacheFatal(pEntry, "Stream error occured while writing '%s' in '%s': %d (?)\n", 501 501 pEntry->pszName, pEntry->pszDir, strerror(iErr)); 502 502 } … … 508 508 * Spawns a child in a synchronous fashion. 509 509 * Terminating on failure. 510 * 510 * 511 511 * @param papszArgv Argument vector. The cArgv element is NULL. 512 512 * @param cArgv The number of arguments in the vector. … … 524 524 fdReDir = open(pszStdOut, O_CREAT | O_TRUNC | O_WRONLY, 0777); 525 525 if (fdReDir < 0) 526 kObjCacheFatal(pEntry, "%s - failed to create stdout redirection file '%s': %s\n", 526 kObjCacheFatal(pEntry, "%s - failed to create stdout redirection file '%s': %s\n", 527 527 pszMsg, pszStdOut, strerror(errno)); 528 528 … … 561 561 fdReDir = open(pszStdOut, O_CREAT | O_TRUNC | O_WRONLY, 0777); 562 562 if (fdReDir < 0) 563 kObjCacheFatal(pEntry, "%s - failed to create stdout redirection file '%s': %s\n", 563 kObjCacheFatal(pEntry, "%s - failed to create stdout redirection file '%s': %s\n", 564 564 pszMsg, pszStdOut, strerror(errno)); 565 565 if (fdReDir != 1) … … 572 572 573 573 execvp(papszArgv[0], (char **)papszArgv); 574 kObjCacheFatal(pEntry, "%s - execvp failed: %s\n", 574 kObjCacheFatal(pEntry, "%s - execvp failed: %s\n", 575 575 pszMsg, strerror(errno)); 576 576 } … … 582 582 pidWait = waitpid(pid, &iStatus, 0); 583 583 if (pidWait != pid) 584 kObjCacheFatal(pEntry, "%s - waitpid failed rc=%d: %s\n", 584 kObjCacheFatal(pEntry, "%s - waitpid failed rc=%d: %s\n", 585 585 pszMsg, pidWait, strerror(errno)); 586 586 if (!WIFEXITED(iStatus)) … … 597 597 * Spawns a child in a synchronous fashion. 598 598 * Terminating on failure. 599 * 599 * 600 600 * @param papszArgv Argument vector. The cArgv element is NULL. 601 601 * @param cArgv The number of arguments in the vector. … … 632 632 fcntl(fds[0], F_SETFD, FD_CLOEXEC); 633 633 fcntl(fdStdOut, F_SETFD, FD_CLOEXEC); 634 #endif 634 #endif 635 635 636 636 /* … … 648 648 { 649 649 execvp(papszArgv[0], (char **)papszArgv); 650 kObjCacheFatal(pEntry, "%s - execvp failed: %s\n", 650 kObjCacheFatal(pEntry, "%s - execvp failed: %s\n", 651 651 pszMsg, strerror(errno)); 652 652 } 653 653 if (pid == -1) 654 654 kObjCacheFatal(pEntry, "%s - fork() failed: %s\n", pszMsg, strerror(errno)); 655 #endif 655 #endif 656 656 657 657 /* … … 682 682 { 683 683 size_t off = psz - *ppszOutput; 684 assert(off == cbAlloc);685 684 cbLeft = 4*1024*1024; 686 685 cbAlloc += cbLeft; … … 688 687 psz = *ppszOutput + off; 689 688 } 690 } 689 } 691 690 close(fds[0]); 692 691 *pcchOutput = cbAlloc - cbLeft; … … 698 697 pidWait = _cwait(&iStatus, pid, _WAIT_CHILD); 699 698 if (pidWait == -1) 700 kObjCacheFatal(pEntry, "%s - waitpid failed: %s\n", 699 kObjCacheFatal(pEntry, "%s - waitpid failed: %s\n", 701 700 pszMsg, strerror(errno)); 702 701 if (iStatus) … … 707 706 pidWait = waitpid(pid, &iStatus, 0); 708 707 if (pidWait != pid) 709 kObjCacheFatal(pEntry, "%s - waitpid failed rc=%d: %s\n", 708 kObjCacheFatal(pEntry, "%s - waitpid failed rc=%d: %s\n", 710 709 pszMsg, pidWait, strerror(errno)); 711 710 if (!WIFEXITED(iStatus)) … … 721 720 /** 722 721 * Reads the (new) output of the precompiler. 723 * 722 * 724 723 * Not used when using pipes. 725 * 724 * 726 725 * @param pEntry The cache entry. cbNewCpp and pszNewCppMapping will be updated. 727 726 */ … … 730 729 pEntry->pszNewCppMapping = ReadFileInDir(pEntry->pszNewCppName, pEntry->pszDir, &pEntry->cbNewCpp); 731 730 if (!pEntry->pszNewCppMapping) 732 kObjCacheFatal(pEntry, "failed to open/read '%s' in '%s': %s\n", 731 kObjCacheFatal(pEntry, "failed to open/read '%s' in '%s': %s\n", 733 732 pEntry->pszNewCppName, pEntry->pszDir, strerror(errno)); 734 733 kObjCacheVerbose(pEntry, "precompiled file is %lu bytes long\n", (unsigned long)pEntry->cbNewCpp); … … 737 736 738 737 /** 739 * Worker for kObjCachePreCompile and calculates the checksum of 738 * Worker for kObjCachePreCompile and calculates the checksum of 740 739 * the precompiler output. 741 * 740 * 742 741 * @param pEntry The cache entry. NewSum will be updated. 743 742 */ … … 763 762 /** 764 763 * Run the precompiler and calculate the checksum of the output. 765 * 764 * 766 765 * @param pEntry The cache entry. 767 766 * @param papszArgvPreComp The argument vector for executing precompiler. The cArgvPreComp'th argument must be NULL. … … 779 778 pEntry->fPiped = 1; 780 779 else 781 #endif 780 #endif 782 781 pEntry->fPiped = 0; 783 782 … … 788 787 * If we're using the pipe strategy, we will not do any renaming. 789 788 */ 790 if ( pEntry->pszOldCppName 789 if ( pEntry->pszOldCppName 791 790 && !pEntry->fPiped 792 791 && DoesFileInDirExist(pEntry->pszOldCppName, pEntry->pszDir)) … … 800 799 UnlinkFileInDir(psz, pEntry->pszDir); 801 800 if (RenameFileInDir(pEntry->pszOldCppName, psz, pEntry->pszDir)) 802 kObjCacheFatal(pEntry, "failed to rename '%s' -> '%s' in '%s': %s\n", 801 kObjCacheFatal(pEntry, "failed to rename '%s' -> '%s' in '%s': %s\n", 803 802 pEntry->pszOldCppName, psz, pEntry->pszDir, strerror(errno)); 804 803 free(pEntry->pszOldCppName); … … 815 814 kObjCacheSpawnPipe(pEntry, papszArgvPreComp, cArgvPreComp, "precompile", &pEntry->pszNewCppMapping, &pEntry->cbNewCpp); 816 815 else 817 #endif 816 #endif 818 817 { 819 818 if (fRedirStdOut) … … 829 828 /** 830 829 * Check whether the string is a '#line' statement. 831 * 830 * 832 831 * @returns 1 if it is, 0 if it isn't. 833 * @param psz The line to examin. 832 * @param psz The line to examin. 834 833 * @parma piLine Where to store the line number. 835 834 * @parma ppszFile Where to store the start of the filename. … … 855 854 return 0; 856 855 iLine = 0; 857 do 856 do 858 857 { 859 858 iLine *= 10; … … 878 877 /** 879 878 * Scan backwards for the previous #line statement. 880 * 879 * 881 880 * @returns The filename in the previous statement. 882 881 * @param pszStart Where to start. … … 913 912 914 913 /** 915 * Worker for kObjCacheCompareOldAndNewOutput() that compares the 914 * Worker for kObjCacheCompareOldAndNewOutput() that compares the 916 915 * precompiled output using a fast but not very good method. 917 * 918 * @returns 1 if matching, 0 if not matching. 916 * 917 * @returns 1 if matching, 0 if not matching. 919 918 * @param pEntry The entry containing the names of the files to compare. 920 919 * The entry is not updated in any way. … … 952 951 * Pinpoint the difference exactly and the try find the start 953 952 * of that line. Then skip forward until we find something to 954 * work on that isn't spaces, #line statements or closing curly 955 * braces. 953 * work on that isn't spaces, #line statements or closing curly 954 * braces. 956 955 * 957 * The closing curly braces are ignored because they are frequently 958 * found at the end of header files (__END_DECLS) and the worst 959 * thing that may happen if it isn't one of these braces we're 960 * ignoring is that the final line in a function block is a little 961 * bit off in the debug info. 956 * The closing curly braces are ignored because they are frequently 957 * found at the end of header files (__END_DECLS) and the worst 958 * thing that may happen if it isn't one of these braces we're 959 * ignoring is that the final line in a function block is a little 960 * bit off in the debug info. 962 961 * 963 * Since we might be skipping a few new empty headers, it is 964 * possible that we will omit this header from the dependencies 962 * Since we might be skipping a few new empty headers, it is 963 * possible that we will omit this header from the dependencies 965 964 * when using VCC. This might not be a problem, since it seems 966 965 * we'll have to use the precompiler output to generate the deps … … 987 986 /* locate the start of that line. */ 988 987 psz = psz1; 989 while ( psz > pEntry->pszNewCppMapping 988 while ( psz > pEntry->pszNewCppMapping 990 989 && psz[-1] != '\n') 991 990 psz--; … … 1133 1132 } 1134 1133 1135 return psz1 == pszEnd1 1134 return psz1 == pszEnd1 1136 1135 && psz2 == pszEnd2; 1137 1136 } … … 1139 1138 1140 1139 /** 1141 * Worker for kObjCacheCompileIfNeeded that compares the 1142 * precompiled output. 1143 * 1144 * @returns 1 if matching, 0 if not matching. 1140 * Worker for kObjCacheCompileIfNeeded that compares the 1141 * precompiled output. 1142 * 1143 * @returns 1 if matching, 0 if not matching. 1145 1144 * @param pEntry The entry containing the names of the files to compare. 1146 1145 * This will load the old cpp output (changing pszOldCppName and cbOldCpp). … … 1148 1147 static int kObjCacheCompareOldAndNewOutput(PKOBJCACHE pEntry) 1149 1148 { 1150 /** @todo do some quick but fancy comparing that determins whether code 1149 /** @todo do some quick but fancy comparing that determins whether code 1151 1150 * has actually changed or moved. We can ignore declarations and typedefs that 1152 * has just been moved up/down a bit. The typical case is adding a new error 1151 * has just been moved up/down a bit. The typical case is adding a new error 1153 1152 * #define that doesn't influence the current compile job. */ 1154 1153 … … 1159 1158 if (!pEntry->pszOldCppMapping) 1160 1159 { 1161 kObjCacheVerbose(pEntry, "failed to read old cpp file ('%s' in '%s'): %s\n", 1160 kObjCacheVerbose(pEntry, "failed to read old cpp file ('%s' in '%s'): %s\n", 1162 1161 pEntry->pszOldCppName, pEntry->pszDir, strerror(errno)); 1163 1162 return 0; … … 1174 1173 1175 1174 /** 1176 * Worker for kObjCacheCompileIfNeeded that does the actual (re)compilation. 1177 * 1178 * @returns 1 if matching, 0 if not matching. 1175 * Worker for kObjCacheCompileIfNeeded that does the actual (re)compilation. 1176 * 1177 * @returns 1 if matching, 0 if not matching. 1179 1178 * @param pEntry The cache entry. 1180 1179 * @param papszArgvCompile The argument vector for invoking the compiler. The cArgvCompile'th entry must be NULL. … … 1202 1201 FILE *pFile = FOpenFileInDir(pEntry->pszNewCppName, pEntry->pszDir, "wb"); 1203 1202 if (!pFile) 1204 kObjCacheFatal(pEntry, "failed to create file '%s' in '%s': %s\n", 1203 kObjCacheFatal(pEntry, "failed to create file '%s' in '%s': %s\n", 1205 1204 pEntry->pszNewCppName, pEntry->pszDir, strerror(errno)); 1206 1205 if (fwrite(pEntry->pszNewCppMapping, pEntry->cbNewCpp, 1, pFile) != 1) … … 1230 1229 /** 1231 1230 * Check if (re-)compilation is required and do it. 1232 * 1233 * @returns 1 if matching, 0 if not matching. 1231 * 1232 * @returns 1 if matching, 0 if not matching. 1234 1233 * @param pEntry The cache entry. 1235 1234 * @param papszArgvCompile The argument vector for invoking the compiler. The cArgvCompile'th entry must be NULL. … … 1257 1256 * TODO: Ignore irrelevant options here (like warning level). 1258 1257 */ 1259 if ( !pEntry->fNeedCompiling 1258 if ( !pEntry->fNeedCompiling 1260 1259 && pEntry->cArgvCompile != cArgvCompile) 1261 1260 { … … 1333 1332 1334 1333 /** 1335 * Gets the absolute path 1336 * 1334 * Gets the absolute path 1335 * 1337 1336 * @returns A new heap buffer containing the absolute path. 1338 1337 * @param pszPath The path to make absolute. (Readonly) … … 1354 1353 /** 1355 1354 * Utility function that finds the filename part in a path. 1356 * 1355 * 1357 1356 * @returns Pointer to the file name part (this may be ""). 1358 1357 * @param pszPath The path to parse. … … 1361 1360 { 1362 1361 const char *pszFilename = strchr(pszPath, '\0') - 1; 1363 while ( pszFilename > pszPath 1362 while ( pszFilename > pszPath 1364 1363 && !IS_SLASH_DRV(pszFilename[-1])) 1365 1364 pszFilename--; … … 1370 1369 /** 1371 1370 * Utility function that combines a filename and a directory into a path. 1372 * 1371 * 1373 1372 * @returns malloced buffer containing the result. 1374 1373 * @param pszName The file name. … … 1390 1389 /** 1391 1390 * Compares two path strings to see if they are identical. 1392 * 1393 * This doesn't do anything fancy, just the case ignoring and 1391 * 1392 * This doesn't do anything fancy, just the case ignoring and 1394 1393 * slash unification. 1395 * 1394 * 1396 1395 * @returns 1 if equal, 0 otherwise. 1397 1396 * @param pszPath1 The first path. … … 1424 1423 #else 1425 1424 return !strncmp(pszPath1, pszPath2, cch); 1426 #endif 1425 #endif 1427 1426 } 1428 1427 … … 1430 1429 /** 1431 1430 * Calculate how to get to pszPath from pszDir. 1432 * 1431 * 1433 1432 * @returns The relative path from pszDir to path pszPath. 1434 1433 * @param pszPath The path to the object. … … 1482 1481 /** 1483 1482 * Utility function that combines a filename and directory and passes it onto fopen. 1484 * 1483 * 1485 1484 * @returns fopen return value. 1486 1485 * @param pszName The file name. … … 1499 1498 /** 1500 1499 * Deletes a file in a directory. 1501 * 1500 * 1502 1501 * @returns whatever unlink returns. 1503 1502 * @param pszName The file name. … … 1515 1514 /** 1516 1515 * Renames a file in a directory. 1517 * 1516 * 1518 1517 * @returns whatever unlink returns. 1519 1518 * @param pszOldName The new file name. … … 1534 1533 /** 1535 1534 * Check if a (regular) file exists in a directory. 1536 * 1535 * 1537 1536 * @returns 1 if it exists and is a regular file, 0 if not. 1538 1537 * @param pszName The file name. … … 1551 1550 #else 1552 1551 #error "Port me" 1553 #endif 1552 #endif 1554 1553 } 1555 1554 … … 1557 1556 /** 1558 1557 * Reads into memory an entire file. 1559 * 1558 * 1560 1559 * @returns Pointer to the heap allocation containing the file. 1561 1560 * On failure NULL and errno is returned. … … 1632 1631 /** 1633 1632 * Prints a syntax error and returns the appropriate exit code 1634 * 1633 * 1635 1634 * @returns approriate exit code. 1636 1635 * @param pszFormat The syntax error message. … … 1780 1779 1781 1780 /** @page kObjCache Benchmarks. 1782 * 1781 * 1783 1782 * 2007-06-02 - 21-23:00: 1784 1783 * Mac OS X debug -j 3 clobber build (rm -Rf out/darwin.x86/debug ; sync ; svn diff ; sync ; sleep 1 ; time kmk -j 3): … … 1786 1785 * user 13m13.291s 1787 1786 * sys 2m58.193s 1788 * 1787 * 1789 1788 * Mac OS X debug -j 3 depend build (touch include/iprt/err.h ; sync ; svn diff ; sync ; sleep 1 ; time kmk -j 3): 1790 * real 3m55.275s 1789 * real 3m55.275s 1791 1790 * user 4m11.852s 1792 1791 * sys 0m54.931s … … 1796 1795 * user 14m27.736s 1797 1796 * sys 3m39.512s 1798 * 1797 * 1799 1798 * Mac OS X debug -j 3 cached depend build (touch include/iprt/err.h ; sync ; svn diff ; sync ; sleep 1 ; time kmk -j 3 USE_KOBJCACHE=1): 1800 1799 * real 1m17.445s 1801 1800 * user 1m13.410s 1802 1801 * sys 0m22.789s 1803 * 1802 * 1804 1803 * Mac OS X debug -j3 cached depend build (touch include/iprt/cdefs.h ; sync ; svn diff ; sync ; sleep 1 ; time kmk -j 3 USE_KOBJCACHE=1): 1805 1804 * real 1m29.315s 1806 1805 * user 1m31.391s 1807 1806 * sys 0m32.748s 1808 * 1809 */ 1807 * 1808 */
Note:
See TracChangeset
for help on using the changeset viewer.