summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Help/release/3.19.rst8
-rw-r--r--Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst20
-rw-r--r--Modules/CMakeCCompilerId.c.in4
-rw-r--r--Modules/CMakeCXXCompilerId.cpp.in4
-rw-r--r--Modules/CMakeFortranCompilerId.F.in2
-rw-r--r--Source/CMakeVersion.cmake4
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx73
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h22
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx127
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.h4
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx12
-rw-r--r--Tests/Framework/CMakeLists.txt10
-rw-r--r--Tests/Framework/space.c7
-rw-r--r--Tests/Framework/use_space.c8
15 files changed, 203 insertions, 104 deletions
diff --git a/Help/release/3.19.rst b/Help/release/3.19.rst
index 1d55f1e57..49c679394 100644
--- a/Help/release/3.19.rst
+++ b/Help/release/3.19.rst
@@ -432,3 +432,11 @@ Changes made since CMake 3.19.0 include the following.
``CMakePresets.json`` or ``CMakeUserPresets.json`` files.
This was mistakenly allowed by the implementation in CMake 3.19.0 through
CMake 3.19.5, and was not documented.
+
+3.19.7
+------
+
+* With :ref:`Visual Studio Generators` for VS 2017 and higher, the
+ :variable:`CMAKE_GENERATOR_TOOLSET` field ``version=`` now accepts
+ three-component MSVC toolset versions such as ``14.28.29910``.
+ See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_VERSION` variable.
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
index 64f2e39cb..c4369ee71 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
@@ -11,3 +11,23 @@ may be specified by a field in :variable:`CMAKE_GENERATOR_TOOLSET` of
the form ``version=14.11``. If none is specified CMake will choose a default
toolset. The value may be empty if no minor version was selected and the
default is used.
+
+If the value is not empty, it is the version number that MSBuild uses in
+its ``Microsoft.VCToolsVersion.*.props`` file names.
+
+.. versionadded:: 3.19.7
+
+ VS 16.9's toolset may also be specified as ``14.28.16.9`` because
+ VS 16.10 uses the file name ``Microsoft.VCToolsVersion.14.28.16.9.props``.
+
+Three-Component MSVC Toolset Versions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.19.7
+
+The ``version=`` field may be given a three-component toolset version
+such as ``14.28.29910``, and CMake will convert it to the name used by
+MSBuild ``Microsoft.VCToolsVersion.*.props`` files. This is useful
+to distinguish between VS 16.8's ``14.28.29333`` toolset and VS 16.9's
+``14.28.29910`` toolset. It also matches ``vcvarsall``'s ``-vcvars_ver=``
+behavior.
diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in
index 8ba6abc7d..14e1282c8 100644
--- a/Modules/CMakeCCompilerId.c.in
+++ b/Modules/CMakeCCompilerId.c.in
@@ -26,7 +26,7 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
-#if defined(_CRAYC) || defined(__cray__)
+#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
@@ -77,7 +77,7 @@ int main(int argc, char* argv[])
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
-#if defined(_CRAYC) || defined(__cray__)
+#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_dialect_default[argc];
diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in
index 672fff86d..d55d8b190 100644
--- a/Modules/CMakeCXXCompilerId.cpp.in
+++ b/Modules/CMakeCXXCompilerId.cpp.in
@@ -20,7 +20,7 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
-#if defined(_CRAYC) || defined(__cray__)
+#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
@@ -76,7 +76,7 @@ int main(int argc, char* argv[])
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
-#if defined(_CRAYC) || defined(__cray__)
+#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_dialect_default[argc];
diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in
index 7e8828b77..6b51e3803 100644
--- a/Modules/CMakeFortranCompilerId.F.in
+++ b/Modules/CMakeFortranCompilerId.F.in
@@ -108,7 +108,7 @@
#else
PRINT *, 'INFO:compiler[]'
#endif
-#if defined(_CRAYFTN)
+#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
PRINT *, 'INFO:compiler_wrapper[CrayPrgEnv]'
#endif
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 2652592f9..2b087607b 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 19)
-set(CMake_VERSION_PATCH 6)
+set(CMake_VERSION_PATCH 7)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
@@ -21,7 +21,7 @@ endif()
if(NOT CMake_VERSION_NO_GIT)
# If this source was exported by 'git archive', use its commit info.
- set(git_info [==[0ecd9de6dd CMake 3.19.6]==])
+ set(git_info [==[22612dd53a CMake 3.19.7]==])
# Otherwise, try to identify the current development source version.
if(NOT git_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]?[0-9a-f]?)[0-9a-f]* "
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 7794df3fa..badce2eb5 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -3,6 +3,7 @@
#include "cmGlobalVisualStudio10Generator.h"
#include <algorithm>
+#include <utility>
#include <cm/memory>
@@ -302,16 +303,16 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
// If a specific minor version of the toolset was requested, verify that it
// is compatible to the major version and that is exists on disk.
// If not clear the value.
- std::string version = this->GeneratorToolsetVersion;
+ std::string versionToolset = this->GeneratorToolsetVersion;
cmsys::RegularExpression regex("[0-9][0-9]\\.[0-9][0-9]");
- if (regex.find(version)) {
- version = "v" + version.erase(2, 1);
+ if (regex.find(versionToolset)) {
+ versionToolset = "v" + versionToolset.erase(2, 1);
} else {
// Version not recognized. Clear it.
- version.clear();
+ versionToolset.clear();
}
- if (!cmHasPrefix(version, this->GetPlatformToolsetString())) {
+ if (!cmHasPrefix(versionToolset, this->GetPlatformToolsetString())) {
std::ostringstream e;
/* clang-format off */
e <<
@@ -329,15 +330,20 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
this->GeneratorToolsetVersion.clear();
}
- bool const isDefaultToolset =
- this->IsDefaultToolset(this->GeneratorToolsetVersion);
- if (isDefaultToolset) {
- // If the given version is the default toolset, remove the setting
- this->GeneratorToolsetVersion.clear();
- } else {
- std::string const toolsetPath = this->GetAuxiliaryToolset();
- if (!toolsetPath.empty() && !cmSystemTools::FileExists(toolsetPath)) {
-
+ std::string auxProps;
+ switch (this->FindAuxToolset(this->GeneratorToolsetVersion, auxProps)) {
+ case AuxToolset::None:
+ this->GeneratorToolsetVersionProps = {};
+ break;
+ case AuxToolset::Default:
+ // The given version is the default toolset. Remove the setting.
+ this->GeneratorToolsetVersion.clear();
+ this->GeneratorToolsetVersionProps = {};
+ break;
+ case AuxToolset::PropsExist:
+ this->GeneratorToolsetVersionProps = std::move(auxProps);
+ break;
+ case AuxToolset::PropsMissing: {
std::ostringstream e;
/* clang-format off */
e <<
@@ -347,22 +353,24 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
" " << this->GetPlatformToolsetString() << ",version=" <<
this->GeneratorToolsetVersion << "\n"
"does not seem to be installed at\n" <<
- " " << toolsetPath;
+ " " << auxProps;
;
/* clang-format on */
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
// Clear the configured tool-set
this->GeneratorToolsetVersion.clear();
- }
+ this->GeneratorToolsetVersionProps = {};
+ } break;
}
}
if (const char* toolset = this->GetPlatformToolset()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET", toolset);
}
- if (const char* version = this->GetPlatformToolsetVersion()) {
- mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_VERSION", version);
+ if (!this->GeneratorToolsetVersion.empty()) {
+ mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_VERSION",
+ this->GeneratorToolsetVersion);
}
if (const char* hostArch = this->GetPlatformToolsetHostArchitecture()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE", hostArch);
@@ -719,23 +727,10 @@ std::string const& cmGlobalVisualStudio10Generator::GetPlatformToolsetString()
return empty;
}
-const char* cmGlobalVisualStudio10Generator::GetPlatformToolsetVersion() const
-{
- std::string const& version = this->GetPlatformToolsetVersionString();
- if (version.empty()) {
- return nullptr;
- }
- return version.c_str();
-}
-
std::string const&
-cmGlobalVisualStudio10Generator::GetPlatformToolsetVersionString() const
+cmGlobalVisualStudio10Generator::GetPlatformToolsetVersionProps() const
{
- if (!this->GeneratorToolsetVersion.empty()) {
- return this->GeneratorToolsetVersion;
- }
- static std::string const empty;
- return empty;
+ return this->GeneratorToolsetVersionProps;
}
const char*
@@ -792,15 +787,11 @@ cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaCustomDirString() const
return this->GeneratorToolsetCudaCustomDir;
}
-bool cmGlobalVisualStudio10Generator::IsDefaultToolset(
- const std::string&) const
-{
- return true;
-}
-
-std::string cmGlobalVisualStudio10Generator::GetAuxiliaryToolset() const
+cmGlobalVisualStudio10Generator::AuxToolset
+cmGlobalVisualStudio10Generator::FindAuxToolset(std::string&,
+ std::string&) const
{
- return {};
+ return AuxToolset::None;
}
bool cmGlobalVisualStudio10Generator::FindMakeProgram(cmMakefile* mf)
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 65ea33fc9..8d30ef8e8 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -61,9 +61,8 @@ public:
const char* GetPlatformToolset() const;
std::string const& GetPlatformToolsetString() const;
- /** The toolset version. */
- const char* GetPlatformToolsetVersion() const;
- std::string const& GetPlatformToolsetVersionString() const;
+ /** The toolset version props file, if any. */
+ std::string const& GetPlatformToolsetVersionProps() const;
/** The toolset host architecture name (e.g. x64 for 64-bit host tools). */
const char* GetPlatformToolsetHostArchitecture() const;
@@ -120,9 +119,6 @@ public:
std::string Encoding() override;
const char* GetToolsVersion() const;
- virtual bool IsDefaultToolset(const std::string& version) const;
- virtual std::string GetAuxiliaryToolset() const;
-
bool GetSupportsUnityBuilds() const { return this->SupportsUnityBuilds; }
bool FindMakeProgram(cmMakefile* mf) override;
@@ -168,6 +164,16 @@ protected:
virtual bool SelectWindowsPhoneToolset(std::string& toolset) const;
virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
+ enum class AuxToolset
+ {
+ None,
+ Default,
+ PropsExist,
+ PropsMissing
+ };
+ virtual AuxToolset FindAuxToolset(std::string& version,
+ std::string& props) const;
+
std::string const& GetMSBuildCommand();
cmIDEFlagTable const* LoadFlagTable(std::string const& optionsName,
@@ -176,7 +182,7 @@ protected:
std::string const& table) const;
std::string GeneratorToolset;
- std::string GeneratorToolsetVersion;
+ std::string GeneratorToolsetVersionProps;
std::string GeneratorToolsetHostArchitecture;
std::string GeneratorToolsetCustomVCTargetsDir;
std::string GeneratorToolsetCuda;
@@ -230,6 +236,8 @@ private:
std::string FindDevEnvCommand() override;
std::string GetVSMakeProgram() override { return this->GetMSBuildCommand(); }
+ std::string GeneratorToolsetVersion;
+
bool PlatformToolsetNeedsDebugEnum;
bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 84f870ea6..fb518a233 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -2,6 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudioVersionedGenerator.h"
+#include <cmext/string_view>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+
#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio10Generator.h"
@@ -391,27 +396,6 @@ bool cmGlobalVisualStudioVersionedGenerator::GetVSInstanceVersion(
return vsSetupAPIHelper.GetVSInstanceVersion(vsInstanceVersion);
}
-bool cmGlobalVisualStudioVersionedGenerator::IsDefaultToolset(
- const std::string& version) const
-{
- if (version.empty()) {
- return true;
- }
-
- std::string vcToolsetVersion;
- if (this->vsSetupAPIHelper.GetVCToolsetVersion(vcToolsetVersion)) {
-
- cmsys::RegularExpression regex("[0-9][0-9]\\.[0-9]+");
- if (regex.find(version) && regex.find(vcToolsetVersion)) {
- const auto majorMinorEnd = vcToolsetVersion.find('.', 3);
- const auto majorMinor = vcToolsetVersion.substr(0, majorMinorEnd);
- return version == majorMinor;
- }
- }
-
- return false;
-}
-
bool cmGlobalVisualStudioVersionedGenerator::IsStdOutEncodingSupported() const
{
// Supported from Visual Studio 16.7 Preview 3.
@@ -446,29 +430,92 @@ cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision()
return "";
}
-std::string cmGlobalVisualStudioVersionedGenerator::GetAuxiliaryToolset() const
+cmGlobalVisualStudioVersionedGenerator::AuxToolset
+cmGlobalVisualStudioVersionedGenerator::FindAuxToolset(
+ std::string& version, std::string& props) const
{
- const char* version = this->GetPlatformToolsetVersion();
- if (version) {
- std::string instancePath;
- GetVSInstance(instancePath);
- std::string toolsetDir = instancePath + "/VC/Auxiliary/Build";
- char sep = '/';
- if (cmSystemTools::VersionCompareGreaterEq(version, "14.20")) {
- std::string toolsetDot =
- cmStrCat(toolsetDir, '.', version, "/Microsoft.VCToolsVersion.",
- version, ".props");
- if (cmSystemTools::PathExists(toolsetDot)) {
- sep = '.';
+ if (version.empty()) {
+ return AuxToolset::None;
+ }
+
+ std::string instancePath;
+ this->GetVSInstance(instancePath);
+ cmSystemTools::ConvertToUnixSlashes(instancePath);
+
+ // Translate three-component format accepted by "vcvarsall -vcvars_ver=".
+ cmsys::RegularExpression threeComponent(
+ "^([0-9]+\\.[0-9]+)\\.[0-9][0-9][0-9][0-9][0-9]$");
+ if (threeComponent.find(version)) {
+ // Load "VC/Auxiliary/Build/*/Microsoft.VCToolsVersion.*.txt" files
+ // with two matching components to check their three-component version.
+ std::string const& twoComponent = threeComponent.match(1);
+ std::string pattern =
+ cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s, twoComponent,
+ "*/Microsoft.VCToolsVersion."_s, twoComponent, "*.txt"_s);
+ cmsys::Glob glob;
+ glob.SetRecurseThroughSymlinks(false);
+ if (glob.FindFiles(pattern)) {
+ for (std::string const& txt : glob.GetFiles()) {
+ std::string ver;
+ cmsys::ifstream fin(txt.c_str());
+ if (fin && std::getline(fin, ver)) {
+ // Strip trailing whitespace.
+ ver = ver.substr(0, ver.find_first_not_of("0123456789."));
+ // If the three-component version matches, translate it to
+ // that used by the "Microsoft.VCToolsVersion.*.txt" file name.
+ if (ver == version) {
+ cmsys::RegularExpression extractVersion(
+ "VCToolsVersion\\.([0-9.]+)\\.txt$");
+ if (extractVersion.find(txt)) {
+ version = extractVersion.match(1);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (cmSystemTools::VersionCompareGreaterEq(version, "14.20")) {
+ props = cmStrCat(instancePath, "/VC/Auxiliary/Build."_s, version,
+ "/Microsoft.VCToolsVersion."_s, version, ".props"_s);
+ if (cmSystemTools::PathExists(props)) {
+ return AuxToolset::PropsExist;
+ }
+ }
+ props = cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s, version,
+ "/Microsoft.VCToolsVersion."_s, version, ".props"_s);
+ if (cmSystemTools::PathExists(props)) {
+ return AuxToolset::PropsExist;
+ }
+
+ // Accept the toolset version that is default in the current VS version
+ // by matching the name later VS versions will use for the SxS props files.
+ std::string vcToolsetVersion;
+ if (this->vsSetupAPIHelper.GetVCToolsetVersion(vcToolsetVersion)) {
+ // Accept an exact-match (three-component version).
+ if (version == vcToolsetVersion) {
+ return AuxToolset::Default;
+ }
+
+ // Accept known SxS props file names using four version components
+ // in VS versions later than the current.
+ if (version == "14.28.16.9" && vcToolsetVersion == "14.28.29910") {
+ return AuxToolset::Default;
+ }
+
+ // The first two components of the default toolset version typically
+ // match the name used by later VS versions for the SxS props files.
+ cmsys::RegularExpression twoComponent("^([0-9]+\\.[0-9]+)");
+ if (twoComponent.find(version)) {
+ std::string const versionPrefix = cmStrCat(twoComponent.match(1), '.');
+ if (cmHasPrefix(vcToolsetVersion, versionPrefix)) {
+ return AuxToolset::Default;
}
}
- std::string toolsetPath =
- cmStrCat(toolsetDir, sep, version, "/Microsoft.VCToolsVersion.", version,
- ".props");
- cmSystemTools::ConvertToUnixSlashes(toolsetPath);
- return toolsetPath;
}
- return {};
+
+ return AuxToolset::PropsMissing;
}
bool cmGlobalVisualStudioVersionedGenerator::InitializeWindows(cmMakefile* mf)
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h
index 46a5f40e5..cee129e52 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.h
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.h
@@ -30,8 +30,8 @@ public:
bool GetVSInstanceVersion(unsigned long long& vsInstanceVersion) const;
- bool IsDefaultToolset(const std::string& version) const override;
- std::string GetAuxiliaryToolset() const override;
+ AuxToolset FindAuxToolset(std::string& version,
+ std::string& props) const override;
bool IsStdOutEncodingSupported() const override;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 51a791532..5b4485193 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -3647,7 +3647,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
// implicit search path, so we need it
libPaths.Add("-F " + this->XCodeEscapePath(fwDir));
}
- libPaths.Add("-framework " + fwName);
+ libPaths.Add("-framework " + this->XCodeEscapePath(fwName));
} else {
libPaths.Add(this->XCodeEscapePath(cleanPath));
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4eb3b7f8f..489e42d8e 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -623,14 +623,14 @@ void cmVisualStudio10TargetGenerator::Generate()
}
switch (this->ProjectType) {
- case vcxproj:
- if (this->GlobalGenerator->GetPlatformToolsetVersion()) {
- Elem(e0, "Import")
- .Attribute("Project",
- this->GlobalGenerator->GetAuxiliaryToolset());
+ case vcxproj: {
+ std::string const& props =
+ this->GlobalGenerator->GetPlatformToolsetVersionProps();
+ if (!props.empty()) {
+ Elem(e0, "Import").Attribute("Project", props);
}
Elem(e0, "Import").Attribute("Project", VS10_CXX_DEFAULT_PROPS);
- break;
+ } break;
case csproj:
Elem(e0, "Import")
.Attribute("Project", VS10_CSharp_DEFAULT_PROPS)
diff --git a/Tests/Framework/CMakeLists.txt b/Tests/Framework/CMakeLists.txt
index f741ec256..aabf6b419 100644
--- a/Tests/Framework/CMakeLists.txt
+++ b/Tests/Framework/CMakeLists.txt
@@ -83,6 +83,16 @@ if(NOT XCODE OR NOT XCODE_VERSION VERSION_LESS 5)
target_link_libraries(barStatic fooStatic)
endif()
+if(XCODE)
+ add_library(space SHARED space.c)
+ set_target_properties(space PROPERTIES
+ FRAMEWORK TRUE
+ OUTPUT_NAME "space space"
+ )
+ add_executable(use_space use_space.c)
+ target_link_libraries(use_space PRIVATE space)
+endif()
+
include(CPack)
if(APPLE)
diff --git a/Tests/Framework/space.c b/Tests/Framework/space.c
new file mode 100644
index 000000000..bf5b0c38b
--- /dev/null
+++ b/Tests/Framework/space.c
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ int space(void)
+{
+ return 0;
+}
diff --git a/Tests/Framework/use_space.c b/Tests/Framework/use_space.c
new file mode 100644
index 000000000..bb4893d03
--- /dev/null
+++ b/Tests/Framework/use_space.c
@@ -0,0 +1,8 @@
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+ int space(void);
+int main(void)
+{
+ return space();
+}