示例#1
0
//--------------------------------------------------------------------------------------------------
static void GenerateSystemConfig
(
    const std::string& stagingDirPath
)
//--------------------------------------------------------------------------------------------------
{
    // Open the bindings file for writing
    std::string path = stagingDirPath + "/bindings";

    if (BuildParams.IsVerbose())
    {
        std::cout << "Writing non-app bindings to file '" << path << "'."
                  << std::endl;
    }

    std::ofstream cfgStream(path, std::ofstream::trunc);

    // For each binding in the System object's list,
    for (auto bindIter : System.ApiBinds())
    {
        auto& bind = bindIter.second;

        // If the client is a non-app user,
        // Write an entry into the bindings file for this binding.
        if (! bind.IsClientAnApp())
        {
            cfgStream << '<' << bind.ClientUserName() << ">."
                      << bind.ClientInterfaceName() << " -> ";

            if (bind.IsServerAnApp())
            {
                cfgStream << bind.ServerAppName() << ".";
            }
            else
            {
                cfgStream << "<" << bind.ServerUserName() << ">.";
            }

            cfgStream << bind.ServerInterfaceName() << std::endl;
        }
    }
}
//--------------------------------------------------------------------------------------------------
static void GenerateSystemConfig
(
    const std::string& stagingDirPath,  ///< Path to the root of the app's staging directory.
    legato::App& app,                   ///< The app to generate the configuration for.
    const legato::BuildParams_t& buildParams ///< Build parameters, such as the "is verbose" flag.
)
//--------------------------------------------------------------------------------------------------
{
    // TODO: Rename this file to something that makes more sense (like "system.cfg", because it
    // gets installed in the "system" config tree).
    std::string path = stagingDirPath + "/root.cfg";

    if (buildParams.IsVerbose())
    {
        std::cout << "Generating system configuration data for app '" << app.Name() << "' in file '"
                  << path << "'." << std::endl;
    }

    std::ofstream cfgStream(path, std::ofstream::trunc);

    cfgStream << "{" << std::endl;

    GenerateAppVersionConfig(cfgStream, app);

    GenerateAppLimitsConfig(cfgStream, app);

    GenerateGroupsConfig(cfgStream, app);

    GenerateFileMappingConfig(cfgStream, app);

    GenerateProcessConfig(cfgStream, app);

    GenerateIpcBindingConfig(cfgStream, app, buildParams);

    GenerateConfigTreeAclConfig(cfgStream, app);

    cfgStream << "}" << std::endl;
}
示例#3
0
//--------------------------------------------------------------------------------------------------
static void Build
(
    void
)
//--------------------------------------------------------------------------------------------------
{
    // Construct the working directory structure, which consists of an "obj" directory and
    // a "staging" directory.  Application bundles will be put inside the "staging" directory.
    // The "staging" directory will get tarred to become the actual system bundle.
    // The "obj" directory is for intermediate build output, like generated .c
    // files and .o files.  Under the "obj" directory each app has its own subdirectory to work in.
    if (BuildParams.IsVerbose())
    {
        std::cout << "Creating working directories under '" << BuildParams.ObjOutputDir() << "'."
                  << std::endl;
    }
    std::string objDirPath = BuildParams.ObjOutputDir() + "/obj";
    std::string stagingDirPath = BuildParams.ObjOutputDir() + "/staging";

    // Clean the staging area.
    legato::CleanDir(stagingDirPath);

    // Create the staging and working directories.
    legato::MakeDir(objDirPath);
    legato::MakeDir(stagingDirPath);

    // For each app in the system,
    for (auto& mapEntry : System.Apps())
    {
        auto& app = mapEntry.second;

        // Create an Application Builder object to use to build this app.
        // Give it the appropriate build parameters.
        legato::BuildParams_t appBuildParams(BuildParams);
        appBuildParams.ObjOutputDir(legato::CombinePath(objDirPath, app.Name()));
        appBuildParams.StagingDir(legato::CombinePath(appBuildParams.ObjOutputDir(), "staging"));
        ApplicationBuilder_t appBuilder(appBuildParams);

        // Build the app.  This should result in an application bundle appearing in the
        // staging directory.
        appBuilder.Build(app, stagingDirPath);
    }

    // TODO: Copy in metadata for use by Developer Studio.

    // Generate a configuration data file containing user-to-app and user-to-user bindings.
    GenerateSystemConfig(stagingDirPath);

    // Create the tarball file name.
    std::string outputPath = legato::CombinePath(OutputDir, System.Name());
    outputPath += "." + BuildParams.Target() + "_sys";  // Add the file name extension.
    if (!legato::IsAbsolutePath(outputPath))
    {
        outputPath = legato::GetWorkingDir() + "/" + outputPath;
    }

    // Create the tarball.
    std::string tarCommandLine = "tar cf \"" + outputPath + "\" -C \"" + stagingDirPath + "\" .";
    if (BuildParams.IsVerbose())
    {
        std::cout << "Packaging system into '" << outputPath << "'." << std::endl;
        std::cout << std::endl << "$ "<< tarCommandLine << std::endl << std::endl;
    }
    mk::ExecuteCommandLine(tarCommandLine);
}
示例#4
0
//--------------------------------------------------------------------------------------------------
static legato::Executable& ConstructObjectModel
(
    void
)
//--------------------------------------------------------------------------------------------------
{
    bool errorFound = false;

    // Create a new Executable object.
    legato::Executable& exe = App.CreateExecutable(ExePath);

    if (BuildParams.IsVerbose())
    {
        std::cout << "Making executable '" << exe.OutputPath() << "'" << std::endl
                  << "\t(using exe name '" << exe.CName() << "')" << std::endl
                  << "\tcontaining:" << std::endl;
    }

    // For each item of content, we have to figure out what type of content it is and
    // handle it accordingly.
    for (auto contentName: ContentNames)
    {
        const char* contentType;

        if (legato::IsCSource(contentName))
        {
            contentType = "C source code";

            // Add the source code file to the default component.
            exe.AddCSourceFile(legato::FindFile(contentName, BuildParams.ComponentDirs()));
        }
        else if (legato::IsLibrary(contentName))
        {
            contentType = "library";

            // Add the library file to the list of libraries to be linked with the default
            // component.
            exe.AddLibrary(contentName);
        }
        else if (legato::IsComponent(contentName, BuildParams.ComponentDirs()))
        {
            contentType = "component";

            // Find the component and add it to the executable's list of component instances.
            // NOTE: For now, we only support one instance of a component per executable, and it is
            //       identified by the file system path to that component (relative to a directory
            //       somewhere in the component search path).
            legato::Component& component = GetComponent(contentName);
            exe.AddComponentInstance(legato::ComponentInstance(component));
        }
        else
        {
            contentType = "** unknown **";

            std::cerr << "** ERROR: Couldn't identify content item '"
                      << contentName << "'." << std::endl;

            errorFound = true;
        }

        if (BuildParams.IsVerbose())
        {
            std::cout << "\t\t'" << contentName << "' (" << contentType << ")" << std::endl;
        }
    }

    if (errorFound)
    {
        throw std::runtime_error("Unable to identify requested content.");
    }

    return exe;
}