Merge topic 'fix-custom-target-with-csharp'

9040df31e2 Merge branch 'backport-fix-custom-target-with-csharp'
1acd1c2b50 CSharp: Fix regression in VS project type selection for custom target
a56edad6d6 CSharp: Fix regression in VS project type selection for custom target

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2549
This commit is contained in:
Brad King 2018-11-01 11:36:14 +00:00 committed by Kitware Robot
commit d955b4f753
9 changed files with 40 additions and 31 deletions

View File

@ -855,7 +855,7 @@ void cmExportFileGenerator::SetImportDetailProperties(
std::string propval; std::string propval;
if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) { if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
propval = p; propval = p;
} else if (target->HasLanguage("CSharp", config)) { } else if (target->IsCSharpOnly()) {
// C# projects do not have the /clr flag, so we set the property // C# projects do not have the /clr flag, so we set the property
// here to mark the target as (only) managed (i.e. no .lib file // here to mark the target as (only) managed (i.e. no .lib file
// to link to). Otherwise the COMMON_LANGUAGE_RUNTIME target // to link to). Otherwise the COMMON_LANGUAGE_RUNTIME target

View File

@ -5716,20 +5716,23 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
} }
} }
bool cmGeneratorTarget::HasLanguage(std::string const& language, bool cmGeneratorTarget::IsCSharpOnly() const
std::string const& config,
bool exclusive) const
{ {
std::set<std::string> languages; // Only certain target types may compile CSharp.
this->GetLanguages(languages, config); if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
// The "exclusive" check applies only to source files and not this->GetType() != cmStateEnums::STATIC_LIBRARY &&
// the linker language which may be affected by dependencies. this->GetType() != cmStateEnums::EXECUTABLE) {
if (exclusive && languages.size() > 1) {
return false; return false;
} }
// add linker language (if it is different from compiler languages) std::set<std::string> languages;
languages.insert(this->GetLinkerLanguage(config)); this->GetLanguages(languages, "");
return languages.count(language) > 0; // Consider an explicit linker language property, but *not* the
// computed linker language that may depend on linked targets.
const char* linkLang = this->GetProperty("LINKER_LANGUAGE");
if (linkLang && *linkLang) {
languages.insert(linkLang);
}
return languages.size() == 1 && languages.count("CSharp") > 0;
} }
void cmGeneratorTarget::ComputeLinkImplementationLanguages( void cmGeneratorTarget::ComputeLinkImplementationLanguages(
@ -6095,6 +6098,5 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
// C# targets are always managed. This language specific check // C# targets are always managed. This language specific check
// is added to avoid that the COMMON_LANGUAGE_RUNTIME target property // is added to avoid that the COMMON_LANGUAGE_RUNTIME target property
// has to be set manually for C# targets. // has to be set manually for C# targets.
return this->HasLanguage("CSharp", config) ? ManagedType::Managed return this->IsCSharpOnly() ? ManagedType::Managed : ManagedType::Native;
: ManagedType::Native;
} }

View File

@ -372,11 +372,7 @@ public:
void GetLanguages(std::set<std::string>& languages, void GetLanguages(std::set<std::string>& languages,
std::string const& config) const; std::string const& config) const;
// Evaluate if the target uses the given language for compilation bool IsCSharpOnly() const;
// and/or linking. If 'exclusive' is true, 'language' is expected
// to be the only language used in source files for the target.
bool HasLanguage(std::string const& language, std::string const& config,
bool exclusive = true) const;
void GetObjectLibrariesCMP0026( void GetObjectLibrariesCMP0026(
std::vector<cmGeneratorTarget*>& objlibs) const; std::vector<cmGeneratorTarget*>& objlibs) const;

View File

@ -98,7 +98,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
ext = ".vfproj"; ext = ".vfproj";
project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \""; project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
} }
if (t->HasLanguage("CSharp", "")) { if (t->IsCSharpOnly()) {
ext = ".csproj"; ext = ".csproj";
project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \""; project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"";
} }

View File

@ -205,12 +205,11 @@ static bool cmVS10IsTargetsFile(std::string const& path)
return cmSystemTools::Strucmp(ext.c_str(), ".targets") == 0; return cmSystemTools::Strucmp(ext.c_str(), ".targets") == 0;
} }
static std::string computeProjectFileExtension(cmGeneratorTarget const* t, static std::string computeProjectFileExtension(cmGeneratorTarget const* t)
const std::string& config)
{ {
std::string res; std::string res;
res = ".vcxproj"; res = ".vcxproj";
if (t->HasLanguage("CSharp", config)) { if (t->IsCSharpOnly()) {
res = ".csproj"; res = ".csproj";
} }
return res; return res;
@ -305,8 +304,8 @@ void cmVisualStudio10TargetGenerator::Generate()
this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) { this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
return; return;
} }
const std::string ProjectFileExtension = computeProjectFileExtension( const std::string ProjectFileExtension =
this->GeneratorTarget, *this->Configurations.begin()); computeProjectFileExtension(this->GeneratorTarget);
if (ProjectFileExtension == ".vcxproj") { if (ProjectFileExtension == ".vcxproj") {
this->ProjectType = vcxproj; this->ProjectType = vcxproj;
this->Managed = false; this->Managed = false;
@ -1398,8 +1397,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
std::string path = this->LocalGenerator->GetCurrentBinaryDirectory(); std::string path = this->LocalGenerator->GetCurrentBinaryDirectory();
path += "/"; path += "/";
path += this->Name; path += this->Name;
path += computeProjectFileExtension(this->GeneratorTarget, path += computeProjectFileExtension(this->GeneratorTarget);
*this->Configurations.begin());
path += ".filters"; path += ".filters";
cmGeneratedFileStream fout(path); cmGeneratedFileStream fout(path);
fout.SetCopyIfDifferent(true); fout.SetCopyIfDifferent(true);
@ -3800,7 +3798,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
path = lg->GetCurrentBinaryDirectory(); path = lg->GetCurrentBinaryDirectory();
path += "/"; path += "/";
path += dt->GetName(); path += dt->GetName();
path += computeProjectFileExtension(dt, *this->Configurations.begin()); path += computeProjectFileExtension(dt);
} }
ConvertToWindowsSlash(path); ConvertToWindowsSlash(path);
Elem e2(e1, "ProjectReference"); Elem e2(e1, "ProjectReference");
@ -3826,7 +3824,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
} }
// Workaround for static library C# targets // Workaround for static library C# targets
if (referenceNotManaged && dt->GetType() == cmStateEnums::STATIC_LIBRARY) { if (referenceNotManaged && dt->GetType() == cmStateEnums::STATIC_LIBRARY) {
referenceNotManaged = !dt->HasLanguage("CSharp", ""); referenceNotManaged = !dt->IsCSharpOnly();
} }
if (referenceNotManaged) { if (referenceNotManaged) {
e2.Element("ReferenceOutputAssembly", "false"); e2.Element("ReferenceOutputAssembly", "false");

View File

@ -9,5 +9,5 @@ add_executable(CSharpOnly csharponly.cs)
target_link_libraries(CSharpOnly lib1 lib2) target_link_libraries(CSharpOnly lib1 lib2)
add_custom_target(CSharpCustom SOURCES empty.cs) add_custom_target(CSharpCustom ALL SOURCES empty.cs)
add_custom_target(custom.cs DEPENDS empty.txt) add_custom_target(custom.cs ALL DEPENDS empty.txt)

View File

@ -1,5 +1,13 @@
include(RunCMake) include(RunCMake)
function(run_TargetWithCommand)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TargetWithCommand-build)
run_cmake(TargetWithCommand)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(TargetWithCommand-build ${CMAKE_COMMAND} --build . --config Debug)
endfunction()
run_TargetWithCommand()
# Use a single build tree for a few tests without cleaning. # Use a single build tree for a few tests without cleaning.
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CommandWithOutput-build) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CommandWithOutput-build)
set(RunCMake_TEST_NO_CLEAN 1) set(RunCMake_TEST_NO_CLEAN 1)

View File

@ -0,0 +1 @@
Custom target with CSharp source

View File

@ -0,0 +1,4 @@
enable_language(CSharp)
add_custom_target(drive ALL SOURCES dummy.cs
COMMAND ${CMAKE_COMMAND} -E echo "Custom target with CSharp source")