resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmLocalXCodeGenerator.cxx
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 "cmLocalXCodeGenerator.h"
4
5 #include <memory>
6 #include <ostream>
7 #include <utility>
8
9 #include "cmGeneratorExpression.h"
10 #include "cmGeneratorTarget.h"
11 #include "cmGlobalXCodeGenerator.h"
12 #include "cmMakefile.h"
13 #include "cmSourceFile.h"
14 #include "cmStringAlgorithms.h"
15 #include "cmSystemTools.h"
16
17 class cmGlobalGenerator;
18
19 cmLocalXCodeGenerator::cmLocalXCodeGenerator(cmGlobalGenerator* gg,
20                                              cmMakefile* mf)
21   : cmLocalGenerator(gg, mf)
22 {
23   // the global generator does this, so do not
24   // put these flags into the language flags
25   this->EmitUniversalBinaryFlags = false;
26 }
27
28 cmLocalXCodeGenerator::~cmLocalXCodeGenerator() = default;
29
30 std::string cmLocalXCodeGenerator::GetTargetDirectory(
31   cmGeneratorTarget const*) const
32 {
33   // No per-target directory for this generator (yet).
34   return "";
35 }
36
37 void cmLocalXCodeGenerator::AppendFlagEscape(std::string& flags,
38                                              const std::string& rawFlag) const
39 {
40   const cmGlobalXCodeGenerator* gg =
41     static_cast<const cmGlobalXCodeGenerator*>(this->GlobalGenerator);
42   gg->AppendFlag(flags, rawFlag);
43 }
44
45 void cmLocalXCodeGenerator::Generate()
46 {
47   cmLocalGenerator::Generate();
48
49   for (const auto& target : this->GetGeneratorTargets()) {
50     target->HasMacOSXRpathInstallNameDir("");
51   }
52 }
53
54 void cmLocalXCodeGenerator::AddGeneratorSpecificInstallSetup(std::ostream& os)
55 {
56   // First check if we need to warn about incompatible settings
57   for (const auto& target : this->GetGeneratorTargets()) {
58     target->HasMacOSXRpathInstallNameDir("");
59   }
60
61   // CMakeIOSInstallCombined.cmake needs to know the location of the top of
62   // the build directory
63   os << "set(CMAKE_BINARY_DIR \"" << this->GetBinaryDirectory() << "\")\n\n";
64
65   if (this->Makefile->PlatformIsAppleEmbedded()) {
66     std::string platformName;
67     switch (this->Makefile->GetAppleSDKType()) {
68       case cmMakefile::AppleSDK::IPhoneOS:
69         platformName = "iphoneos";
70         break;
71       case cmMakefile::AppleSDK::IPhoneSimulator:
72         platformName = "iphonesimulator";
73         break;
74       case cmMakefile::AppleSDK::AppleTVOS:
75         platformName = "appletvos";
76         break;
77       case cmMakefile::AppleSDK::AppleTVSimulator:
78         platformName = "appletvsimulator";
79         break;
80       case cmMakefile::AppleSDK::WatchOS:
81         platformName = "watchos";
82         break;
83       case cmMakefile::AppleSDK::WatchSimulator:
84         platformName = "watchsimulator";
85         break;
86       case cmMakefile::AppleSDK::MacOS:
87         break;
88     }
89     if (!platformName.empty()) {
90       // The effective platform name is just the platform name with a hyphen
91       // prepended. We can get the SUPPORTED_PLATFORMS from the project file
92       // at runtime, so we don't need to compute that here.
93       /* clang-format off */
94       os <<
95         "if(NOT PLATFORM_NAME)\n"
96         "  if(NOT \"$ENV{PLATFORM_NAME}\" STREQUAL \"\")\n"
97         "    set(PLATFORM_NAME \"$ENV{PLATFORM_NAME}\")\n"
98         "  endif()\n"
99         "  if(NOT PLATFORM_NAME)\n"
100         "    set(PLATFORM_NAME " << platformName << ")\n"
101         "  endif()\n"
102         "endif()\n\n"
103         "if(NOT EFFECTIVE_PLATFORM_NAME)\n"
104         "  if(NOT \"$ENV{EFFECTIVE_PLATFORM_NAME}\" STREQUAL \"\")\n"
105         "    set(EFFECTIVE_PLATFORM_NAME \"$ENV{EFFECTIVE_PLATFORM_NAME}\")\n"
106         "  endif()\n"
107         "  if(NOT EFFECTIVE_PLATFORM_NAME)\n"
108         "    set(EFFECTIVE_PLATFORM_NAME -" << platformName << ")\n"
109         "  endif()\n"
110         "endif()\n\n";
111       /* clang-format off */
112     }
113   }
114 }
115
116 void cmLocalXCodeGenerator::ComputeObjectFilenames(
117   std::map<cmSourceFile const*, std::string>& mapping,
118   cmGeneratorTarget const*)
119 {
120   // Count the number of object files with each name. Warn about duplicate
121   // names since Xcode names them uniquely automatically with a numeric suffix
122   // to avoid exact duplicate file names. Note that Mac file names are not
123   // typically case sensitive, hence the LowerCase.
124   std::map<std::string, int> counts;
125   for (auto& si : mapping) {
126     cmSourceFile const* sf = si.first;
127     std::string objectName = cmStrCat(
128       cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()), ".o");
129
130     std::string objectNameLower = cmSystemTools::LowerCase(objectName);
131     counts[objectNameLower] += 1;
132     if (2 == counts[objectNameLower]) {
133       // TODO: emit warning about duplicate name?
134     }
135     si.second = objectName;
136   }
137 }
138
139 void cmLocalXCodeGenerator::AddXCConfigSources(cmGeneratorTarget* target)
140 {
141   auto xcconfig = target->GetProperty("XCODE_XCCONFIG");
142   if (!xcconfig) {
143     return;
144   }
145   auto configs = target->Makefile->GetGeneratorConfigs(
146                           cmMakefile::IncludeEmptyConfig);
147
148   for (auto& config : configs) {
149     auto file = cmGeneratorExpression::Evaluate(
150       xcconfig,
151       this, config);
152     if (!file.empty()) {
153       target->AddSource(file);
154     }
155   }
156 }