1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #include "cmLocalCommonGenerator.h"
4 
5 #include <utility>
6 #include <vector>
7 
8 #include "cmGeneratorTarget.h"
9 #include "cmMakefile.h"
10 #include "cmOutputConverter.h"
11 #include "cmState.h"
12 #include "cmStateDirectory.h"
13 #include "cmStateSnapshot.h"
14 #include "cmStringAlgorithms.h"
15 #include "cmValue.h"
16 
17 class cmGlobalGenerator;
18 
cmLocalCommonGenerator(cmGlobalGenerator * gg,cmMakefile * mf,WorkDir wd)19 cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
20                                                cmMakefile* mf, WorkDir wd)
21   : cmLocalGenerator(gg, mf)
22   , WorkingDirectory(wd)
23 {
24   this->ConfigNames =
25     this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
26 }
27 
28 cmLocalCommonGenerator::~cmLocalCommonGenerator() = default;
29 
GetWorkingDirectory() const30 std::string const& cmLocalCommonGenerator::GetWorkingDirectory() const
31 {
32   if (this->WorkingDirectory == WorkDir::TopBin) {
33     return this->GetState()->GetBinaryDirectory();
34   }
35   return this->StateSnapshot.GetDirectory().GetCurrentBinary();
36 }
37 
MaybeRelativeToWorkDir(std::string const & path) const38 std::string cmLocalCommonGenerator::MaybeRelativeToWorkDir(
39   std::string const& path) const
40 {
41   if (this->WorkingDirectory == WorkDir::TopBin) {
42     return this->MaybeRelativeToTopBinDir(path);
43   }
44   return this->MaybeRelativeToCurBinDir(path);
45 }
46 
GetTargetFortranFlags(cmGeneratorTarget const * target,std::string const & config)47 std::string cmLocalCommonGenerator::GetTargetFortranFlags(
48   cmGeneratorTarget const* target, std::string const& config)
49 {
50   std::string flags;
51 
52   // Enable module output if necessary.
53   this->AppendFlags(
54     flags, this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODOUT_FLAG"));
55 
56   // Add a module output directory flag if necessary.
57   std::string mod_dir =
58     target->GetFortranModuleDirectory(this->GetWorkingDirectory());
59   if (!mod_dir.empty()) {
60     mod_dir = this->ConvertToOutputFormat(
61       this->MaybeRelativeToWorkDir(mod_dir), cmOutputConverter::SHELL);
62   } else {
63     mod_dir =
64       this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
65   }
66   if (!mod_dir.empty()) {
67     std::string modflag = cmStrCat(
68       this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"),
69       mod_dir);
70     this->AppendFlags(flags, modflag);
71     // Some compilers do not search their own module output directory
72     // for using other modules.  Add an include directory explicitly
73     // for consistency with compilers that do search it.
74     std::string incflag =
75       this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_INCLUDE_FLAG");
76     if (!incflag.empty()) {
77       incflag = cmStrCat(incflag, mod_dir);
78       this->AppendFlags(flags, incflag);
79     }
80   }
81 
82   // If there is a separate module path flag then duplicate the
83   // include path with it.  This compiler does not search the include
84   // path for modules.
85   if (cmValue modpath_flag =
86         this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) {
87     std::vector<std::string> includes;
88     this->GetIncludeDirectories(includes, target, "C", config);
89     for (std::string const& id : includes) {
90       std::string flg =
91         cmStrCat(*modpath_flag,
92                  this->ConvertToOutputFormat(id, cmOutputConverter::SHELL));
93       this->AppendFlags(flags, flg);
94     }
95   }
96 
97   return flags;
98 }
99 
ComputeObjectFilenames(std::map<cmSourceFile const *,std::string> & mapping,cmGeneratorTarget const * gt)100 void cmLocalCommonGenerator::ComputeObjectFilenames(
101   std::map<cmSourceFile const*, std::string>& mapping,
102   cmGeneratorTarget const* gt)
103 {
104   // Determine if these object files should use a custom extension
105   char const* custom_ext = gt->GetCustomObjectExtension();
106   for (auto& si : mapping) {
107     cmSourceFile const* sf = si.first;
108     bool keptSourceExtension;
109     si.second = this->GetObjectFileNameWithoutTarget(
110       *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext);
111   }
112 }
113