//-------------------------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------------------------- 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); }
//-------------------------------------------------------------------------------------------------- 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; }