//-------------------------------------------------------------------------------------------------- void ApplicationBuilder_t::Build ( legato::App& app, std::string outputDirPath ///< Directory into which the generated app bundle should be put. ) //-------------------------------------------------------------------------------------------------- { CheckForLimitsConflicts(app); // Construct the working directory structure, which consists of an "work" directory and // a "staging" directory. Inside the "staging" directory, there is "lib", "bin", and any // other directories required to hold files bundled by the application or one of its components. // The "work" directory is for intermediate build output, like generated .c files and .o files. // The "staging" directory will get tar-compressed to become the actual application file. if (m_Params.IsVerbose()) { std::cout << "Creating working directories under '" << m_Params.ObjOutputDir() << "'." << std::endl; } legato::BuildParams_t buildParams(m_Params); const std::string& stagingDirPath = m_Params.StagingDir(); buildParams.LibOutputDir(stagingDirPath + "/lib"); buildParams.ExeOutputDir(stagingDirPath + "/bin"); buildParams.ObjOutputDir(m_Params.ObjOutputDir() + "/work"); // Clean the staging area. legato::CleanDir(stagingDirPath); // Create directories. legato::MakeDir(buildParams.ObjOutputDir()); legato::MakeDir(buildParams.LibOutputDir()); legato::MakeDir(buildParams.ExeOutputDir()); // Build all the components in the application, each with its own working directory // to avoid file name conflicts between .o files in different components, and copy all // generated and bundled files into the application staging area. // NOTE: Components have to be built before any other components that depend on them. // They also need to be bundled into the app in the same order, so that higher-layer // components can override files bundled by lower-layer components. ComponentBuilder_t componentBuilder(buildParams); auto& map = app.ComponentMap(); for (auto& mapEntry : map) { auto& componentPtr = mapEntry.second; BuildAndBundleComponent(*componentPtr, componentBuilder, buildParams.ObjOutputDir()); } // Build all the executables and their IPC libs. BuildExecutables(app, buildParams); // Copy in any bundled files and directories from the "bundles:" section of the .adef. // Note: do the directories first, in case the files list adds files to those directories. for (auto& fileMapping : app.BundledDirs()) { mk::CopyToStaging( fileMapping.m_SourcePath, stagingDirPath, fileMapping.m_DestPath, m_Params.IsVerbose() ); } for (auto& fileMapping : app.BundledFiles()) { mk::CopyToStaging( fileMapping.m_SourcePath, stagingDirPath, fileMapping.m_DestPath, m_Params.IsVerbose() ); } // Generate the app-specific configuration data that tells the framework what limits to place // on the app when it is run, etc. GenerateSystemConfig(stagingDirPath, app, m_Params); // TODO: Generate the application's configuration tree (containing all its pool sizes, // and anything else listed under the "config:" section of the .adef.) // TODO: Copy in the metadata (.adef and Component.cdef) files so they can be retrieved // by Developer Studio. // Zip it all up. std::string outputPath = legato::CombinePath( outputDirPath, app.Name() + "." + buildParams.Target() ); if (!legato::IsAbsolutePath(outputPath)) { outputPath = legato::GetWorkingDir() + "/" + outputPath; } std::string tarCommandLine = "tar cjf \"" + outputPath + "\" -C \"" + stagingDirPath + "\" ."; if (m_Params.IsVerbose()) { std::cout << "Packaging application into '" << outputPath << "'." << std::endl; std::cout << std::endl << "$ " << tarCommandLine << std::endl << std::endl; } mk::ExecuteCommandLine(tarCommandLine); }
//-------------------------------------------------------------------------------------------------- static void GenerateFileMappingConfig ( std::ofstream& cfgStream, const legato::App& app ) //-------------------------------------------------------------------------------------------------- { size_t index = 0; // Create nodes under "files", where each node is named with an index, starting a 0, // and contains a "src" node and a "dest" node. cfgStream << " \"files\"" << std::endl; cfgStream << " {" << std::endl; // Import the files specified in the .adef file. for (const auto& mapping : app.RequiredFiles()) { GenerateSingleFileMappingConfig(cfgStream, index++, mapping); } // Bundled files also need to be imported into the application sandbox. for (const auto& mapping : app.BundledFiles()) { GenerateBundledObjectMappingConfig(cfgStream, index++, mapping); } // Bundled directories also need to be imported into the application sandbox. for (const auto& mapping : app.BundledDirs()) { GenerateBundledObjectMappingConfig(cfgStream, index++, mapping); } // Map into the sandbox all the files for all the components. for (const auto& pair : app.ComponentMap()) { const auto& componentPtr = pair.second; // External files... for (const auto& mapping : componentPtr->RequiredFiles()) { GenerateSingleFileMappingConfig(cfgStream, index++, mapping); } // External directories... for (const auto& mapping : componentPtr->RequiredDirs()) { GenerateSingleFileMappingConfig(cfgStream, index++, mapping); } // NOTE: Bundled files and directories also need to be mapped into the application sandbox // because the application's on-target install directory is outside its runtime sandbox. // Bundled files... for (const auto& mapping : componentPtr->BundledFiles()) { GenerateBundledObjectMappingConfig(cfgStream, index++, mapping); } // Bundled directories... for (const auto& mapping : componentPtr->BundledDirs()) { GenerateBundledObjectMappingConfig(cfgStream, index++, mapping); } } cfgStream << " }" << std::endl << std::endl; }