/src/CMake/Source/cmLocalCommonGenerator.cxx
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | #include "cmLocalCommonGenerator.h" |
4 | | |
5 | | #include <map> |
6 | | #include <memory> |
7 | | #include <utility> |
8 | | #include <vector> |
9 | | |
10 | | #include <cm/optional> |
11 | | |
12 | | #include "cmGeneratorTarget.h" |
13 | | #include "cmGlobalGenerator.h" |
14 | | #include "cmMakefile.h" |
15 | | #include "cmObjectLocation.h" |
16 | | #include "cmOutputConverter.h" |
17 | | #include "cmStateDirectory.h" |
18 | | #include "cmStateSnapshot.h" |
19 | | #include "cmStringAlgorithms.h" |
20 | | #include "cmValue.h" |
21 | | |
22 | | cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg, |
23 | | cmMakefile* mf) |
24 | 0 | : cmLocalGenerator(gg, mf) |
25 | 0 | { |
26 | | // Multi-config generators define one set of configurations at the top. |
27 | | // Single-config generators nominally define one configuration at the top, |
28 | | // but the implementation has never been strict about that, so look up the |
29 | | // per-directory config to preserve behavior. |
30 | 0 | this->ConfigNames = (gg->IsMultiConfig() && !gg->GetMakefiles().empty() |
31 | 0 | ? gg->GetMakefiles().front().get() |
32 | 0 | : this->Makefile) |
33 | 0 | ->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); |
34 | 0 | } |
35 | | |
36 | 0 | cmLocalCommonGenerator::~cmLocalCommonGenerator() = default; |
37 | | |
38 | | std::string const& cmLocalCommonGenerator::GetWorkingDirectory() const |
39 | 0 | { |
40 | 0 | return this->StateSnapshot.GetDirectory().GetCurrentBinary(); |
41 | 0 | } |
42 | | |
43 | | std::string cmLocalCommonGenerator::GetTargetFortranFlags( |
44 | | cmGeneratorTarget const* target, std::string const& config) |
45 | 0 | { |
46 | 0 | std::string flags; |
47 | | |
48 | | // Enable module output if necessary. |
49 | 0 | this->AppendFlags( |
50 | 0 | flags, this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODOUT_FLAG")); |
51 | | |
52 | | // Add a module output directory flag if necessary. |
53 | 0 | std::string mod_dir = |
54 | 0 | target->GetFortranModuleDirectory(this->GetWorkingDirectory()); |
55 | 0 | if (!mod_dir.empty()) { |
56 | 0 | mod_dir = this->ConvertToOutputFormat( |
57 | 0 | this->MaybeRelativeToWorkDir(mod_dir), cmOutputConverter::SHELL); |
58 | 0 | } else { |
59 | 0 | mod_dir = |
60 | 0 | this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT"); |
61 | 0 | } |
62 | 0 | if (!mod_dir.empty()) { |
63 | 0 | std::string modflag = cmStrCat( |
64 | 0 | this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"), |
65 | 0 | mod_dir); |
66 | 0 | this->AppendFlags(flags, modflag); |
67 | | // Some compilers do not search their own module output directory |
68 | | // for using other modules. Add an include directory explicitly |
69 | | // for consistency with compilers that do search it. |
70 | 0 | std::string incflag = |
71 | 0 | this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_INCLUDE_FLAG"); |
72 | 0 | if (!incflag.empty()) { |
73 | 0 | incflag = cmStrCat(incflag, mod_dir); |
74 | 0 | this->AppendFlags(flags, incflag); |
75 | 0 | } |
76 | 0 | } |
77 | | |
78 | | // If there is a separate module path flag then duplicate the |
79 | | // include path with it. This compiler does not search the include |
80 | | // path for modules. |
81 | 0 | if (cmValue modpath_flag = |
82 | 0 | this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) { |
83 | 0 | std::vector<std::string> includes; |
84 | 0 | this->GetIncludeDirectories(includes, target, "C", config); |
85 | 0 | for (std::string const& id : includes) { |
86 | 0 | std::string flg = |
87 | 0 | cmStrCat(*modpath_flag, |
88 | 0 | this->ConvertToOutputFormat(id, cmOutputConverter::SHELL)); |
89 | 0 | this->AppendFlags(flags, flg); |
90 | 0 | } |
91 | 0 | } |
92 | |
|
93 | 0 | return flags; |
94 | 0 | } |
95 | | |
96 | | std::string cmLocalCommonGenerator::ComputeLongTargetDirectory( |
97 | | cmGeneratorTarget const* target) const |
98 | 0 | { |
99 | 0 | std::string dir = target->GetName(); |
100 | | #if defined(__VMS) |
101 | | dir += "_dir"; |
102 | | #else |
103 | 0 | dir += ".dir"; |
104 | 0 | #endif |
105 | 0 | return dir; |
106 | 0 | } |
107 | | |
108 | | std::string cmLocalCommonGenerator::GetTargetDirectory( |
109 | | cmGeneratorTarget const* target, |
110 | | cmStateEnums::IntermediateDirKind kind) const |
111 | 0 | { |
112 | 0 | if (target->GetUseShortObjectNames(kind)) { |
113 | 0 | return this->ComputeShortTargetDirectory(target); |
114 | 0 | } |
115 | 0 | return this->ComputeLongTargetDirectory(target); |
116 | 0 | } |
117 | | |
118 | | void cmLocalCommonGenerator::ComputeObjectFilenames( |
119 | | std::map<cmSourceFile const*, cmObjectLocations>& mapping, |
120 | | std::string const& config, cmGeneratorTarget const* gt) |
121 | 0 | { |
122 | | // Determine if these object files should use a custom extension |
123 | 0 | char const* custom_ext = gt->GetCustomObjectExtension(); |
124 | 0 | for (auto& si : mapping) { |
125 | 0 | cmSourceFile const* sf = si.first; |
126 | 0 | bool keptSourceExtension; |
127 | 0 | bool force = true; |
128 | 0 | si.second.ShortLoc.emplace(this->GetObjectFileNameWithoutTarget( |
129 | 0 | *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext, &force)); |
130 | 0 | force = false; |
131 | 0 | si.second.LongLoc.Update(this->GetObjectFileNameWithoutTarget( |
132 | 0 | *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext, &force)); |
133 | 0 | this->FillCustomInstallObjectLocations(*sf, config, custom_ext, |
134 | 0 | si.second.InstallLongLoc); |
135 | 0 | } |
136 | 0 | } |