Logo Search packages:      
Sourcecode: kbuild version File versions  Download package

int main ( int  argc,
char **  argv 
)

Main function.

Returns:
0 on success. -n count of failiures.
Parameters:
@param 
Returns:
Remarks:

Definition at line 3658 of file kObjCache.c.

References AppendArgs(), FindFilenameInPath(), g_cVerbosityLevel, kObjCacheCreate(), kObjCacheDestroy(), kObjCacheFindMatchingEntry(), kObjCacheInsertEntry(), kObjCacheIsNew(), kObjCacheLock(), kObjCacheRemoveEntry(), kObjCacheUnlock(), kOCEntryAbsPath(), kOCEntryCalcRecompile(), kOCEntryCompileIt(), kOCEntryCopy(), kOCEntryCreate(), kOCEntryDestroy(), kOCEntryNeedsCompiling(), kOCEntryPreCompile(), kOCEntryPreCompileAndCompile(), kOCEntryRead(), kOCEntrySetCompileArgv(), kOCEntrySetCompileObjName(), kOCEntrySetCppName(), kOCEntrySetPipedMode(), kOCEntrySetTarget(), kOCEntryWrite(), MakePathFromDirAndFile(), NULL, SyntaxError(), and usage().

{
    PKOBJCACHE pCache;
    PKOCENTRY pEntry;

    const char *pszCacheDir = getenv("KOBJCACHE_DIR");
    const char *pszCacheName = NULL;
    const char *pszCacheFile = NULL;
    const char *pszEntryFile = NULL;

    const char **papszArgvPreComp = NULL;
    unsigned cArgvPreComp = 0;
    const char *pszPreCompName = NULL;
    int fRedirPreCompStdOut = 0;

    const char **papszArgvCompile = NULL;
    unsigned cArgvCompile = 0;
    const char *pszObjName = NULL;
    int fRedirCompileStdIn = 0;

    const char *pszTarget = NULL;

    enum { kOC_Options, kOC_CppArgv, kOC_CcArgv, kOC_BothArgv } enmMode = kOC_Options;

    size_t cch;
    char *psz;
    int i;

    SetErrorPrefix("kObjCache");

    /*
     * Arguments passed in the environmnet?
     */
    psz = getenv("KOBJCACHE_OPTS");
    if (psz)
        AppendArgs(&argc, &argv, psz, "--kObjCache-options");

    /*
     * Parse the arguments.
     */
    if (argc <= 1)
        return usage(stderr);
    for (i = 1; i < argc; i++)
    {
        if (!strcmp(argv[i], "--kObjCache-cpp"))
        {
            enmMode = kOC_CppArgv;
            if (!pszPreCompName)
            {
                if (++i >= argc)
                    return SyntaxError("--kObjCache-cpp requires an object filename!\n");
                pszPreCompName = argv[i];
            }
        }
        else if (!strcmp(argv[i], "--kObjCache-cc"))
        {
            enmMode = kOC_CcArgv;
            if (!pszObjName)
            {
                if (++i >= argc)
                    return SyntaxError("--kObjCache-cc requires an precompiler output filename!\n");
                pszObjName = argv[i];
            }
        }
        else if (!strcmp(argv[i], "--kObjCache-both"))
            enmMode = kOC_BothArgv;
        else if (!strcmp(argv[i], "--kObjCache-options"))
            enmMode = kOC_Options;
        else if (!strcmp(argv[i], "--help"))
            return usage(stderr);
        else if (enmMode != kOC_Options)
        {
            if (enmMode == kOC_CppArgv || enmMode == kOC_BothArgv)
            {
                if (!(cArgvPreComp % 16))
                    papszArgvPreComp = xrealloc((void *)papszArgvPreComp, (cArgvPreComp + 17) * sizeof(papszArgvPreComp[0]));
                papszArgvPreComp[cArgvPreComp++] = argv[i];
                papszArgvPreComp[cArgvPreComp] = NULL;
            }
            if (enmMode == kOC_CcArgv || enmMode == kOC_BothArgv)
            {
                if (!(cArgvCompile % 16))
                    papszArgvCompile = xrealloc((void *)papszArgvCompile, (cArgvCompile + 17) * sizeof(papszArgvCompile[0]));
                papszArgvCompile[cArgvCompile++] = argv[i];
                papszArgvCompile[cArgvCompile] = NULL;
            }
        }
        else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--entry-file"))
        {
            if (i + 1 >= argc)
                return SyntaxError("%s requires a cache entry filename!\n", argv[i]);
            pszEntryFile = argv[++i];
        }
        else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--cache-file"))
        {
            if (i + 1 >= argc)
                return SyntaxError("%s requires a cache filename!\n", argv[i]);
            pszCacheFile = argv[++i];
        }
        else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--name"))
        {
            if (i + 1 >= argc)
                return SyntaxError("%s requires a cache name!\n", argv[i]);
            pszCacheName = argv[++i];
        }
        else if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--cache-dir"))
        {
            if (i + 1 >= argc)
                return SyntaxError("%s requires a cache directory!\n", argv[i]);
            pszCacheDir = argv[++i];
        }
        else if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--target"))
        {
            if (i + 1 >= argc)
                return SyntaxError("%s requires a target platform/arch name!\n", argv[i]);
            pszTarget = argv[++i];
        }
        else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--passthru"))
            fRedirPreCompStdOut = fRedirCompileStdIn = 1;
        else if (!strcmp(argv[i], "-r") || !strcmp(argv[i], "--redir-stdout"))
            fRedirPreCompStdOut = 1;
        else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose"))
            g_cVerbosityLevel++;
        else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--quiet"))
            g_cVerbosityLevel = 0;
        else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-?")
              || !strcmp(argv[i], "/h") || !strcmp(argv[i], "/?") || !strcmp(argv[i], "/help"))
        {
            usage(stdout);
            return 0;
        }
        else if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version"))
        {
            printf("kObjCache - kBuild version %d.%d.%d ($Revision: 1184 $)\n"
                   "Copyright (C) 2007 Knut St. Osmundsen\n",
                   KBUILD_VERSION_MAJOR, KBUILD_VERSION_MINOR, KBUILD_VERSION_PATCH);
            return 0;
        }
        else
            return SyntaxError("Doesn't grok '%s'!\n", argv[i]);
    }
    if (!pszEntryFile)
        return SyntaxError("No cache entry filename (-f)!\n");
    if (!pszTarget)
        return SyntaxError("No target name (-t)!\n");
    if (!cArgvCompile)
        return SyntaxError("No compiler arguments (--kObjCache-cc)!\n");
    if (!cArgvPreComp)
        return SyntaxError("No precompiler arguments (--kObjCache-cc)!\n");

    /*
     * Calc the cache file name.
     * It's a bit messy since the extension has to be replaced.
     */
    if (!pszCacheFile)
    {
        if (!pszCacheDir)
            return SyntaxError("No cache dir (-d / KOBJCACHE_DIR) and no cache filename!\n");
        if (!pszCacheName)
        {
            psz = (char *)FindFilenameInPath(pszEntryFile);
            if (!*psz)
                return SyntaxError("The cache file (-f) specifies a directory / nothing!\n");
            cch = psz - pszEntryFile;
            pszCacheName = memcpy(xmalloc(cch + 5), psz, cch + 1);
            psz = strrchr(pszCacheName, '.');
            if (!psz || psz <= pszCacheName)
                psz = (char *)pszCacheName + cch;
            memcpy(psz, ".koc", sizeof(".koc") - 1);
        }
        pszCacheFile = MakePathFromDirAndFile(pszCacheName, pszCacheDir);
    }

    /*
     * Create and initialize the two objects we'll be working on.
     *
     * We're supposed to be the only ones actually writing to the local file,
     * so it's perfectly fine to read it here before we lock it. This simplifies
     * the detection of object name and compiler argument changes.
     */
    SetErrorPrefix("kObjCache - %s", FindFilenameInPath(pszCacheFile));
    pCache = kObjCacheCreate(pszCacheFile);

    pEntry = kOCEntryCreate(pszEntryFile);
    kOCEntryRead(pEntry);
    kOCEntrySetCompileObjName(pEntry, pszObjName);
    kOCEntrySetCompileArgv(pEntry, papszArgvCompile, cArgvCompile);
    kOCEntrySetTarget(pEntry, pszTarget);
    kOCEntrySetCppName(pEntry, pszPreCompName);
    kOCEntrySetPipedMode(pEntry, fRedirPreCompStdOut, fRedirCompileStdIn);

    /*
     * Open (& lock) the two files and do validity checks and such.
     */
    kObjCacheLock(pCache);
    if (    kObjCacheIsNew(pCache)
        &&  kOCEntryNeedsCompiling(pEntry))
    {
        /*
         * Both files are missing/invalid.
         * Optimize this path as it is frequently used when making a clean build.
         */
        kObjCacheUnlock(pCache);
        InfoMsg(1, "doing full compile\n");
        kOCEntryPreCompileAndCompile(pEntry, papszArgvPreComp, cArgvPreComp);
        kObjCacheLock(pCache);
    }
    else
    {
        /*
         * Do the precompile (don't need to lock the cache file for this).
         */
        kObjCacheUnlock(pCache);
        kOCEntryPreCompile(pEntry, papszArgvPreComp, cArgvPreComp);

        /*
         * Check if we need to recompile. If we do, try see if the is a cache entry first.
         */
        kOCEntryCalcRecompile(pEntry);
        if (kOCEntryNeedsCompiling(pEntry))
        {
            PKOCENTRY pUseEntry;
            kObjCacheLock(pCache);
            kObjCacheRemoveEntry(pCache, pEntry);
            pUseEntry = kObjCacheFindMatchingEntry(pCache, pEntry);
            if (pUseEntry)
            {
                InfoMsg(1, "using cache entry '%s'\n", kOCEntryAbsPath(pUseEntry));
                kOCEntryCopy(pEntry, pUseEntry);
                kOCEntryDestroy(pUseEntry);
            }
            else
            {
                kObjCacheUnlock(pCache);
                InfoMsg(1, "recompiling\n");
                kOCEntryCompileIt(pEntry);
                kObjCacheLock(pCache);
            }
        }
        else
        {
            InfoMsg(1, "no need to recompile\n");
            kObjCacheLock(pCache);
        }
    }

    /*
     * Update the cache files.
     */
    kObjCacheRemoveEntry(pCache, pEntry);
    kObjCacheInsertEntry(pCache, pEntry);
    kOCEntryWrite(pEntry);
    kObjCacheUnlock(pCache);
    kObjCacheDestroy(pCache);
    return 0;
}


Generated by  Doxygen 1.6.0   Back to index