| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #include "cmLocalCommonGenerator.h" | |
| #include <map> | |
| #include <memory> | |
| #include <utility> | |
| #include <vector> | |
| #include <cm/optional> | |
| #include "cmGeneratorTarget.h" | |
| #include "cmGlobalGenerator.h" | |
| #include "cmMakefile.h" | |
| #include "cmObjectLocation.h" | |
| #include "cmOutputConverter.h" | |
| #include "cmStateDirectory.h" | |
| #include "cmStateSnapshot.h" | |
| #include "cmStringAlgorithms.h" | |
| #include "cmValue.h" | |
| cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg, | |
| cmMakefile* mf) | |
| : cmLocalGenerator(gg, mf) | |
| { | |
| // Multi-config generators define one set of configurations at the top. | |
| // Single-config generators nominally define one configuration at the top, | |
| // but the implementation has never been strict about that, so look up the | |
| // per-directory config to preserve behavior. | |
| this->ConfigNames = (gg->IsMultiConfig() && !gg->GetMakefiles().empty() | |
| ? gg->GetMakefiles().front().get() | |
| : this->Makefile) | |
| ->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); | |
| } | |
| cmLocalCommonGenerator::~cmLocalCommonGenerator() = default; | |
| std::string const& cmLocalCommonGenerator::GetWorkingDirectory() const | |
| { | |
| return this->StateSnapshot.GetDirectory().GetCurrentBinary(); | |
| } | |
| std::string cmLocalCommonGenerator::GetTargetFortranFlags( | |
| cmGeneratorTarget const* target, std::string const& config) | |
| { | |
| std::string flags; | |
| // Enable module output if necessary. | |
| this->AppendFlags( | |
| flags, this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODOUT_FLAG")); | |
| // Add a module output directory flag if necessary. | |
| std::string mod_dir = | |
| target->GetFortranModuleDirectory(this->GetWorkingDirectory()); | |
| if (!mod_dir.empty()) { | |
| mod_dir = this->ConvertToOutputFormat( | |
| this->MaybeRelativeToWorkDir(mod_dir), cmOutputConverter::SHELL); | |
| } else { | |
| mod_dir = | |
| this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT"); | |
| } | |
| if (!mod_dir.empty()) { | |
| std::string modflag = cmStrCat( | |
| this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"), | |
| mod_dir); | |
| this->AppendFlags(flags, modflag); | |
| // Some compilers do not search their own module output directory | |
| // for using other modules. Add an include directory explicitly | |
| // for consistency with compilers that do search it. | |
| std::string incflag = | |
| this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_INCLUDE_FLAG"); | |
| if (!incflag.empty()) { | |
| incflag = cmStrCat(std::move(incflag), mod_dir); | |
| this->AppendFlags(flags, incflag); | |
| } | |
| } | |
| // If there is a separate module path flag then duplicate the | |
| // include path with it. This compiler does not search the include | |
| // path for modules. | |
| if (cmValue modpath_flag = | |
| this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) { | |
| std::vector<std::string> includes; | |
| this->GetIncludeDirectories(includes, target, "C", config); | |
| for (std::string const& id : includes) { | |
| std::string flg = | |
| cmStrCat(*modpath_flag, | |
| this->ConvertToOutputFormat(id, cmOutputConverter::SHELL)); | |
| this->AppendFlags(flags, flg); | |
| } | |
| } | |
| return flags; | |
| } | |
| std::string cmLocalCommonGenerator::ComputeLongTargetDirectory( | |
| cmGeneratorTarget const* target) const | |
| { | |
| std::string dir = target->GetName(); | |
| #if defined(__VMS) | |
| dir += "_dir"; | |
| #else | |
| dir += ".dir"; | |
| #endif | |
| return dir; | |
| } | |
| std::string cmLocalCommonGenerator::GetTargetDirectory( | |
| cmGeneratorTarget const* target, | |
| cmStateEnums::IntermediateDirKind kind) const | |
| { | |
| if (target->GetUseShortObjectNames(kind)) { | |
| return this->ComputeShortTargetDirectory(target); | |
| } | |
| return this->ComputeLongTargetDirectory(target); | |
| } | |
| void cmLocalCommonGenerator::ComputeObjectFilenames( | |
| std::map<cmSourceFile const*, cmObjectLocations>& mapping, | |
| std::string const& config, cmGeneratorTarget const* gt) | |
| { | |
| // Determine if these object files should use a custom extension | |
| char const* custom_ext = gt->GetCustomObjectExtension(); | |
| for (auto& si : mapping) { | |
| cmSourceFile const* sf = si.first; | |
| bool keptSourceExtension; | |
| bool force = true; | |
| si.second.ShortLoc.emplace(this->GetObjectFileNameWithoutTarget( | |
| *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext, &force)); | |
| force = false; | |
| si.second.LongLoc.Update(this->GetObjectFileNameWithoutTarget( | |
| *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext, &force)); | |
| this->FillCustomInstallObjectLocations(*sf, config, custom_ext, | |
| si.second.InstallLongLoc); | |
| } | |
| } |