diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 93842721e8..5387f02605 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -4550,32 +4550,35 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( } if (this->MSTools) { - if (this->GeneratorTarget->IsWin32Executable(config)) { - if (this->GlobalGenerator->TargetsWindowsCE()) { - linkOptions.AddFlag("SubSystem", "WindowsCE"); - if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { - if (this->ClOptions[config]->UsingUnicode()) { - linkOptions.AddFlag("EntryPointSymbol", "wWinMainCRTStartup"); - } else { - linkOptions.AddFlag("EntryPointSymbol", "WinMainCRTStartup"); + if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { + // Specify an entry point for executables. + if (this->GeneratorTarget->IsWin32Executable(config)) { + if (this->GlobalGenerator->TargetsWindowsCE()) { + linkOptions.AddFlag("SubSystem", "WindowsCE"); + if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { + if (this->ClOptions[config]->UsingUnicode()) { + linkOptions.AddFlag("EntryPointSymbol", "wWinMainCRTStartup"); + } else { + linkOptions.AddFlag("EntryPointSymbol", "WinMainCRTStartup"); + } } + } else { + linkOptions.AddFlag("SubSystem", "Windows"); } } else { - linkOptions.AddFlag("SubSystem", "Windows"); + if (this->GlobalGenerator->TargetsWindowsCE()) { + linkOptions.AddFlag("SubSystem", "WindowsCE"); + if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { + if (this->ClOptions[config]->UsingUnicode()) { + linkOptions.AddFlag("EntryPointSymbol", "mainWCRTStartup"); + } else { + linkOptions.AddFlag("EntryPointSymbol", "mainACRTStartup"); + } + } + } else { + linkOptions.AddFlag("SubSystem", "Console"); + }; } - } else { - if (this->GlobalGenerator->TargetsWindowsCE()) { - linkOptions.AddFlag("SubSystem", "WindowsCE"); - if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { - if (this->ClOptions[config]->UsingUnicode()) { - linkOptions.AddFlag("EntryPointSymbol", "mainWCRTStartup"); - } else { - linkOptions.AddFlag("EntryPointSymbol", "mainACRTStartup"); - } - } - } else { - linkOptions.AddFlag("SubSystem", "Console"); - }; } if (cmValue stackVal = this->Makefile->GetDefinition( @@ -4660,6 +4663,26 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( } } + if (this->ProjectType == VsProjectType::vcxproj && this->MSTools) { + // Suppress MSBuild default settings for which the project + // specifies no flags. + if (!linkOptions.HasFlag("DataExecutionPrevention")) { + linkOptions.AddFlag("DataExecutionPrevention", ""); + } + if (!linkOptions.HasFlag("ImageHasSafeExceptionHandlers")) { + linkOptions.AddFlag("ImageHasSafeExceptionHandlers", ""); + } + if (!linkOptions.HasFlag("LinkErrorReporting")) { + linkOptions.AddFlag("LinkErrorReporting", ""); + } + if (!linkOptions.HasFlag("RandomizedBaseAddress")) { + linkOptions.AddFlag("RandomizedBaseAddress", ""); + } + if (!linkOptions.HasFlag("SubSystem")) { + linkOptions.AddFlag("SubSystem", ""); + } + } + this->LinkOptions[config] = std::move(pOptions); return true; } diff --git a/Tests/RunCMake/VS10Project/VsDefaultFlags-check.cmake b/Tests/RunCMake/VS10Project/VsDefaultFlags-check.cmake index 724d63ccd5..afecdf3535 100644 --- a/Tests/RunCMake/VS10Project/VsDefaultFlags-check.cmake +++ b/Tests/RunCMake/VS10Project/VsDefaultFlags-check.cmake @@ -1,4 +1,4 @@ -macro(VsDefaultFlags_check tgt) +macro(VsDefaultCompilerFlags_check tgt) set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/${tgt}.vcxproj") if(NOT EXISTS "${vcProjectFile}") set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not exist.") @@ -38,4 +38,83 @@ macro(VsDefaultFlags_check tgt) endif() endmacro() -VsDefaultFlags_check(empty) +macro(VsDefaultLinkerFlags_check tgt needs_subsystem_console) + set(HAVE_DataExecutionPrevention 0) + set(HAVE_ImageHasSafeExceptionHandlers 0) + set(HAVE_LinkErrorReporting 0) + set(HAVE_RandomizedBaseAddress 0) + set(HAVE_SubSystem 0) + set(HAVE_SubSystem_Console 0) + + file(STRINGS "${vcProjectFile}" lines) + foreach(line IN LISTS lines) + if(line MATCHES "^ *") + set(HAVE_DataExecutionPrevention 1) + endif() + if(line MATCHES "^ *") + set(HAVE_ImageHasSafeExceptionHandlers 1) + endif() + if(line MATCHES "^ *") + set(HAVE_LinkErrorReporting 1) + endif() + if(line MATCHES "^ *") + set(HAVE_RandomizedBaseAddress 1) + endif() + if(line MATCHES "^ *") + set(HAVE_SubSystem 1) + endif() + if(line MATCHES "^ *Console") + set(HAVE_SubSystem_Console 1) + endif() + endforeach() + + if(NOT HAVE_DataExecutionPrevention) + set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a property.") + return() + endif() + + if(NOT HAVE_ImageHasSafeExceptionHandlers) + set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a property.") + return() + endif() + + if(NOT HAVE_LinkErrorReporting) + set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a property.") + return() + endif() + + if(NOT HAVE_RandomizedBaseAddress) + set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a property.") + return() + endif() + + if(${needs_subsystem_console}) + if(HAVE_SubSystem) + set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj has a property.") + return() + endif() + + if(NOT HAVE_SubSystem_Console) + set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a property with 'Console' value.") + return() + endif() + else() + if(NOT HAVE_SubSystem) + set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a property.") + return() + endif() + + if(HAVE_SubSystem_Console) + set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj has a property with 'Console' value.") + return() + endif() + endif() +endmacro() + +VsDefaultCompilerFlags_check(emptyStatic) + +VsDefaultCompilerFlags_check(emptyShared) +VsDefaultLinkerFlags_check(emptyShared OFF) + +VsDefaultCompilerFlags_check(main) +VsDefaultLinkerFlags_check(main ON) diff --git a/Tests/RunCMake/VS10Project/VsDefaultFlags.cmake b/Tests/RunCMake/VS10Project/VsDefaultFlags.cmake index a0094385db..caeedd5a6e 100644 --- a/Tests/RunCMake/VS10Project/VsDefaultFlags.cmake +++ b/Tests/RunCMake/VS10Project/VsDefaultFlags.cmake @@ -1,2 +1,4 @@ enable_language(C) -add_library(empty empty.c) +add_library(emptyStatic STATIC empty.c) +add_library(emptyShared SHARED empty.c) +add_executable(main main.c) diff --git a/Tests/RunCMake/VS10Project/main.c b/Tests/RunCMake/VS10Project/main.c new file mode 100644 index 0000000000..d123e0977a --- /dev/null +++ b/Tests/RunCMake/VS10Project/main.c @@ -0,0 +1,4 @@ +int main(int argc, char** argv) +{ + return 0; +}