diff options
author | Brad King <brad.king@kitware.com> | 2020-09-14 15:52:31 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-09-18 16:49:17 (GMT) |
commit | 2db623f554d5522350214a7c5bacd5ec2dec1b34 (patch) | |
tree | 27da28d96274f726e195d216199fd949005a0930 /Source | |
parent | 3ab18c870dc00499f33a40a193e95cc4e1df54ba (diff) | |
download | CMake-2db623f554d5522350214a7c5bacd5ec2dec1b34.zip CMake-2db623f554d5522350214a7c5bacd5ec2dec1b34.tar.gz CMake-2db623f554d5522350214a7c5bacd5ec2dec1b34.tar.bz2 |
Xcode: Add option to specify build system variant
Extend the `-T <toolset>` option to support a `buildsystem=` field with
the Xcode generator. Add a `CMAKE_XCODE_BUILD_SYSTEM` variable to
inform project code about the selected build system variant.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 115 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.h | 11 |
2 files changed, 114 insertions, 12 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index be4f9ad..cceaea0 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -8,6 +8,7 @@ #include <cstring> #include <iomanip> #include <sstream> +#include <unordered_set> #include <utility> #include <cm/memory> @@ -280,32 +281,122 @@ bool cmGlobalXCodeGenerator::SetSystemName(std::string const& s, return this->cmGlobalGenerator::SetSystemName(s, mf); } +namespace { +cm::string_view cmXcodeBuildSystemString(cmGlobalXCodeGenerator::BuildSystem b) +{ + switch (b) { + case cmGlobalXCodeGenerator::BuildSystem::One: + return "1"_s; + } + return {}; +} +} + bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts, bool build, cmMakefile* mf) { - if (ts.find_first_of(",=") != std::string::npos) { - std::ostringstream e; - /* clang-format off */ - e << - "Generator\n" - " " << this->GetName() << "\n" - "does not recognize the toolset\n" - " " << ts << "\n" - "that was specified."; - /* clang-format on */ - mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); + if (!this->ParseGeneratorToolset(ts, mf)) { return false; } - this->GeneratorToolset = ts; if (build) { return true; } if (!this->GeneratorToolset.empty()) { mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET", this->GeneratorToolset); } + mf->AddDefinition("CMAKE_XCODE_BUILD_SYSTEM", + cmXcodeBuildSystemString(this->XcodeBuildSystem)); return true; } +bool cmGlobalXCodeGenerator::ParseGeneratorToolset(std::string const& ts, + cmMakefile* mf) +{ + std::vector<std::string> const fields = cmTokenize(ts, ","); + auto fi = fields.cbegin(); + if (fi == fields.cend()) { + return true; + } + + // The first field may be the Xcode GCC_VERSION. + if (fi->find('=') == fi->npos) { + this->GeneratorToolset = *fi; + ++fi; + } + + std::unordered_set<std::string> handled; + + // The rest of the fields must be key=value pairs. + for (; fi != fields.cend(); ++fi) { + std::string::size_type pos = fi->find('='); + if (pos == fi->npos) { + /* clang-format off */ + std::string const& e = cmStrCat( + "Generator\n" + " ", this->GetName(), "\n" + "given toolset specification\n" + " ", ts, "\n" + "that contains a field after the first ',' with no '='." + ); + /* clang-format on */ + mf->IssueMessage(MessageType::FATAL_ERROR, e); + return false; + } + std::string const key = fi->substr(0, pos); + std::string const value = fi->substr(pos + 1); + if (!handled.insert(key).second) { + /* clang-format off */ + std::string const& e = cmStrCat( + "Generator\n" + " ", this->GetName(), "\n" + "given toolset specification\n" + " ", ts, "\n" + "that contains duplicate field key '", key, "'." + ); + /* clang-format on */ + mf->IssueMessage(MessageType::FATAL_ERROR, e); + return false; + } + if (!this->ProcessGeneratorToolsetField(key, value, mf)) { + return false; + } + } + + return true; +} + +bool cmGlobalXCodeGenerator::ProcessGeneratorToolsetField( + std::string const& key, std::string const& value, cmMakefile* mf) +{ + if (key == "buildsystem") { + if (value == "1"_s) { + this->XcodeBuildSystem = BuildSystem::One; + } else { + /* clang-format off */ + std::string const& e = cmStrCat( + "Generator\n" + " ", this->GetName(), "\n" + "toolset specification field\n" + " buildsystem=", value, "\n" + "value is unkonwn. It must be '1'." + ); + /* clang-format on */ + mf->IssueMessage(MessageType::FATAL_ERROR, e); + return false; + } + return true; + } + /* clang-format off */ + std::string const& e = cmStrCat( + "Generator\n" + " ", this->GetName(), "\n" + "given toolset specification that contains invalid field '", key, "'." + ); + /* clang-format on */ + mf->IssueMessage(MessageType::FATAL_ERROR, e); + return false; +} + void cmGlobalXCodeGenerator::EnableLanguage( std::vector<std::string> const& lang, cmMakefile* mf, bool optional) { diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 4e68682..bbf3ee9 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -113,11 +113,20 @@ public: cmMakefile* mf) override; void AppendFlag(std::string& flags, std::string const& flag) const; + enum class BuildSystem + { + One = 1, + }; + protected: void AddExtraIDETargets() override; void Generate() override; private: + bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf); + bool ProcessGeneratorToolsetField(std::string const& key, + std::string const& value, cmMakefile* mf); + cmXCodeObject* CreateOrGetPBXGroup(cmGeneratorTarget* gtgt, cmSourceGroup* sg); cmXCodeObject* CreatePBXGroup(cmXCodeObject* parent, @@ -254,6 +263,8 @@ protected: std::vector<std::unique_ptr<cmXCodeObject>> XCodeObjects; cmXCodeObject* RootObject; + BuildSystem XcodeBuildSystem = BuildSystem::One; + private: std::string const& GetXcodeBuildCommand(); std::string FindXcodeBuildCommand(); |