summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2021-02-04 13:18:13 +0000
committerKitware Robot <kwrobot@kitware.com>2021-02-04 08:18:20 -0500
commit7b9ea201fc5f8110e0f8478d8dc3715030a406b5 (patch)
tree63ce9f8dfde26812aaea8584520f4b9984896dc9
parentc131afc190d69f605c83391d12dde142f481a698 (diff)
parent5389bb4274f80b69e45aceffbdf3ffdb1e79908f (diff)
downloadcmake-7b9ea201fc5f8110e0f8478d8dc3715030a406b5.tar.gz
Merge topic 'xcode-framework-path' into release-3.19
5389bb4274 Xcode: Don't hard-code SDK-provided implicit framework search paths df08f8df30 cmComputeLinkInformation: Fix misspelt private variable name 375b307bae Apple: Fix linking to frameworks that do not exist until build time Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !5760
-rw-r--r--Source/cmComputeLinkInformation.cxx30
-rw-r--r--Source/cmComputeLinkInformation.h4
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx15
-rw-r--r--Tests/Framework/CMakeLists.txt16
-rw-r--r--Tests/Framework/External/CMakeLists.txt5
-rw-r--r--Tests/Framework/External/external.c4
-rw-r--r--Tests/Framework/useExternal.c6
7 files changed, 62 insertions, 18 deletions
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 201a9d9bf6..b9f15b70e8 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -474,6 +474,12 @@ std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
return this->FrameworkPaths;
}
+std::set<std::string> const&
+cmComputeLinkInformation::GetFrameworkPathsEmitted() const
+{
+ return this->FrameworkPathsEmitted;
+}
+
const std::set<const cmGeneratorTarget*>&
cmComputeLinkInformation::GetSharedLibrariesLinked() const
{
@@ -699,9 +705,13 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item,
} else {
// This is not a CMake target. Use the name given.
if (cmSystemTools::FileIsFullPath(item.Value)) {
- if (cmSystemTools::FileIsDirectory(item.Value)) {
+ if (cmSystemTools::IsPathToFramework(item.Value) &&
+ this->Makefile->IsOn("APPLE")) {
+ // This is a framework.
+ this->AddFrameworkItem(item.Value);
+ } else if (cmSystemTools::FileIsDirectory(item.Value)) {
// This is a directory.
- this->AddDirectoryItem(item.Value);
+ this->DropDirectoryItem(item.Value);
} else {
// Use the full path given to the library file.
this->Depends.push_back(item.Value);
@@ -1306,16 +1316,6 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
}
}
-void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
-{
- if (this->Makefile->IsOn("APPLE") &&
- cmSystemTools::IsPathToFramework(item)) {
- this->AddFrameworkItem(item);
- } else {
- this->DropDirectoryItem(item);
- }
-}
-
void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
{
// A full path to a directory was found as a link item. Warn the
@@ -1342,8 +1342,8 @@ void cmComputeLinkInformation::ComputeFrameworkInfo()
"CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES");
this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);
- this->FrameworkPathsEmmitted.insert(implicitDirVec.begin(),
- implicitDirVec.end());
+ this->FrameworkPathsEmitted.insert(implicitDirVec.begin(),
+ implicitDirVec.end());
// Regular expression to extract a framework path and name.
this->SplitFramework.compile("(.*)/(.*)\\.framework$");
@@ -1351,7 +1351,7 @@ void cmComputeLinkInformation::ComputeFrameworkInfo()
void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
{
- if (this->FrameworkPathsEmmitted.insert(p).second) {
+ if (this->FrameworkPathsEmitted.insert(p).second) {
this->FrameworkPaths.push_back(p);
}
}
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 543b6d7e1b..9fec702065 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -55,6 +55,7 @@ public:
std::vector<BT<std::string>> GetDirectoriesWithBacktraces();
std::vector<std::string> const& GetDepends() const;
std::vector<std::string> const& GetFrameworkPaths() const;
+ std::set<std::string> const& GetFrameworkPathsEmitted() const;
std::string GetLinkLanguage() const { return this->LinkLanguage; }
std::vector<std::string> const& GetRuntimeSearchPath() const;
std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }
@@ -155,7 +156,6 @@ private:
void AddFullItem(BT<std::string> const& item);
bool CheckImplicitDirItem(std::string const& item);
void AddUserItem(BT<std::string> const& item, bool pathNotKnown);
- void AddDirectoryItem(std::string const& item);
void AddFrameworkItem(std::string const& item);
void DropDirectoryItem(std::string const& item);
bool CheckSharedLibNoSOName(std::string const& item);
@@ -165,7 +165,7 @@ private:
// Framework info.
void ComputeFrameworkInfo();
void AddFrameworkPath(std::string const& p);
- std::set<std::string> FrameworkPathsEmmitted;
+ std::set<std::string> FrameworkPathsEmitted;
cmsys::RegularExpression SplitFramework;
// Linker search path computation.
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index df45b35230..51a7915329 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -3620,6 +3620,15 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
// now add the left-over link libraries
{
+ // Keep track of framework search paths we've already added or that are
+ // part of the set of implicit search paths. We don't want to repeat
+ // them and we also need to avoid hard-coding any SDK-specific paths.
+ // This is essential for getting device-and-simulator builds to work,
+ // 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<std::string> emitted(cli->GetFrameworkPathsEmitted());
+ const auto& fwPaths = cli->GetFrameworkPaths();
+ emitted.insert(fwPaths.begin(), fwPaths.end());
BuildObjectListOrString libPaths(this, true);
for (auto const& libItem : configItemMap[configName]) {
auto const& libName = *libItem;
@@ -3633,7 +3642,11 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
const auto fwName =
cmSystemTools::GetFilenameWithoutExtension(libPath);
const auto fwDir = cmSystemTools::GetParentDirectory(libPath);
- libPaths.Add("-F " + this->XCodeEscapePath(fwDir));
+ if (emitted.insert(fwDir).second) {
+ // This is a search path we had not added before and it isn't an
+ // implicit search path, so we need it
+ libPaths.Add("-F " + this->XCodeEscapePath(fwDir));
+ }
libPaths.Add("-framework " + fwName);
} else {
libPaths.Add(this->XCodeEscapePath(cleanPath));
diff --git a/Tests/Framework/CMakeLists.txt b/Tests/Framework/CMakeLists.txt
index a313c2c03c..f741ec2567 100644
--- a/Tests/Framework/CMakeLists.txt
+++ b/Tests/Framework/CMakeLists.txt
@@ -84,3 +84,19 @@ if(NOT XCODE OR NOT XCODE_VERSION VERSION_LESS 5)
endif()
include(CPack)
+
+if(APPLE)
+ set(ExternalFramework_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/External")
+ file(REMOVE_RECURSE "${ExternalFramework_INSTALL_DIR}")
+
+ include(ExternalProject)
+ ExternalProject_Add(ExternalFramework
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/External"
+ INSTALL_DIR "${ExternalFramework_INSTALL_DIR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
+ )
+
+ add_executable(useExternal useExternal.c)
+ target_link_libraries(useExternal PRIVATE "${ExternalFramework_INSTALL_DIR}/lib/External.framework")
+ add_dependencies(useExternal ExternalFramework)
+endif()
diff --git a/Tests/Framework/External/CMakeLists.txt b/Tests/Framework/External/CMakeLists.txt
new file mode 100644
index 0000000000..b9128fd922
--- /dev/null
+++ b/Tests/Framework/External/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.19)
+project(ExternalFramework C)
+add_library(External SHARED external.c)
+set_property(TARGET External PROPERTY FRAMEWORK 1)
+install(TARGETS External DESTINATION lib)
diff --git a/Tests/Framework/External/external.c b/Tests/Framework/External/external.c
new file mode 100644
index 0000000000..8441e71a05
--- /dev/null
+++ b/Tests/Framework/External/external.c
@@ -0,0 +1,4 @@
+int external(void)
+{
+ return 0;
+}
diff --git a/Tests/Framework/useExternal.c b/Tests/Framework/useExternal.c
new file mode 100644
index 0000000000..8494b15068
--- /dev/null
+++ b/Tests/Framework/useExternal.c
@@ -0,0 +1,6 @@
+extern int external(void);
+
+int main(void)
+{
+ return external();
+}