123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmGlobalGhsMultiGenerator.h"
- #include "cmsys/SystemTools.hxx"
- #include "cmAlgorithms.h"
- #include "cmDocumentationEntry.h"
- #include "cmGeneratedFileStream.h"
- #include "cmGeneratorTarget.h"
- #include "cmGhsMultiTargetGenerator.h"
- #include "cmLocalGhsMultiGenerator.h"
- #include "cmMakefile.h"
- #include "cmVersion.h"
- const char* cmGlobalGhsMultiGenerator::FILE_EXTENSION = ".gpj";
- const char* cmGlobalGhsMultiGenerator::DEFAULT_MAKE_PROGRAM = "gbuild";
- cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
- : cmGlobalGenerator(cm)
- , OSDirRelative(false)
- {
- this->GhsBuildCommandInitialized = false;
- }
- cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator()
- {
- cmDeleteAll(TargetFolderBuildStreams);
- }
- cmLocalGenerator* cmGlobalGhsMultiGenerator::CreateLocalGenerator(
- cmMakefile* mf)
- {
- return new cmLocalGhsMultiGenerator(this, mf);
- }
- void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
- {
- entry.Name = GetActualName();
- entry.Brief =
- "Generates Green Hills MULTI files (experimental, work-in-progress).";
- }
- void cmGlobalGhsMultiGenerator::EnableLanguage(
- std::vector<std::string> const& l, cmMakefile* mf, bool optional)
- {
- mf->AddDefinition("CMAKE_SYSTEM_NAME", "GHS-MULTI");
- mf->AddDefinition("CMAKE_SYSTEM_PROCESSOR", "ARM");
- const std::string ghsCompRoot(GetCompRoot());
- mf->AddDefinition("GHS_COMP_ROOT", ghsCompRoot.c_str());
- std::string ghsCompRootStart =
- 0 == ghsCompRootStart.size() ? "" : ghsCompRoot + "/";
- mf->AddDefinition("CMAKE_C_COMPILER",
- std::string(ghsCompRootStart + "ccarm.exe").c_str());
- mf->AddDefinition("CMAKE_C_COMPILER_ID_RUN", "TRUE");
- mf->AddDefinition("CMAKE_C_COMPILER_ID", "GHS");
- mf->AddDefinition("CMAKE_C_COMPILER_FORCED", "TRUE");
- mf->AddDefinition("CMAKE_CXX_COMPILER",
- std::string(ghsCompRootStart + "cxarm.exe").c_str());
- mf->AddDefinition("CMAKE_CXX_COMPILER_ID_RUN", "TRUE");
- mf->AddDefinition("CMAKE_CXX_COMPILER_ID", "GHS");
- mf->AddDefinition("CMAKE_CXX_COMPILER_FORCED", "TRUE");
- if (!ghsCompRoot.empty()) {
- static const char* compPreFix = "comp_";
- std::string compFilename =
- cmsys::SystemTools::FindLastString(ghsCompRoot.c_str(), compPreFix);
- cmsys::SystemTools::ReplaceString(compFilename, compPreFix, "");
- mf->AddDefinition("CMAKE_SYSTEM_VERSION", compFilename.c_str());
- }
- mf->AddDefinition("GHSMULTI", "1"); // identifier for user CMake files
- this->cmGlobalGenerator::EnableLanguage(l, mf, optional);
- }
- bool cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile* mf)
- {
- // The GHS generator knows how to lookup its build tool
- // directly instead of needing a helper module to do it, so we
- // do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
- if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
- mf->AddDefinition("CMAKE_MAKE_PROGRAM",
- this->GetGhsBuildCommand().c_str());
- }
- return true;
- }
- std::string const& cmGlobalGhsMultiGenerator::GetGhsBuildCommand()
- {
- if (!this->GhsBuildCommandInitialized) {
- this->GhsBuildCommandInitialized = true;
- this->GhsBuildCommand = this->FindGhsBuildCommand();
- }
- return this->GhsBuildCommand;
- }
- std::string cmGlobalGhsMultiGenerator::FindGhsBuildCommand()
- {
- std::vector<std::string> userPaths;
- userPaths.push_back(this->GetCompRoot());
- std::string makeProgram =
- cmSystemTools::FindProgram(DEFAULT_MAKE_PROGRAM, userPaths);
- if (makeProgram.empty()) {
- makeProgram = DEFAULT_MAKE_PROGRAM;
- }
- return makeProgram;
- }
- std::string cmGlobalGhsMultiGenerator::GetCompRoot()
- {
- std::string output;
- const std::vector<std::string> potentialDirsHardPaths(
- GetCompRootHardPaths());
- const std::vector<std::string> potentialDirsRegistry(GetCompRootRegistry());
- std::vector<std::string> potentialDirsComplete;
- potentialDirsComplete.insert(potentialDirsComplete.end(),
- potentialDirsHardPaths.begin(),
- potentialDirsHardPaths.end());
- potentialDirsComplete.insert(potentialDirsComplete.end(),
- potentialDirsRegistry.begin(),
- potentialDirsRegistry.end());
- // Use latest version
- std::string outputDirName;
- for (std::vector<std::string>::const_iterator potentialDirsCompleteIt =
- potentialDirsComplete.begin();
- potentialDirsCompleteIt != potentialDirsComplete.end();
- ++potentialDirsCompleteIt) {
- const std::string dirName(
- cmsys::SystemTools::GetFilenameName(*potentialDirsCompleteIt));
- if (dirName.compare(outputDirName) > 0) {
- output = *potentialDirsCompleteIt;
- outputDirName = dirName;
- }
- }
- return output;
- }
- std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootHardPaths()
- {
- std::vector<std::string> output;
- cmSystemTools::Glob("C:/ghs", "comp_[^;]+", output);
- for (std::vector<std::string>::iterator outputIt = output.begin();
- outputIt != output.end(); ++outputIt) {
- *outputIt = "C:/ghs/" + *outputIt;
- }
- return output;
- }
- std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootRegistry()
- {
- std::vector<std::string> output(2);
- cmsys::SystemTools::ReadRegistryValue(
- "HKEY_LOCAL_"
- "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
- "Windows\\CurrentVersion\\Uninstall\\"
- "GreenHillsSoftwared771f1b4;InstallLocation",
- output[0]);
- cmsys::SystemTools::ReadRegistryValue(
- "HKEY_LOCAL_"
- "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
- "Windows\\CurrentVersion\\Uninstall\\"
- "GreenHillsSoftware9881cef6;InstallLocation",
- output[1]);
- return output;
- }
- void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
- std::string const& filepath, cmGeneratedFileStream** filestream)
- {
- // Get a stream where to generate things.
- if (NULL == *filestream) {
- *filestream = new cmGeneratedFileStream(filepath.c_str());
- if (NULL != *filestream) {
- OpenBuildFileStream(*filestream);
- }
- }
- }
- void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
- cmGeneratedFileStream* filestream)
- {
- *filestream << "#!gbuild" << std::endl;
- }
- void cmGlobalGhsMultiGenerator::OpenBuildFileStream()
- {
- // Compute GHS MULTI's build file path.
- std::string buildFilePath =
- this->GetCMakeInstance()->GetHomeOutputDirectory();
- buildFilePath += "/";
- buildFilePath += "default";
- buildFilePath += FILE_EXTENSION;
- this->Open(std::string(""), buildFilePath, &this->TargetFolderBuildStreams);
- OpenBuildFileStream(GetBuildFileStream());
- char const* osDir =
- this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR");
- if (NULL == osDir) {
- osDir = "";
- cmSystemTools::Error("GHS_OS_DIR cache variable must be set");
- } else {
- this->GetCMakeInstance()->MarkCliAsUsed("GHS_OS_DIR");
- }
- std::string fOSDir(this->trimQuotes(osDir));
- std::replace(fOSDir.begin(), fOSDir.end(), '\\', '/');
- if (!fOSDir.empty() && ('c' == fOSDir[0] || 'C' == fOSDir[0])) {
- this->OSDirRelative = false;
- } else {
- this->OSDirRelative = true;
- }
- char const* bspName =
- this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME");
- if (NULL == bspName) {
- bspName = "";
- cmSystemTools::Error("GHS_BSP_NAME cache variable must be set");
- } else {
- this->GetCMakeInstance()->MarkCliAsUsed("GHS_BSP_NAME");
- }
- std::string fBspName(this->trimQuotes(bspName));
- std::replace(fBspName.begin(), fBspName.end(), '\\', '/');
- this->WriteMacros();
- this->WriteHighLevelDirectives();
- GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, this->GetBuildFileStream());
- this->WriteDisclaimer(this->GetBuildFileStream());
- *this->GetBuildFileStream() << "# Top Level Project File" << std::endl;
- if (!fBspName.empty()) {
- *this->GetBuildFileStream() << " -bsp " << fBspName << std::endl;
- }
- this->WriteCompilerOptions(fOSDir);
- }
- void cmGlobalGhsMultiGenerator::CloseBuildFileStream(
- cmGeneratedFileStream** filestream)
- {
- if (filestream) {
- delete *filestream;
- *filestream = NULL;
- } else {
- cmSystemTools::Error("Build file stream was not open.");
- }
- }
- void cmGlobalGhsMultiGenerator::Generate()
- {
- this->cmGlobalGenerator::Generate();
- if (!this->LocalGenerators.empty()) {
- this->OpenBuildFileStream();
- // Build all the folder build files
- for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
- cmLocalGhsMultiGenerator* lg =
- static_cast<cmLocalGhsMultiGenerator*>(this->LocalGenerators[i]);
- const std::vector<cmGeneratorTarget*>& tgts = lg->GetGeneratorTargets();
- this->UpdateBuildFiles(tgts);
- }
- }
- cmDeleteAll(TargetFolderBuildStreams);
- this->TargetFolderBuildStreams.clear();
- }
- void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
- std::vector<std::string>& makeCommand, const std::string& makeProgram,
- const std::string& /*projectName*/, const std::string& /*projectDir*/,
- const std::string& targetName, const std::string& /*config*/, bool /*fast*/,
- bool /*verbose*/, std::vector<std::string> const& makeOptions)
- {
- makeCommand.push_back(
- this->SelectMakeProgram(makeProgram, this->GetGhsBuildCommand()));
- makeCommand.insert(makeCommand.end(), makeOptions.begin(),
- makeOptions.end());
- if (!targetName.empty()) {
- if (targetName == "clean") {
- makeCommand.push_back("-clean");
- } else {
- makeCommand.push_back(targetName);
- }
- }
- }
- void cmGlobalGhsMultiGenerator::WriteMacros()
- {
- char const* ghsGpjMacros =
- this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
- if (NULL != ghsGpjMacros) {
- std::vector<std::string> expandedList;
- cmSystemTools::ExpandListArgument(std::string(ghsGpjMacros), expandedList);
- for (std::vector<std::string>::const_iterator expandedListI =
- expandedList.begin();
- expandedListI != expandedList.end(); ++expandedListI) {
- *this->GetBuildFileStream() << "macro " << *expandedListI << std::endl;
- }
- }
- }
- void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives()
- {
- *this->GetBuildFileStream() << "primaryTarget=arm_integrity.tgt"
- << std::endl;
- char const* const customization =
- this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
- if (NULL != customization && strlen(customization) > 0) {
- *this->GetBuildFileStream()
- << "customization=" << trimQuotes(customization) << std::endl;
- this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
- }
- }
- void cmGlobalGhsMultiGenerator::WriteCompilerOptions(std::string const& fOSDir)
- {
- *this->GetBuildFileStream() << " -os_dir=\"" << fOSDir << "\""
- << std::endl;
- }
- void cmGlobalGhsMultiGenerator::WriteDisclaimer(std::ostream* os)
- {
- (*os) << "#" << std::endl
- << "# CMAKE generated file: DO NOT EDIT!" << std::endl
- << "# Generated by \"" << GetActualName() << "\""
- << " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
- << cmVersion::GetMinorVersion() << std::endl
- << "#" << std::endl;
- }
- void cmGlobalGhsMultiGenerator::AddFilesUpToPath(
- cmGeneratedFileStream* mainBuildFile,
- std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
- char const* homeOutputDirectory, std::string const& path,
- GhsMultiGpj::Types projType, std::string const& relPath)
- {
- std::string workingPath(path);
- cmSystemTools::ConvertToUnixSlashes(workingPath);
- std::vector<cmsys::String> splitPath =
- cmSystemTools::SplitString(workingPath);
- std::string workingRelPath(relPath);
- cmSystemTools::ConvertToUnixSlashes(workingRelPath);
- if (!workingRelPath.empty()) {
- workingRelPath += "/";
- }
- std::string pathUpTo;
- for (std::vector<cmsys::String>::const_iterator splitPathI =
- splitPath.begin();
- splitPath.end() != splitPathI; ++splitPathI) {
- pathUpTo += *splitPathI;
- if (targetFolderBuildStreams->end() ==
- targetFolderBuildStreams->find(pathUpTo)) {
- AddFilesUpToPathNewBuildFile(
- mainBuildFile, targetFolderBuildStreams, homeOutputDirectory, pathUpTo,
- splitPath.begin() == splitPathI, workingRelPath, projType);
- }
- AddFilesUpToPathAppendNextFile(targetFolderBuildStreams, pathUpTo,
- splitPathI, splitPath.end(), projType);
- pathUpTo += "/";
- }
- }
- void cmGlobalGhsMultiGenerator::Open(
- std::string const& mapKeyName, std::string const& fileName,
- std::map<std::string, cmGeneratedFileStream*>* fileMap)
- {
- if (fileMap->end() == fileMap->find(fileName)) {
- cmGeneratedFileStream* temp(new cmGeneratedFileStream);
- temp->open(fileName.c_str());
- (*fileMap)[mapKeyName] = temp;
- }
- }
- void cmGlobalGhsMultiGenerator::AddFilesUpToPathNewBuildFile(
- cmGeneratedFileStream* mainBuildFile,
- std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
- char const* homeOutputDirectory, std::string const& pathUpTo,
- bool const isFirst, std::string const& relPath,
- GhsMultiGpj::Types const projType)
- {
- // create folders up to file path
- std::string absPath = std::string(homeOutputDirectory) + "/" + relPath;
- std::string newPath = absPath + pathUpTo;
- if (!cmSystemTools::FileExists(newPath.c_str())) {
- cmSystemTools::MakeDirectory(newPath.c_str());
- }
- // Write out to filename for first time
- std::string relFilename(GetFileNameFromPath(pathUpTo));
- std::string absFilename = absPath + relFilename;
- Open(pathUpTo, absFilename, targetFolderBuildStreams);
- OpenBuildFileStream((*targetFolderBuildStreams)[pathUpTo]);
- GhsMultiGpj::WriteGpjTag(projType, (*targetFolderBuildStreams)[pathUpTo]);
- WriteDisclaimer((*targetFolderBuildStreams)[pathUpTo]);
- // Add to main build file
- if (isFirst) {
- *mainBuildFile << relFilename << " ";
- GhsMultiGpj::WriteGpjTag(projType, mainBuildFile);
- }
- }
- void cmGlobalGhsMultiGenerator::AddFilesUpToPathAppendNextFile(
- std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
- std::string const& pathUpTo,
- std::vector<cmsys::String>::const_iterator splitPathI,
- std::vector<cmsys::String>::const_iterator end,
- GhsMultiGpj::Types const projType)
- {
- std::vector<cmsys::String>::const_iterator splitPathNextI = splitPathI + 1;
- if (end != splitPathNextI &&
- targetFolderBuildStreams->end() ==
- targetFolderBuildStreams->find(pathUpTo + "/" + *splitPathNextI)) {
- std::string nextFilename(*splitPathNextI);
- nextFilename = GetFileNameFromPath(nextFilename);
- *(*targetFolderBuildStreams)[pathUpTo] << nextFilename << " ";
- GhsMultiGpj::WriteGpjTag(projType, (*targetFolderBuildStreams)[pathUpTo]);
- }
- }
- std::string cmGlobalGhsMultiGenerator::GetFileNameFromPath(
- std::string const& path)
- {
- std::string output(path);
- if (!path.empty()) {
- cmSystemTools::ConvertToUnixSlashes(output);
- std::vector<cmsys::String> splitPath = cmSystemTools::SplitString(output);
- output += "/" + splitPath.back() + FILE_EXTENSION;
- }
- return output;
- }
- void cmGlobalGhsMultiGenerator::UpdateBuildFiles(
- const std::vector<cmGeneratorTarget*>& tgts)
- {
- for (std::vector<cmGeneratorTarget*>::const_iterator tgtsI = tgts.begin();
- tgtsI != tgts.end(); ++tgtsI) {
- const cmGeneratorTarget* tgt = *tgtsI;
- if (IsTgtForBuild(tgt)) {
- std::string folderName = tgt->GetEffectiveFolderName();
- if (this->TargetFolderBuildStreams.end() ==
- this->TargetFolderBuildStreams.find(folderName)) {
- this->AddFilesUpToPath(
- GetBuildFileStream(), &this->TargetFolderBuildStreams,
- this->GetCMakeInstance()->GetHomeOutputDirectory().c_str(),
- folderName, GhsMultiGpj::PROJECT);
- }
- std::vector<cmsys::String> splitPath = cmSystemTools::SplitString(
- cmGhsMultiTargetGenerator::GetRelBuildFileName(tgt));
- std::string foldNameRelBuildFile(*(splitPath.end() - 2) + "/" +
- splitPath.back());
- *this->TargetFolderBuildStreams[folderName] << foldNameRelBuildFile
- << " ";
- GhsMultiGpj::WriteGpjTag(cmGhsMultiTargetGenerator::GetGpjTag(tgt),
- this->TargetFolderBuildStreams[folderName]);
- }
- }
- }
- bool cmGlobalGhsMultiGenerator::IsTgtForBuild(const cmGeneratorTarget* tgt)
- {
- const std::string config =
- tgt->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
- std::vector<cmSourceFile*> tgtSources;
- tgt->GetSourceFiles(tgtSources, config);
- bool tgtInBuild = true;
- char const* excludeFromAll = tgt->GetProperty("EXCLUDE_FROM_ALL");
- if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
- '\0' == excludeFromAll[1]) {
- tgtInBuild = false;
- }
- return !tgtSources.empty() && tgtInBuild;
- }
- std::string cmGlobalGhsMultiGenerator::trimQuotes(std::string const& str)
- {
- std::string result;
- result.reserve(str.size());
- for (const char* ch = str.c_str(); *ch != '\0'; ++ch) {
- if (*ch != '"') {
- result += *ch;
- }
- }
- return result;
- }
|