Пример #1
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);
    }
}
Пример #2
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());
}