mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00

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.
165 lines
5.3 KiB
C++
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);
|
|
}
|
|
}
|
|
}
|