Ejemplo n.º 1
0
BuildInfo *LSCompiler::loadBuildFile(const utString& cref)
{
    for (UTsize i = 0; i < sourcePath.size(); i++)
    {
        utString path = sourcePath.at(i);
        path += platform_getFolderDelimiter();
        path += cref;
        if (!strstr(cref.c_str(), ".build"))
        {
            path += ".build";
        }

        utFileStream stream;
        stream.open(path.c_str(), utStream::SM_READ);
        if (stream.isOpen())
        {
            stream.close();

            BuildInfo *buildInfo = BuildInfo::parseBuildFile(path.c_str());
            return buildInfo;
        }
    }

    return NULL;
}
Ejemplo n.º 2
0
const char *platform_normalizePath(const char *path)
{
    static char npath[4096];
    int         i;
    int         nlen;
    char        delimiter;

    nlen = strlen(path);

    if (nlen > 4000)
    {
        return "";
    }

    strcpy(npath, path);

    delimiter = platform_getFolderDelimiter()[0];

    for (i = 0; i < nlen; i++)
    {
        if ((npath[i] == '\\') || (npath[i] == '/'))
        {
            npath[i] = delimiter;
        }
    }

    return npath;
}
Ejemplo n.º 3
0
void LSCompiler::generateRootDependenciesRecursive(const utString& ref)
{
    // We're either going to be compiling against an existing loom assembly
    // or compiling from a build file

    char cref[2048];

    snprintf(cref, 2048, "%s", ref.c_str());
    if (strstr(cref, ".loomlib"))
    {
        *(strstr(cref, ".loomlib")) = 0;
    }

    for (UTsize i = 0; i < rootBuildDependencies.size(); i++)
    {
        BuildInfo *buildInfo = rootBuildDependencies.at(i);
        if (buildInfo->getAssemblyName() == cref)
        {
            return;
        }
    }

    // first look in the src folders for an existing build file
    BuildInfo *buildInfo = loadBuildFile(cref);

    if (buildInfo)
    {
        utString  assemblyLib = buildInfo->getOutputDir() + platform_getFolderDelimiter() + buildInfo->getAssemblyName() + ".loomlib";

        // If the assembly is not built yet, build it
        if (!platform_mapFileExists(assemblyLib.c_str()))
        {
            for (UTsize i = 0; i < buildInfo->getNumReferences(); i++)
            {
                utString rref = buildInfo->getReference(i);
                generateRootDependenciesRecursive(rref);
            }

            rootBuildDependencies.push_back(buildInfo);
        }
        else
        {
            rootLibDependencies.push_back(ref);
        }
    }

    if (rootDependencies.find(ref) == UT_NPOS)
    {
        if (!buildInfo)
        {
            // we're compiling against a .loomlib and won't be rebuilding it
            rootLibDependencies.push_back(ref);
        }

        rootDependencies.push_back(ref);
    }
}
Ejemplo n.º 4
0
// Take a snapshot of the state of all our tracked files. This snapshot can
// then be compared to identify changes.
static utArray<FileEntry> *generateFileState(const char *root)
{
    utArray<FileEntry> *list = lmNew(NULL) utArray<FileEntry>();

    // Walk files in assets and src.
    char buffer[2048];

    sprintf(buffer, "%s%s%s", root, platform_getFolderDelimiter(), "assets");
    platform_walkFiles(buffer, handleFileStateWalkCallback, list);

    sprintf(buffer, "%s%s%s", root, platform_getFolderDelimiter(), "src");
    platform_walkFiles(buffer, handleFileStateWalkCallback, list);

    sprintf(buffer, "%s%s%s", root, platform_getFolderDelimiter(), "bin");
    platform_walkFiles(buffer, handleFileStateWalkCallback, list);

    // Sort the list into canonical order.
    list->sort(compareFileEntryBool);

    // Return the list.
    return list;
}
Ejemplo n.º 5
0
void LSCompiler::linkRootAssembly(const utString& sjson)
{
    json_error_t jerror;
    json_t       *json = json_loadb((const char *)sjson.c_str(), sjson.length(), 0, &jerror);

    lmAssert(json, "Error linking assembly");

    json_t *ref_array = json_object_get(json, "references");
    lmAssert(json, "Error linking assembly, can't get executable references");

    for (UTsize i = 0; i < rootBuildDependencies.size(); i++)
    {
        BuildInfo *buildInfo     = rootBuildDependencies.at(i);
        utString  assemblySource = buildInfo->getOutputDir() + platform_getFolderDelimiter() + buildInfo->getAssemblyName() + ".loomlib";

        utArray<unsigned char> rarray;
        lmAssert(utFileStream::tryReadToArray(assemblySource, rarray), "Unable to load library assembly %s", assemblySource.c_str());

        utBase64 base64 = utBase64::encode64(rarray);

        for (size_t j = 0; j < json_array_size(ref_array); j++)
        {
            json_t   *jref = json_array_get(ref_array, j);
            utString jname = json_string_value(json_object_get(jref, "name"));
            if (buildInfo->getAssemblyName() == jname)
            {
                logVerbose("Linking: %s", jname.c_str());

                json_object_set(jref, "binary", json_string(base64.getBase64().c_str()));
                json_object_set(jref, "uid", json_string(readAssemblyUID(rarray)));
                break;
            }
        }
    }

    // filter the reference array by the import assemblies
    utStack<int> filter;
    for (size_t j = 0; j < json_array_size(ref_array); j++)
    {
        json_t   *jref = json_array_get(ref_array, j);
        utString jname = json_string_value(json_object_get(jref, "name"));

        bool found = false;

        // always find the System assembly, so we don't have to explicitly import from it
        if (jname == "System")
        {
            found = true;
        }

        for (UTsize k = 0; k < importedAssemblies.size() && !found; k++)
        {
            if (importedAssemblies.at(k)->getName() == jname)
            {
                found = true;
                break;
            }
        }

        if (!found)
        {
            filter.push((int)j);
        }
    }

    while (filter.size())
    {
        json_array_remove(ref_array, filter.pop());
    }

    for (UTsize i = 0; i < rootLibDependencies.size(); i++)
    {
        utString libName = rootLibDependencies.at(i);

        for (size_t j = 0; j < json_array_size(ref_array); j++)
        {
            json_t   *jref = json_array_get(ref_array, j);
            utString jname = json_string_value(json_object_get(jref, "name"));

            if (libName != jname)
            {
                continue;
            }

            log("Linking: %s", libName.c_str());

            utString delim   = platform_getFolderDelimiter();
            utString libPath = sdkPath + delim + "libs" + delim + libName + ".loomlib";

            utArray<unsigned char> rarray;

            if (libName == "System" && embeddedSystemAssembly)
            {
                size_t embeddedSystemAssemblyLength = strlen(embeddedSystemAssembly);
                rarray.resize((int)(embeddedSystemAssemblyLength + 1));
                memcpy(&rarray[0], embeddedSystemAssembly, embeddedSystemAssemblyLength + 1);
            }
            else
            {
                lmAssert(utFileStream::tryReadToArray(libPath, rarray), "Unable to load library assembly %s at %s", libName.c_str(), libPath.c_str());    
            }

            utBase64 base64 = utBase64::encode64(rarray);
            json_object_set(jref, "binary", json_string(base64.getBase64().c_str()));
            json_object_set(jref, "uid", json_string(readAssemblyUID(rarray)));

            break;
        }
    }

    json_object_set(json, "executable", json_true());

    utString execSource = rootBuildInfo->getOutputDir() + utString(platform_getFolderDelimiter()) + rootBuildInfo->getAssemblyName() + ".loom";

    // generate binary assembly for executable
    BinWriter::writeExecutable(execSource.c_str(), json);

    log("Compile Successful: %s\n", execSource.c_str());
}
Ejemplo n.º 6
0
void LSCompiler::compileAssembly(BuildInfo *buildInfo)
{
    clearImports();

    log("Compiling: %s", buildInfo->getAssemblyName().c_str());

    LSCompiler *compiler = new LSCompiler();

    // open a new (isolated) compiler VM
    compiler->openCompilerVM();

    compiler->vm->setCompiling(true);

    // parses the build file, parses source files, generates AST, etc
    compiler->buildInfo = buildInfo;

    // let the buildInfo know we are debug
    compiler->buildInfo->setDebugBuild(debugBuild);

    // build 1st pass assembly which contains type signatures but no code
    AssemblyBuilder *ab = AssemblyBuilder::create(compiler->buildInfo);

    utString typesAssembly;

    // write out temporary assembly
    ab->writeToString(typesAssembly);

    //load the type signature assembly into our VM (also loads any references)
    Assembly *assembly = compiler->vm->loadTypeAssembly(typesAssembly);

    // compile all modules (types)
    compiler->compileModules();

    // dump any errors/warnings
    LSCompilerLog::dump();

    // if we have any compiler errors, exit
    if (LSCompilerLog::getNumErrors())
    {
        exit(EXIT_FAILURE);
    }

    LSCompilerLog::clear();

    ab->setAssembly(assembly);

    // inject type information
    ab->injectTypes(assembly);

    // inject byte code into assembly builder
    ab->injectByteCode(assembly);

    // write out final assembly
    utString outputDir = compiler->buildInfo->getOutputDir();

    utString ext = ".loom";

    if (compiler->buildInfo->isExecutable())
    {
        processExecutableConfig(ab);
        utString json;
        ab->writeToString(json);

        // output a loom lib for IDE's to consume

        if (dumpSymbols)
        {
            utString jsonFileName;

            if (outputDir.length())
            {
                jsonFileName = outputDir + platform_getFolderDelimiter() + compiler->buildInfo->getAssemblyName() + ".symbols";
            }
            else
            {
                jsonFileName = compiler->buildInfo->getAssemblyName() + ".symbols";
            }

            ab->writeToFile(jsonFileName);

            log("Symbols Generated: %s", jsonFileName.c_str());
        }

        // finally link the root assembly
        linkRootAssembly(json);
    }
    else
    {
        utString jsonFileName;

        ext = ".loomlib";

        if (outputDir.length())
        {
            jsonFileName = outputDir + platform_getFolderDelimiter() + compiler->buildInfo->getAssemblyName() + ext;
        }
        else
        {
            jsonFileName = compiler->buildInfo->getAssemblyName() + ext;
        }

        ab->writeToFile(jsonFileName);
    }


    compiler->vm->setCompiling(false);

    // shut 'er down!
    compiler->closeCompilerVM();

    delete compiler;
}