From ad9020a89922eff4b817ba6278d31a412cc17601 Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Wed, 10 May 2023 11:40:37 +0200 Subject: Apple Frameworks: honor SYSTEM target property Fixes: #24109 --- Help/release/dev/System-Framework.rst | 4 +++ Source/cmGeneratorTarget.cxx | 41 +++++++++++++++------- Source/cmGlobalXCodeGenerator.cxx | 4 +-- Source/cmLinkLineComputer.cxx | 20 +++++++---- Source/cmLinkLineComputer.h | 4 ++- Source/cmLocalGenerator.cxx | 40 +++++++++++---------- .../Framework/FrameworkSystemIncludeTest.cmake | 12 +++++++ 7 files changed, 84 insertions(+), 41 deletions(-) create mode 100644 Help/release/dev/System-Framework.rst diff --git a/Help/release/dev/System-Framework.rst b/Help/release/dev/System-Framework.rst new file mode 100644 index 0000000..106cf23 --- /dev/null +++ b/Help/release/dev/System-Framework.rst @@ -0,0 +1,4 @@ +System-Framework +---------------- + +* The :prop_tgt:`SYSTEM` target property is now honored for Apple Frameworks. diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 28ba60f..32f0cbd 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -794,6 +794,15 @@ void handleSystemIncludesDep(cmLocalGenerator* lg, result.append(cmGeneratorExpression::Evaluate( *dirs, lg, config, headTarget, dagChecker, depTgt, language)); } + + if (depTgt->Target->IsFrameworkOnApple()) { + if (auto fwDescriptor = depTgt->GetGlobalGenerator()->SplitFrameworkPath( + depTgt->GetLocation(config), + cmGlobalGenerator::FrameworkFormat::Strict)) { + result.push_back(fwDescriptor->Directory); + result.push_back(fwDescriptor->GetFrameworkPath()); + } + } } } @@ -3819,32 +3828,38 @@ std::vector> cmGeneratorTarget::GetIncludeDirectories( AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang, &dagChecker, entries, IncludeRuntimeInterface::Yes); + processIncludeDirectories(this, entries, includes, uniqueIncludes, + debugIncludes); + if (this->IsApple()) { if (cmLinkImplementationLibraries const* impl = this->GetLinkImplementationLibraries(config, LinkInterfaceFor::Usage)) { for (cmLinkImplItem const& lib : impl->Libraries) { - std::string libDir = cmSystemTools::CollapseFullPath( - lib.AsStr(), this->Makefile->GetHomeOutputDirectory()); - - static cmsys::RegularExpression frameworkCheck( - "(.*\\.framework)(/Versions/[^/]+)?/[^/]+$"); - if (!frameworkCheck.find(libDir)) { + std::string libDir; + if (lib.Target == nullptr) { + libDir = cmSystemTools::CollapseFullPath( + lib.AsStr(), this->Makefile->GetHomeOutputDirectory()); + } else if (lib.Target->Target->IsFrameworkOnApple()) { + libDir = lib.Target->GetLocation(config); + } else { continue; } - libDir = frameworkCheck.match(1); + auto fwDescriptor = + this->GetGlobalGenerator()->SplitFrameworkPath(libDir); + if (!fwDescriptor) { + continue; + } - EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace()); - ee.Values.emplace_back(std::move(libDir)); - entries.Entries.emplace_back(std::move(ee)); + auto fwInclude = fwDescriptor->GetFrameworkPath(); + if (uniqueIncludes.insert(fwInclude).second) { + includes.emplace_back(fwInclude, cmListFileBacktrace()); + } } } } - processIncludeDirectories(this, entries, includes, uniqueIncludes, - debugIncludes); - this->IncludeDirectoriesCache.emplace(cacheKey, includes); return includes; } diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 60f46e5..110933e 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -2765,7 +2765,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, if (emitted.insert(frameworkDir).second) { std::string incpath = this->XCodeEscapePath(frameworkDir); if (emitSystemIncludes && - gtgt->IsSystemIncludeDirectory(include, configName, + gtgt->IsSystemIncludeDirectory(frameworkDir, configName, langForIncludes)) { sysfdirs.Add(incpath); } else { @@ -3910,8 +3910,6 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target) // otherwise we end up hard-coding a path to the wrong SDK for // SDK-provided frameworks that are added by their full path. std::set emitted(cli->GetFrameworkPathsEmitted()); - const auto& fwPaths = cli->GetFrameworkPaths(); - emitted.insert(fwPaths.begin(), fwPaths.end()); BuildObjectListOrString libPaths(this, true); BuildObjectListOrString fwSearchPaths(this, true); for (auto const& libItem : configItemMap[configName]) { diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx index ba0c138..b7ee4fa 100644 --- a/Source/cmLinkLineComputer.cxx +++ b/Source/cmLinkLineComputer.cxx @@ -191,16 +191,24 @@ std::string cmLinkLineComputer::ComputeRPath(cmComputeLinkInformation& cli) } std::string cmLinkLineComputer::ComputeFrameworkPath( - cmComputeLinkInformation& cli, std::string const& fwSearchFlag) + cmComputeLinkInformation& cli, cmValue fwSearchFlag, cmValue sysFwSearchFlag) { + if (!fwSearchFlag && !sysFwSearchFlag) { + return std::string{}; + } + std::string frameworkPath; - if (!fwSearchFlag.empty()) { - std::vector const& fwDirs = cli.GetFrameworkPaths(); - for (std::string const& fd : fwDirs) { + auto const& fwDirs = cli.GetFrameworkPaths(); + for (auto const& fd : fwDirs) { + if (sysFwSearchFlag && + cli.GetTarget()->IsSystemIncludeDirectory(fd, cli.GetConfig(), + cli.GetLinkLanguage())) { + frameworkPath += sysFwSearchFlag; + } else { frameworkPath += fwSearchFlag; - frameworkPath += this->ConvertToOutputFormat(fd); - frameworkPath += " "; } + frameworkPath += this->ConvertToOutputFormat(fd); + frameworkPath += " "; } return frameworkPath; } diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h index 9fb222c..4e285f2 100644 --- a/Source/cmLinkLineComputer.h +++ b/Source/cmLinkLineComputer.h @@ -9,6 +9,7 @@ #include #include "cmStateDirectory.h" +#include "cmValue.h" class cmComputeLinkInformation; class cmGeneratorTarget; @@ -43,7 +44,8 @@ public: std::vector>& linkPath); std::string ComputeFrameworkPath(cmComputeLinkInformation& cli, - std::string const& fwSearchFlag); + cmValue fwSearchFlag, + cmValue sysFwSearchFlag); std::string ComputeLinkLibraries(cmComputeLinkInformation& cli, std::string const& stdLibString); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 4089fd4..63b2043 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -914,7 +914,7 @@ std::string cmLocalGenerator::GetIncludeFlags( cmSystemTools::CollapseFullPath(cmStrCat(i, "/../")); if (emitted.insert(frameworkDir).second) { if (sysFwSearchFlag && target && - target->IsSystemIncludeDirectory(i, config, lang)) { + target->IsSystemIncludeDirectory(frameworkDir, config, lang)) { includeFlags << *sysFwSearchFlag; } else { includeFlags << *fwSearchFlag; @@ -1645,9 +1645,9 @@ std::vector> cmLocalGenerator::GetTargetCompileFlags( return flags; } -static std::string GetFrameworkFlags(const std::string& lang, - const std::string& config, - cmGeneratorTarget* target) +std::string cmLocalGenerator::GetFrameworkFlags(std::string const& lang, + std::string const& config, + cmGeneratorTarget* target) { cmLocalGenerator* lg = target->GetLocalGenerator(); cmMakefile* mf = lg->GetMakefile(); @@ -1656,10 +1656,13 @@ static std::string GetFrameworkFlags(const std::string& lang, return std::string(); } - std::string fwSearchFlagVar = "CMAKE_" + lang + "_FRAMEWORK_SEARCH_FLAG"; - cmValue fwSearchFlag = mf->GetDefinition(fwSearchFlagVar); - if (!cmNonempty(fwSearchFlag)) { - return std::string(); + cmValue fwSearchFlag = + mf->GetDefinition(cmStrCat("CMAKE_", lang, "_FRAMEWORK_SEARCH_FLAG")); + cmValue sysFwSearchFlag = mf->GetDefinition( + cmStrCat("CMAKE_", lang, "_SYSTEM_FRAMEWORK_SEARCH_FLAG")); + + if (!fwSearchFlag && !sysFwSearchFlag) { + return std::string{}; } std::set emitted; @@ -1684,7 +1687,12 @@ static std::string GetFrameworkFlags(const std::string& lang, std::vector const& frameworks = cli->GetFrameworkPaths(); for (std::string const& framework : frameworks) { if (emitted.insert(framework).second) { - flags += *fwSearchFlag; + if (sysFwSearchFlag && + target->IsSystemIncludeDirectory(framework, config, lang)) { + flags += *sysFwSearchFlag; + } else { + flags += *fwSearchFlag; + } flags += lg->ConvertToOutputFormat(framework, cmOutputConverter::SHELL); flags += " "; @@ -1694,13 +1702,6 @@ static std::string GetFrameworkFlags(const std::string& lang, return flags; } -std::string cmLocalGenerator::GetFrameworkFlags(std::string const& l, - std::string const& config, - cmGeneratorTarget* target) -{ - return ::GetFrameworkFlags(l, config, target); -} - void cmLocalGenerator::GetTargetDefines(cmGeneratorTarget const* target, std::string const& config, std::string const& lang, @@ -1788,10 +1789,13 @@ void cmLocalGenerator::OutputLinkLibraries( cmStrCat("CMAKE_", cli.GetLinkLanguage(), "_STANDARD_LIBRARIES")); // Append the framework search path flags. - std::string fwSearchFlag = this->Makefile->GetSafeDefinition( + cmValue fwSearchFlag = this->Makefile->GetDefinition( cmStrCat("CMAKE_", linkLanguage, "_FRAMEWORK_SEARCH_FLAG")); + cmValue sysFwSearchFlag = this->Makefile->GetDefinition( + cmStrCat("CMAKE_", linkLanguage, "_SYSTEM_FRAMEWORK_SEARCH_FLAG")); - frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag); + frameworkPath = + linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag, sysFwSearchFlag); linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator, linkPath); linkLineComputer->ComputeLinkLibraries(cli, stdLibString, linkLibraries); diff --git a/Tests/RunCMake/Framework/FrameworkSystemIncludeTest.cmake b/Tests/RunCMake/Framework/FrameworkSystemIncludeTest.cmake index d172281..bcf6c29 100644 --- a/Tests/RunCMake/Framework/FrameworkSystemIncludeTest.cmake +++ b/Tests/RunCMake/Framework/FrameworkSystemIncludeTest.cmake @@ -10,3 +10,15 @@ set_target_properties(Example::Example PROPERTIES add_library(testcase FrameworkSystemIncludeTest.c) target_compile_options(testcase PRIVATE "-Werror=#pragma-messages") target_link_libraries(testcase PRIVATE Example::Example) + + + +add_library(Example::Example2 SHARED IMPORTED) +set_target_properties(Example::Example2 PROPERTIES + FRAMEWORK 1 + IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/subdir/Example.framework/Example.tbd" +) + +add_library(testcase2 FrameworkSystemIncludeTest.c) +target_compile_options(testcase2 PRIVATE "-Werror=#pragma-messages") +target_link_libraries(testcase2 PRIVATE Example::Example2) -- cgit v0.12