diff options
-rw-r--r-- | Help/manual/cmake-properties.7.rst | 4 | ||||
-rw-r--r-- | Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst | 24 | ||||
-rw-r--r-- | Help/prop_sf/VS_COPY_TO_OUT_DIR.rst | 6 | ||||
-rw-r--r-- | Help/prop_sf/VS_INCLUDE_IN_VSIX.rst | 6 | ||||
-rw-r--r-- | Help/prop_sf/VS_RESOURCE_GENERATOR.rst | 8 | ||||
-rw-r--r-- | Help/release/dev/vs-advanced-source-properties.rst | 12 | ||||
-rw-r--r-- | Help/release/dev/vs-csharp-support.rst | 13 | ||||
-rw-r--r-- | Help/release/dev/xcode-effective-platform-name.rst | 8 | ||||
-rw-r--r-- | Modules/Qt4Macros.cmake | 2 | ||||
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/QtDialog/AddCacheEntry.cxx | 2 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 5 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 4 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 14 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.h | 2 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 209 | ||||
-rw-r--r-- | Tests/RunCMake/XcodeProject/RunCMakeTest.cmake | 21 | ||||
-rw-r--r-- | Tests/RunCMake/XcodeProject/XcodeMultiplatform.cmake | 14 |
19 files changed, 326 insertions, 34 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 5b39bed..4af8626 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -44,6 +44,7 @@ Properties of Global Scope /prop_gbl/TARGET_MESSAGES /prop_gbl/TARGET_SUPPORTS_SHARED_LIBS /prop_gbl/USE_FOLDERS + /prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME .. _`Directory Properties`: @@ -363,8 +364,11 @@ Properties on Source Files /prop_sf/SKIP_AUTORCC /prop_sf/SKIP_AUTOUIC /prop_sf/SYMBOLIC + /prop_sf/VS_COPY_TO_OUT_DIR /prop_sf/VS_DEPLOYMENT_CONTENT /prop_sf/VS_DEPLOYMENT_LOCATION + /prop_sf/VS_INCLUDE_IN_VSIX + /prop_sf/VS_RESOURCE_GENERATOR /prop_sf/VS_SHADER_ENTRYPOINT /prop_sf/VS_SHADER_FLAGS /prop_sf/VS_SHADER_MODEL diff --git a/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst b/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst new file mode 100644 index 0000000..9a6086e --- /dev/null +++ b/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst @@ -0,0 +1,24 @@ +XCODE_EMIT_EFFECTIVE_PLATFORM_NAME +---------------------------------- + +Control emission of ``EFFECTIVE_PLATFORM_NAME`` by the Xcode generator. + +It is required for building the same target with multiple SDKs. A +common use case is the parallel use of ``iphoneos`` and +``iphonesimulator`` SDKs. + +Three different states possible that control when the Xcode generator +emits the ``EFFECTIVE_PLATFORM_NAME`` variable: + +- If set to ``ON`` it will always be emitted +- If set to ``OFF`` it will never be emitted +- If unset (the default) it will only be emitted when the project was + configured for an embedded Xcode SDK like iOS, tvOS, watchOS or any + of the simulators. + +.. note:: + + When this behavior is enable for generated Xcode projects, the + ``EFFECTIVE_PLATFORM_NAME`` variable will leak into + :manual:`Generator expressions <cmake-generator-expressions(7)>` + like ``TARGET_FILE`` and will render those mostly unusable. diff --git a/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst b/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst new file mode 100644 index 0000000..16c8d83 --- /dev/null +++ b/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst @@ -0,0 +1,6 @@ +VS_COPY_TO_OUT_DIR +------------------ + +Sets the ``<CopyToOutputDirectory>`` tag for a source file in a +Visual Studio project file. Valid values are ``Never``, ``Always`` +and ``PreserveNewest``. diff --git a/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst b/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst new file mode 100644 index 0000000..30f471d --- /dev/null +++ b/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst @@ -0,0 +1,6 @@ +VS_INCLUDE_IN_VSIX +------------------ + +Boolean property to specify if the file should be included within a VSIX +extension package. This is needed for development of Visual Studio +extensions. diff --git a/Help/prop_sf/VS_RESOURCE_GENERATOR.rst b/Help/prop_sf/VS_RESOURCE_GENERATOR.rst new file mode 100644 index 0000000..97e5aac --- /dev/null +++ b/Help/prop_sf/VS_RESOURCE_GENERATOR.rst @@ -0,0 +1,8 @@ +VS_RESOURCE_GENERATOR +--------------------- + +This property allows to specify the resource generator to be used +on this file. It defaults to ``PublicResXFileCodeGenerator`` if +not set. + +This property only applies to C# projects. diff --git a/Help/release/dev/vs-advanced-source-properties.rst b/Help/release/dev/vs-advanced-source-properties.rst new file mode 100644 index 0000000..dd391e0 --- /dev/null +++ b/Help/release/dev/vs-advanced-source-properties.rst @@ -0,0 +1,12 @@ +vs-advanced-source-properties +----------------------------- + +* The :ref:`Visual Studio Generators` for VS 2010 and above + learned some more source file properties: + + - :prop_sf:`VS_RESOURCE_GENERATOR` (C# only): allows setting the resource + generator + - :prop_sf:`VS_COPY_TO_OUT_DIR`: parameter to set if file should be copied + to output directory (values: ``Never``, ``Always``, ``PreserveNewest``) + - :prop_sf:`VS_INCLUDE_IN_VSIX`: boolean property to include file include + Visual Studio extension package diff --git a/Help/release/dev/vs-csharp-support.rst b/Help/release/dev/vs-csharp-support.rst index 26d8574..46b235a 100644 --- a/Help/release/dev/vs-csharp-support.rst +++ b/Help/release/dev/vs-csharp-support.rst @@ -19,7 +19,16 @@ vs-native-csharp-support that specifically targets C# contains ``CSharp`` as a part of their names. -* More finetuning of C# targets can be done using target - properties. Specifically the Visual Studio related target +* More finetuning of C# targets can be done using target and source + file properties. Specifically the Visual Studio related target properties (``VS_*``) are worth a look (for setting toolset versions, root namespaces, assembly icons, ...). + +* **Auto-"linking"** in .csproj files: In C#/.NET development with + Visual Studio there is a number of visual editors used which + generate code. Both the generated files and the ones edited + with the UI are connected in the ``.csproj`` file using + ``<DependentUpon>`` tags. If CMake finds within a C# project + any source file with extension ``.Designer.cs`` or ``.xaml.cs``, + it checks sibling files with extension ``.xaml``, ``.settings``, + ``.resx`` or ``.cs`` and establishes the dependency connection. diff --git a/Help/release/dev/xcode-effective-platform-name.rst b/Help/release/dev/xcode-effective-platform-name.rst new file mode 100644 index 0000000..e337ca0 --- /dev/null +++ b/Help/release/dev/xcode-effective-platform-name.rst @@ -0,0 +1,8 @@ +xcode-effective-platform-name +----------------------------- + +* The Xcode generator can now control emission of the + ``EFFECTIVE_PLATFORM_NAME`` variable through the + :prop_gbl:`XCODE_EMIT_EFFECTIVE_PLATFORM_NAME` global property. + This is useful when building with multiple SDKs like macosx and + iphoneos in parallel. diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake index 0279d1c..0478918 100644 --- a/Modules/Qt4Macros.cmake +++ b/Modules/Qt4Macros.cmake @@ -439,7 +439,7 @@ macro(QT4_CREATE_TRANSLATION _qm_files) get_filename_component(_abs_include "${_pro_include}" ABSOLUTE) string(APPEND _pro_includes " \\\n \"${_abs_include}\"") endforeach() - file(WRITE ${_ts_pro} "SOURCES =${_pro_srcs}\nINCLUDEPATH =${_pro_includes}\n") + file(GENERATE OUTPUT ${_ts_pro} CONTENT "SOURCES =${_pro_srcs}\nINCLUDEPATH =${_pro_includes}\n") endif() add_custom_command(OUTPUT ${_ts_file} COMMAND Qt4::lupdate diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 7990532..8e6ca1a 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 7) -set(CMake_VERSION_PATCH 20170120) +set(CMake_VERSION_PATCH 20170124) #set(CMake_VERSION_RC 1) diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx index daf4bd1..6284ac9 100644 --- a/Source/QtDialog/AddCacheEntry.cxx +++ b/Source/QtDialog/AddCacheEntry.cxx @@ -46,7 +46,7 @@ AddCacheEntry::AddCacheEntry(QWidget* p, const QStringList& varNames, QString AddCacheEntry::name() const { - return this->Name->text(); + return this->Name->text().trimmed(); } QVariant AddCacheEntry::value() const diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index b6db0d6..dcf3764 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -4419,9 +4419,10 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config, // The generator may add the configuration's subdirectory. if (!conf.empty()) { - bool iosPlatform = this->Makefile->PlatformIsAppleIos(); + bool useEPN = + this->GlobalGenerator->UseEffectivePlatformName(this->Makefile); std::string suffix = - usesDefaultOutputDir && iosPlatform ? "${EFFECTIVE_PLATFORM_NAME}" : ""; + usesDefaultOutputDir && useEPN ? "${EFFECTIVE_PLATFORM_NAME}" : ""; this->LocalGenerator->GetGlobalGenerator()->AppendDirectoryForConfig( "/", conf, suffix, out); } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 2808051..f118250 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2342,8 +2342,8 @@ void cmGlobalGenerator::AddGlobalTarget_Install( singleLine.push_back(cmd); if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') { std::string cfgArg = "-DBUILD_TYPE="; - bool iosPlatform = mf->PlatformIsAppleIos(); - if (iosPlatform) { + bool useEPN = this->UseEffectivePlatformName(mf); + if (useEPN) { cfgArg += "$(CONFIGURATION)"; singleLine.push_back(cfgArg); cfgArg = "-DEFFECTIVE_PLATFORM_NAME=$(EFFECTIVE_PLATFORM_NAME)"; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 88ef8da..18e3730 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -333,6 +333,10 @@ public: virtual bool UseFolderProperty() const; + /** Return whether the generator should use EFFECTIVE_PLATFORM_NAME. This is + relevant for mixed macOS and iOS builds. */ + virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; } + std::string GetSharedLibFlagsForLanguage(std::string const& lang) const; /** Generate an <output>.rule file path for a given command output. */ diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 96535eb..d448315 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -22,6 +22,7 @@ #include "cmOutputConverter.h" #include "cmSourceFile.h" #include "cmSourceGroup.h" +#include "cmState.h" #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -3544,6 +3545,19 @@ bool cmGlobalXCodeGenerator::IsMultiConfig() const return true; } +bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const +{ + const char* epnValue = + this->GetCMakeInstance()->GetState()->GetGlobalProperty( + "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME"); + + if (!epnValue) { + return mf->PlatformIsAppleIos(); + } + + return cmSystemTools::IsOn(epnValue); +} + void cmGlobalXCodeGenerator::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 42c39aa..1aaf9c7 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -86,6 +86,8 @@ public: i.e. "Can I build Debug and Release in the same tree?" */ bool IsMultiConfig() const CM_OVERRIDE; + bool UseEffectivePlatformName(cmMakefile* mf) const CM_OVERRIDE; + bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) CM_OVERRIDE; void AppendFlag(std::string& flags, std::string const& flag); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 89380eb..2e6c19b 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -610,30 +610,91 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() this->GeneratorTarget->GetResxSources(resxObjs, ""); if (!resxObjs.empty()) { this->WriteString("<ItemGroup>\n", 1); + std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); + this->ConvertToWindowsSlash(srcDir); for (std::vector<cmSourceFile const*>::const_iterator oi = resxObjs.begin(); oi != resxObjs.end(); ++oi) { std::string obj = (*oi)->GetFullPath(); this->WriteString("<EmbeddedResource Include=\"", 2); this->ConvertToWindowsSlash(obj); + bool useRelativePath = false; + if (csproj == this->ProjectType && this->InSourceBuild) { + // If we do an in-source build and the resource file is in a + // subdirectory + // of the .csproj file, we have to use relative pathnames, otherwise + // visual studio does not show the file in the IDE. Sorry. + if (obj.find(srcDir) == 0) { + obj = this->ConvertPath(obj, true); + this->ConvertToWindowsSlash(obj); + useRelativePath = true; + } + } (*this->BuildFileStream) << obj << "\">\n"; - this->WriteString("<DependentUpon>", 3); - std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h"; - (*this->BuildFileStream) << hFileName << "</DependentUpon>\n"; - - for (std::vector<std::string>::const_iterator i = - this->Configurations.begin(); - i != this->Configurations.end(); ++i) { - this->WritePlatformConfigTag("LogicalName", i->c_str(), 3); - if (this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE") || - // Handle variant of VS_GLOBAL_<variable> for RootNamespace. - this->GeneratorTarget->GetProperty("VS_GLOBAL_RootNamespace")) { - (*this->BuildFileStream) << "$(RootNamespace)."; + if (csproj != this->ProjectType) { + this->WriteString("<DependentUpon>", 3); + std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h"; + (*this->BuildFileStream) << hFileName << "</DependentUpon>\n"; + + for (std::vector<std::string>::const_iterator i = + this->Configurations.begin(); + i != this->Configurations.end(); ++i) { + this->WritePlatformConfigTag("LogicalName", i->c_str(), 3); + if (this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE") || + // Handle variant of VS_GLOBAL_<variable> for RootNamespace. + this->GeneratorTarget->GetProperty("VS_GLOBAL_RootNamespace")) { + (*this->BuildFileStream) << "$(RootNamespace)."; + } + (*this->BuildFileStream) << "%(Filename)"; + (*this->BuildFileStream) << ".resources"; + (*this->BuildFileStream) << "</LogicalName>\n"; + } + } else { + std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); + this->ConvertToWindowsSlash(binDir); + // If the resource was NOT added using a relative path (which should + // be the default), we have to provide a link here + if (!useRelativePath) { + std::string link; + if (obj.find(srcDir) == 0) { + link = obj.substr(srcDir.length() + 1); + } else if (obj.find(binDir) == 0) { + link = obj.substr(binDir.length() + 1); + } else { + link = cmsys::SystemTools::GetFilenameName(obj); + } + if (!link.empty()) { + this->WriteString("<Link>", 3); + (*this->BuildFileStream) << link << "</Link>\n"; + } + } + // Determine if this is a generated resource from a .Designer.cs file + std::string designerResource = + cmSystemTools::GetFilenamePath((*oi)->GetFullPath()) + "/" + + cmSystemTools::GetFilenameWithoutLastExtension( + (*oi)->GetFullPath()) + + ".Designer.cs"; + if (cmsys::SystemTools::FileExists(designerResource)) { + std::string generator = "PublicResXFileCodeGenerator"; + if (const char* g = (*oi)->GetProperty("VS_RESOURCE_GENERATOR")) { + generator = g; + } + this->WriteString("<Generator>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(generator) + << "</Generator>\n"; + if (designerResource.find(srcDir) == 0) { + designerResource = designerResource.substr(srcDir.length() + 1); + } else if (designerResource.find(binDir) == 0) { + designerResource = designerResource.substr(binDir.length() + 1); + } else { + designerResource = + cmsys::SystemTools::GetFilenameName(designerResource); + } + this->ConvertToWindowsSlash(designerResource); + this->WriteString("<LastGenOutput>", 3); + (*this->BuildFileStream) << designerResource << "</LastGenOutput>\n"; } - (*this->BuildFileStream) << "%(Filename)"; - (*this->BuildFileStream) << ".resources"; - (*this->BuildFileStream) << "</LogicalName>\n"; } this->WriteString("</EmbeddedResource>\n", 2); @@ -661,6 +722,24 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup() } this->WriteSource(xamlType, *oi, ">\n"); + if (csproj == this->ProjectType && !this->InSourceBuild) { + // add <Link> tag to written XAML source if necessary + const std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); + const std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); + std::string link; + if (obj.find(srcDir) == 0) { + link = obj.substr(srcDir.length() + 1); + } else if (obj.find(binDir) == 0) { + link = obj.substr(binDir.length() + 1); + } else { + link = cmsys::SystemTools::GetFilenameName(obj); + } + if (!link.empty()) { + this->ConvertToWindowsSlash(link); + this->WriteString("<Link>", 3); + (*this->BuildFileStream) << link << "</Link>\n"; + } + } this->WriteString("<SubType>Designer</SubType>\n", 3); this->WriteString("</", 2); (*this->BuildFileStream) << xamlType << ">\n"; @@ -1348,7 +1427,12 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) std::string shaderEntryPoint; std::string shaderModel; std::string shaderAdditionalFlags; + std::string settingsGenerator; + std::string settingsLastGenOutput; std::string sourceLink; + std::string subType; + std::string copyToOutDir; + std::string includeInVsix; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); if (csproj == this->ProjectType) { // EVERY extra source file must have a <Link>, otherwise it might not @@ -1405,6 +1489,28 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) tool = "XML"; } else if (ext == "natvis") { tool = "Natvis"; + } else if (ext == "settings") { + // remove path to current source dir (if files are in current source dir) + if (!sourceLink.empty()) { + settingsLastGenOutput = sourceLink; + } else { + settingsLastGenOutput = sf->GetFullPath(); + } + std::size_t pos = settingsLastGenOutput.find(".settings"); + settingsLastGenOutput.replace(pos, 9, ".Designer.cs"); + settingsGenerator = "SettingsSingleFileGenerator"; + toolHasSettings = true; + } else if (ext == "vsixmanifest") { + subType = "Designer"; + } + if (const char* c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) { + copyToOutDir = c; + toolHasSettings = true; + } + if (sf->GetPropertyAsBool("VS_INCLUDE_IN_VSIX")) { + includeInVsix = "True"; + tool = "Content"; + toolHasSettings = true; } if (this->NsightTegra) { @@ -1495,10 +1601,35 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) (*this->BuildFileStream) << cmVS10EscapeXML(shaderAdditionalFlags) << "</AdditionalOptions>\n"; } + if (!settingsGenerator.empty()) { + this->WriteString("<Generator>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(settingsGenerator) + << "</Generator>\n"; + } + if (!settingsLastGenOutput.empty()) { + this->WriteString("<LastGenOutput>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(settingsLastGenOutput) + << "</LastGenOutput>\n"; + } if (!sourceLink.empty()) { this->WriteString("<Link>", 3); (*this->BuildFileStream) << cmVS10EscapeXML(sourceLink) << "</Link>\n"; } + if (!subType.empty()) { + this->WriteString("<SubType>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(subType) << "</SubType>\n"; + } + if (!copyToOutDir.empty()) { + this->WriteString("<CopyToOutputDirectory>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(copyToOutDir) + << "</CopyToOutputDirectory>\n"; + } + if (!includeInVsix.empty()) { + this->WriteString("<IncludeInVSIX>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(includeInVsix) + << "</IncludeInVSIX>\n"; + } + this->WriteString("</", 2); (*this->BuildFileStream) << tool << ">\n"; } else { @@ -1540,12 +1671,6 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool, this->GlobalGenerator->PathTooLong(this->GeneratorTarget, sf, sourceRel); } } - if (csproj == this->ProjectType && this->InSourceBuild) { - std::string srcdir = this->Makefile->GetCurrentSourceDirectory(); - if (sourceFile.find(srcdir) != std::string::npos) { - sourceFile = sourceFile.substr(srcdir.size() + 1); - } - } this->ConvertToWindowsSlash(sourceFile); this->WriteString("<", 2); (*this->BuildFileStream) << tool << " Include=\"" @@ -1815,9 +1940,43 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( sourceFileTags["Link"] = link; } } - // - // NOTE: in future commits additional props will be added! - // + // check if file is a generated .Designer.cs or .xaml.cs file + // to add additional necessary tags + const std::string fileExtension = + cmsys::SystemTools::GetFilenameExtension(f); + if (fileExtension == ".Designer.cs" || fileExtension == ".xaml.cs") { + f = f.substr(0, f.length() - fileExtension.length()); + if (sourceFileTags.find("Link") == sourceFileTags.end() && + !this->InSourceBuild) { + // add link fallback + sourceFileTags["Link"] = + cmsys::SystemTools::GetFilenameName(f) + fileExtension; + } + std::vector<std::string> extensions; + extensions.push_back(".resx"); + extensions.push_back(".settings"); + extensions.push_back(".xaml"); + extensions.push_back(".cs"); + std::string dependencyExtension; + for (std::vector<std::string>::iterator i = extensions.begin(); + i != extensions.end(); ++i) { + if (cmsys::SystemTools::FileExists(f + *i)) { + dependencyExtension = *i; + // There should never be more than one match. Otherwise + // one cannot tell on which match the file depends. + break; + } + } + if (dependencyExtension == ".resx") { + sourceFileTags["DesignTime"] = "True"; + sourceFileTags["AutoGen"] = "True"; + } else if (dependencyExtension == ".settings") { + sourceFileTags["DesignTimeSharedInput"] = "True"; + sourceFileTags["AutoGen"] = "True"; + } + sourceFileTags["DependentUpon"] = + cmsys::SystemTools::GetFilenameName(f) + dependencyExtension; + } // write source file specific tags if (!sourceFileTags.empty()) { hasFlags = true; @@ -1825,7 +1984,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( firstString = ""; for (CsPropMap::const_iterator i = sourceFileTags.begin(); i != sourceFileTags.end(); ++i) { - this->WriteString("<", 2); + this->WriteString("<", 3); (*this->BuildFileStream) << i->first << ">" << cmVS10EscapeXML(i->second) << "</" << i->first << ">\n"; diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index 60912c2..f51a107 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -166,3 +166,24 @@ if(NOT XCODE_VERSION VERSION_LESS 6) unset(RunCMake_TEST_NO_CLEAN) unset(RunCMake_TEST_OPTIONS) endif() + +if(NOT XCODE_VERSION VERSION_LESS 5) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeMultiplatform-build) + set(RunCMake_TEST_NO_CLEAN 1) + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(XcodeMultiplatform) + + # build ios before macos + run_cmake_command(XcodeMultiplatform-iphonesimulator-build ${CMAKE_COMMAND} --build . -- -sdk iphonesimulator) + run_cmake_command(XcodeMultiplatform-iphonesimulator-install ${CMAKE_COMMAND} --build . --target install -- -sdk iphonesimulator DESTDIR=${RunCMake_TEST_BINARY_DIR}/_install_iphonesimulator) + + run_cmake_command(XcodeMultiplatform-macosx-build ${CMAKE_COMMAND} --build . -- -sdk macosx) + run_cmake_command(XcodeMultiplatform-macosx-install ${CMAKE_COMMAND} --build . --target install -- -sdk macosx DESTDIR=${RunCMake_TEST_BINARY_DIR}/_install_macosx) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) + unset(RunCMake_TEST_OPTIONS) +endif() diff --git a/Tests/RunCMake/XcodeProject/XcodeMultiplatform.cmake b/Tests/RunCMake/XcodeProject/XcodeMultiplatform.cmake new file mode 100644 index 0000000..a1064f4 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeMultiplatform.cmake @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.3) +enable_language(CXX) + +set_property(GLOBAL PROPERTY XCODE_EMIT_EFFECTIVE_PLATFORM_NAME ON) + +set(CMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "macosx iphonesimulator") +set(CMAKE_MACOSX_BUNDLE true) + +add_library(library STATIC foo.cpp) + +add_executable(main main.cpp) +target_link_libraries(main library) + +install(TARGETS library ARCHIVE DESTINATION lib) |