1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00
Files
CMake/Source/cmLocalXCodeGenerator.cxx
Ben Boeckel fe0163cd23 autogen: compute short directories too
Not just short directory roots. The test suites did an improper
generator check and masked them as the generator masks were put in place
after the core development but before the autogen-specific logic tests
were created.
2025-09-02 12:56:23 -04:00

165 lines
5.3 KiB
C++

/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmLocalXCodeGenerator.h"
#include <memory>
#include <ostream>
#include <utility>
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalXCodeGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmGlobalGenerator;
cmLocalXCodeGenerator::cmLocalXCodeGenerator(cmGlobalGenerator* gg,
cmMakefile* mf)
: cmLocalGenerator(gg, mf)
{
// the global generator does this, so do not
// put these flags into the language flags
this->EmitUniversalBinaryFlags = false;
}
cmLocalXCodeGenerator::~cmLocalXCodeGenerator() = default;
std::string cmLocalXCodeGenerator::GetTargetDirectory(
cmGeneratorTarget const* target,
cmStateEnums::IntermediateDirKind /*kind*/) const
{
return cmStrCat(target->GetName(), ".dir");
}
void cmLocalXCodeGenerator::AppendFlagEscape(std::string& flags,
std::string const& rawFlag) const
{
cmGlobalXCodeGenerator const* gg =
static_cast<cmGlobalXCodeGenerator const*>(this->GlobalGenerator);
gg->AppendFlag(flags, rawFlag);
}
void cmLocalXCodeGenerator::Generate()
{
cmLocalGenerator::Generate();
for (auto const& target : this->GetGeneratorTargets()) {
target->HasMacOSXRpathInstallNameDir("");
}
}
void cmLocalXCodeGenerator::AddGeneratorSpecificInstallSetup(std::ostream& os)
{
// First check if we need to warn about incompatible settings
for (auto const& target : this->GetGeneratorTargets()) {
target->HasMacOSXRpathInstallNameDir("");
}
// CMakeIOSInstallCombined.cmake needs to know the location of the top of
// the build directory
os << "set(CMAKE_BINARY_DIR \"" << this->GetBinaryDirectory() << "\")\n\n";
if (this->Makefile->PlatformIsAppleEmbedded()) {
std::string platformName;
switch (this->Makefile->GetAppleSDKType()) {
case cmMakefile::AppleSDK::IPhoneOS:
platformName = "iphoneos";
break;
case cmMakefile::AppleSDK::IPhoneSimulator:
platformName = "iphonesimulator";
break;
case cmMakefile::AppleSDK::AppleTVOS:
platformName = "appletvos";
break;
case cmMakefile::AppleSDK::AppleTVSimulator:
platformName = "appletvsimulator";
break;
case cmMakefile::AppleSDK::WatchOS:
platformName = "watchos";
break;
case cmMakefile::AppleSDK::WatchSimulator:
platformName = "watchsimulator";
break;
case cmMakefile::AppleSDK::XROS:
platformName = "xros";
break;
case cmMakefile::AppleSDK::XRSimulator:
platformName = "xrsimulator";
break;
case cmMakefile::AppleSDK::MacOS:
break;
}
if (!platformName.empty()) {
// The effective platform name is just the platform name with a hyphen
// prepended. We can get the SUPPORTED_PLATFORMS from the project file
// at runtime, so we don't need to compute that here.
/* clang-format off */
os <<
"if(NOT PLATFORM_NAME)\n"
" if(NOT \"$ENV{PLATFORM_NAME}\" STREQUAL \"\")\n"
" set(PLATFORM_NAME \"$ENV{PLATFORM_NAME}\")\n"
" endif()\n"
" if(NOT PLATFORM_NAME)\n"
" set(PLATFORM_NAME " << platformName << ")\n"
" endif()\n"
"endif()\n\n"
"if(NOT EFFECTIVE_PLATFORM_NAME)\n"
" if(NOT \"$ENV{EFFECTIVE_PLATFORM_NAME}\" STREQUAL \"\")\n"
" set(EFFECTIVE_PLATFORM_NAME \"$ENV{EFFECTIVE_PLATFORM_NAME}\")\n"
" endif()\n"
" if(NOT EFFECTIVE_PLATFORM_NAME)\n"
" set(EFFECTIVE_PLATFORM_NAME -" << platformName << ")\n"
" endif()\n"
"endif()\n\n";
/* clang-format off */
}
}
}
void cmLocalXCodeGenerator::ComputeObjectFilenames(
std::map<cmSourceFile const*, cmObjectLocations>& mapping,
cmGeneratorTarget const*)
{
// Count the number of object files with each name. Warn about duplicate
// names since Xcode names them uniquely automatically with a numeric suffix
// to avoid exact duplicate file names. Note that Mac file names are not
// typically case sensitive, hence the LowerCase.
std::map<std::string, int> counts;
for (auto& si : mapping) {
cmSourceFile const* sf = si.first;
std::string shortObjectName = this->GetShortObjectFileName(*sf);
std::string longObjectName = cmStrCat(
cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()), ".o");
std::string longObjectNameLower = cmSystemTools::LowerCase(longObjectName);
counts[longObjectNameLower] += 1;
if (2 == counts[longObjectNameLower]) {
// TODO: emit warning about duplicate name?
}
si.second.ShortLoc.emplace(shortObjectName);
si.second.LongLoc.Update(longObjectName);
}
}
void cmLocalXCodeGenerator::AddXCConfigSources(cmGeneratorTarget* target)
{
auto xcconfig = target->GetProperty("XCODE_XCCONFIG");
if (!xcconfig) {
return;
}
auto configs = target->Makefile->GetGeneratorConfigs(
cmMakefile::IncludeEmptyConfig);
for (auto& config : configs) {
auto file = cmGeneratorExpression::Evaluate(
*xcconfig,
this, config);
if (!file.empty()) {
target->AddSource(file);
}
}
}