diff options
Diffstat (limited to 'Source/cmVisualStudio10TargetGenerator.cxx')
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 604 |
1 files changed, 411 insertions, 193 deletions
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index cb6afe1..d83662e 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -10,10 +10,11 @@ #include "cmLocalVisualStudio7Generator.h" #include "cmMakefile.h" #include "cmSourceFile.h" +#include "cmSystemTools.h" #include "cmVisualStudioGeneratorOptions.h" #include "windows.h" -#include <cm_auto_ptr.hxx> +#include "cm_auto_ptr.hxx" static std::string const kWINDOWS_7_1_SDK = "Windows7.1SDK"; @@ -111,6 +112,10 @@ cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator() i != this->LinkOptions.end(); ++i) { delete i->second; } + for (OptionsMap::iterator i = this->CudaOptions.begin(); + i != this->CudaOptions.end(); ++i) { + delete i->second; + } if (!this->BuildFileStream) { return; } @@ -205,9 +210,15 @@ void cmVisualStudio10TargetGenerator::Generate() if (!this->ComputeRcOptions()) { return; } + if (!this->ComputeCudaOptions()) { + return; + } if (!this->ComputeMasmOptions()) { return; } + if (!this->ComputeNasmOptions()) { + return; + } if (!this->ComputeLinkOptions()) { return; } @@ -450,11 +461,34 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteString("<Import Project=\"" VS10_CXX_PROPS "\" />\n", 1); } this->WriteString("<ImportGroup Label=\"ExtensionSettings\">\n", 1); + if (this->GlobalGenerator->IsCudaEnabled()) { + this->WriteString("<Import Project=\"$(VCTargetsPath)\\" + "BuildCustomizations\\CUDA ", + 2); + (*this->BuildFileStream) + << cmVS10EscapeXML(this->GlobalGenerator->GetPlatformToolsetCudaString()) + << ".props\" />\n"; + } if (this->GlobalGenerator->IsMasmEnabled()) { this->WriteString("<Import Project=\"$(VCTargetsPath)\\" "BuildCustomizations\\masm.props\" />\n", 2); } + if (this->GlobalGenerator->IsNasmEnabled()) { + // Always search in the standard modules location. + std::string propsTemplate = + GetCMakeFilePath("Templates/MSBuild/nasm.props.in"); + + std::string propsLocal; + propsLocal += this->DefaultArtifactDir; + propsLocal += "\\nasm.props"; + this->ConvertToWindowsSlash(propsLocal); + this->Makefile->ConfigureFile(propsTemplate.c_str(), propsLocal.c_str(), + false, true, true); + std::string import = std::string("<Import Project=\"") + + cmVS10EscapeXML(propsLocal) + "\" />\n"; + this->WriteString(import.c_str(), 2); + } this->WriteString("</ImportGroup>\n", 1); this->WriteString("<ImportGroup Label=\"PropertySheets\">\n", 1); { @@ -505,11 +539,26 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteTargetSpecificReferences(); this->WriteString("<ImportGroup Label=\"ExtensionTargets\">\n", 1); this->WriteTargetsFileReferences(); + if (this->GlobalGenerator->IsCudaEnabled()) { + this->WriteString("<Import Project=\"$(VCTargetsPath)\\" + "BuildCustomizations\\CUDA ", + 2); + (*this->BuildFileStream) + << cmVS10EscapeXML(this->GlobalGenerator->GetPlatformToolsetCudaString()) + << ".targets\" />\n"; + } if (this->GlobalGenerator->IsMasmEnabled()) { this->WriteString("<Import Project=\"$(VCTargetsPath)\\" "BuildCustomizations\\masm.targets\" />\n", 2); } + if (this->GlobalGenerator->IsNasmEnabled()) { + std::string nasmTargets = + GetCMakeFilePath("Templates/MSBuild/nasm.targets"); + std::string import = "<Import Project=\""; + import += cmVS10EscapeXML(nasmTargets) + "\" />\n"; + this->WriteString(import.c_str(), 2); + } this->WriteString("</ImportGroup>\n", 1); if (csproj == this->ProjectType) { for (std::vector<std::string>::const_iterator i = @@ -1002,8 +1051,8 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged( std::string postfixName = cmSystemTools::UpperCase(config); postfixName += "_POSTFIX"; - std::string assemblyName = - this->GeneratorTarget->GetOutputName(config, false); + std::string assemblyName = this->GeneratorTarget->GetOutputName( + config, cmStateEnums::RuntimeBinaryArtifact); if (const char* postfix = this->GeneratorTarget->GetProperty(postfixName)) { assemblyName += postfix; } @@ -1192,16 +1241,15 @@ void cmVisualStudio10TargetGenerator::WriteGroups() // collect up group information std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); - std::vector<cmSourceFile*> classes; - if (!this->GeneratorTarget->GetConfigCommonSourceFiles(classes)) { - return; - } + + std::vector<cmGeneratorTarget::AllConfigSource> const& sources = + this->GeneratorTarget->GetAllConfigSources(); std::set<cmSourceGroup*> groupsUsed; - for (std::vector<cmSourceFile*>::const_iterator s = classes.begin(); - s != classes.end(); s++) { - cmSourceFile* sf = *s; - std::string const& source = sf->GetFullPath(); + for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si = + sources.begin(); + si != sources.end(); ++si) { + std::string const& source = si->Source->GetFullPath(); cmSourceGroup* sourceGroup = this->Makefile->FindSourceGroup(source.c_str(), sourceGroups); groupsUsed.insert(sourceGroup); @@ -1288,23 +1336,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups() this->WriteString("</ItemGroup>\n", 1); } - // Add object library contents as external objects. - std::vector<std::string> objs; - this->GeneratorTarget->UseObjectLibraries(objs, ""); - if (!objs.empty()) { - this->WriteString("<ItemGroup>\n", 1); - for (std::vector<std::string>::const_iterator oi = objs.begin(); - oi != objs.end(); ++oi) { - std::string obj = *oi; - this->WriteString("<Object Include=\"", 2); - this->ConvertToWindowsSlash(obj); - (*this->BuildFileStream) << cmVS10EscapeXML(obj) << "\">\n"; - this->WriteString("<Filter>Object Libraries</Filter>\n", 3); - this->WriteString("</Object>\n", 2); - } - this->WriteString("</ItemGroup>\n", 1); - } - this->WriteString("<ItemGroup>\n", 1); for (std::set<cmSourceGroup*>::iterator g = groupsUsed.begin(); g != groupsUsed.end(); ++g) { @@ -1322,15 +1353,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups() this->WriteString("</Filter>\n", 2); } } - if (!objs.empty()) { - this->WriteString("<Filter Include=\"Object Libraries\">\n", 2); - std::string guidName = "SG_Filter_Object Libraries"; - this->WriteString("<UniqueIdentifier>", 3); - std::string guid = this->GlobalGenerator->GetGUID(guidName.c_str()); - (*this->BuildFileStream) << "{" << guid << "}" - << "</UniqueIdentifier>\n"; - this->WriteString("</Filter>\n", 2); - } if (!resxObjs.empty() || !this->AddedFiles.empty()) { this->WriteString("<Filter Include=\"Resource Files\">\n", 2); @@ -1668,8 +1690,10 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool, // // and fail if this exceeds the maximum allowed path length. Our path // conversion uses full paths when possible to allow deeper trees. - bool forceRelative = false; - std::string sourceFile = this->ConvertPath(sf->GetFullPath(), false); + // However, CUDA 8.0 msbuild rules fail on absolute paths so for CUDA + // we must use relative paths. + bool forceRelative = sf->GetLanguage() == "CUDA"; + std::string sourceFile = this->ConvertPath(sf->GetFullPath(), forceRelative); if (this->LocalGenerator->GetVersion() == cmGlobalVisualStudioGenerator::VS10 && cmSystemTools::FileIsFullPath(sourceFile.c_str())) { @@ -1702,15 +1726,6 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool, this->Tools[tool].push_back(toolSource); } -void cmVisualStudio10TargetGenerator::WriteSources( - std::string const& tool, std::vector<cmSourceFile const*> const& sources) -{ - for (std::vector<cmSourceFile const*>::const_iterator si = sources.begin(); - si != sources.end(); ++si) { - this->WriteSource(tool, *si); - } -} - void cmVisualStudio10TargetGenerator::WriteAllSources() { if (this->GeneratorTarget->GetType() > cmStateEnums::UTILITY) { @@ -1718,105 +1733,121 @@ void cmVisualStudio10TargetGenerator::WriteAllSources() } this->WriteString("<ItemGroup>\n", 1); - std::vector<cmSourceFile const*> headerSources; - this->GeneratorTarget->GetHeaderSources(headerSources, ""); - for (std::vector<cmSourceFile const*>::const_iterator si = - headerSources.begin(); - si != headerSources.end(); ++si) { - this->WriteHeaderSource(*si); + std::vector<size_t> all_configs; + for (size_t ci = 0; ci < this->Configurations.size(); ++ci) { + all_configs.push_back(ci); } - std::vector<cmSourceFile const*> idlSources; - this->GeneratorTarget->GetIDLSources(idlSources, ""); - this->WriteSources("Midl", idlSources); - std::vector<cmSourceFile const*> objectSources; - this->GeneratorTarget->GetObjectSources(objectSources, ""); - for (std::vector<cmSourceFile const*>::const_iterator si = - objectSources.begin(); - si != objectSources.end(); ++si) { - const std::string& lang = (*si)->GetLanguage(); + std::vector<cmGeneratorTarget::AllConfigSource> const& sources = + this->GeneratorTarget->GetAllConfigSources(); + + for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si = + sources.begin(); + si != sources.end(); ++si) { std::string tool; - if (lang == "C" || lang == "CXX") { - tool = "ClCompile"; - } else if (lang == "ASM_MASM" && this->GlobalGenerator->IsMasmEnabled()) { - tool = "MASM"; - } else if (lang == "RC") { - tool = "ResourceCompile"; - } else if (lang == "CSharp") { - tool = "Compile"; + switch (si->Kind) { + case cmGeneratorTarget::SourceKindAppManifest: + tool = "AppxManifest"; + break; + case cmGeneratorTarget::SourceKindCertificate: + tool = "None"; + break; + case cmGeneratorTarget::SourceKindCustomCommand: + // Handled elsewhere. + break; + case cmGeneratorTarget::SourceKindExternalObject: + tool = "Object"; + if (this->LocalGenerator->GetVersion() < + cmGlobalVisualStudioGenerator::VS11) { + // For VS == 10 we cannot use LinkObjects to avoid linking custom + // command outputs. If an object file is generated in this target, + // then vs10 will use it in the build, and we have to list it as + // None instead of Object. + std::vector<cmSourceFile*> const* d = + this->GeneratorTarget->GetSourceDepends(si->Source); + if (d && !d->empty()) { + tool = "None"; + } + } + break; + case cmGeneratorTarget::SourceKindExtra: + this->WriteExtraSource(si->Source); + break; + case cmGeneratorTarget::SourceKindHeader: + this->WriteHeaderSource(si->Source); + break; + case cmGeneratorTarget::SourceKindIDL: + tool = "Midl"; + break; + case cmGeneratorTarget::SourceKindManifest: + // Handled elsewhere. + break; + case cmGeneratorTarget::SourceKindModuleDefinition: + tool = "None"; + break; + case cmGeneratorTarget::SourceKindObjectSource: { + const std::string& lang = si->Source->GetLanguage(); + if (lang == "C" || lang == "CXX") { + tool = "ClCompile"; + } else if (lang == "ASM_MASM" && + this->GlobalGenerator->IsMasmEnabled()) { + tool = "MASM"; + } else if (lang == "ASM_NASM" && + this->GlobalGenerator->IsNasmEnabled()) { + tool = "NASM"; + } else if (lang == "RC") { + tool = "ResourceCompile"; + } else if (lang == "CSharp") { + tool = "Compile"; + } else if (lang == "CUDA" && this->GlobalGenerator->IsCudaEnabled()) { + tool = "CudaCompile"; + } else { + tool = "None"; + } + } break; + case cmGeneratorTarget::SourceKindResx: + // Handled elsewhere. + break; + case cmGeneratorTarget::SourceKindXaml: + // Handled elsewhere. + break; } if (!tool.empty()) { - this->WriteSource(tool, *si, " "); - if (this->OutputSourceSpecificFlags(*si)) { + // Compute set of configurations to exclude, if any. + std::vector<size_t> const& include_configs = si->Configs; + std::vector<size_t> exclude_configs; + std::set_difference(all_configs.begin(), all_configs.end(), + include_configs.begin(), include_configs.end(), + std::back_inserter(exclude_configs)); + + if (si->Kind == cmGeneratorTarget::SourceKindObjectSource) { + // FIXME: refactor generation to avoid tracking XML syntax state. + this->WriteSource(tool, si->Source, " "); + bool have_nested = this->OutputSourceSpecificFlags(si->Source); + if (!exclude_configs.empty()) { + if (!have_nested) { + (*this->BuildFileStream) << ">\n"; + } + this->WriteExcludeFromBuild(exclude_configs); + have_nested = true; + } + if (have_nested) { + this->WriteString("</", 2); + (*this->BuildFileStream) << tool << ">\n"; + } else { + (*this->BuildFileStream) << " />\n"; + } + } else if (!exclude_configs.empty()) { + this->WriteSource(tool, si->Source, ">\n"); + this->WriteExcludeFromBuild(exclude_configs); this->WriteString("</", 2); (*this->BuildFileStream) << tool << ">\n"; } else { - (*this->BuildFileStream) << " />\n"; + this->WriteSource(tool, si->Source); } - } else { - this->WriteSource("None", *si); - } - } - - std::vector<cmSourceFile const*> manifestSources; - this->GeneratorTarget->GetAppManifest(manifestSources, ""); - this->WriteSources("AppxManifest", manifestSources); - - std::vector<cmSourceFile const*> certificateSources; - this->GeneratorTarget->GetCertificates(certificateSources, ""); - this->WriteSources("None", certificateSources); - - std::vector<cmSourceFile const*> externalObjects; - this->GeneratorTarget->GetExternalObjects(externalObjects, ""); - for (std::vector<cmSourceFile const*>::iterator si = externalObjects.begin(); - si != externalObjects.end();) { - if (!(*si)->GetObjectLibrary().empty()) { - si = externalObjects.erase(si); - } else { - ++si; } } - if (this->LocalGenerator->GetVersion() > - cmGlobalVisualStudioGenerator::VS10) { - // For VS >= 11 we use LinkObjects to avoid linking custom command - // outputs. Use Object for all external objects, generated or not. - this->WriteSources("Object", externalObjects); - } else { - // If an object file is generated in this target, then vs10 will use - // it in the build, and we have to list it as None instead of Object. - for (std::vector<cmSourceFile const*>::const_iterator si = - externalObjects.begin(); - si != externalObjects.end(); ++si) { - std::vector<cmSourceFile*> const* d = - this->GeneratorTarget->GetSourceDepends(*si); - this->WriteSource((d && !d->empty()) ? "None" : "Object", *si); - } - } - - std::vector<cmSourceFile const*> extraSources; - this->GeneratorTarget->GetExtraSources(extraSources, ""); - for (std::vector<cmSourceFile const*>::const_iterator si = - extraSources.begin(); - si != extraSources.end(); ++si) { - this->WriteExtraSource(*si); - } - - // Add object library contents as external objects. - std::vector<std::string> objs; - this->GeneratorTarget->UseObjectLibraries(objs, ""); - for (std::vector<std::string>::const_iterator oi = objs.begin(); - oi != objs.end(); ++oi) { - std::string obj = *oi; - this->WriteString("<Object Include=\"", 2); - this->ConvertToWindowsSlash(obj); - (*this->BuildFileStream) << cmVS10EscapeXML(obj) << "\" />\n"; - } - - if (cmSourceFile const* defsrc = - this->GeneratorTarget->GetModuleDefinitionFile("")) { - this->WriteSource("None", defsrc); - } if (this->IsMissingFiles) { this->WriteMissingFiles(); @@ -1850,7 +1881,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( std::string lang = this->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str()); std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf); - const std::string& linkLanguage = this->GeneratorTarget->GetLinkerLanguage(); + const std::string& linkLanguage = + this->GeneratorTarget->GetLinkerLanguage(""); bool needForceLang = false; // source file does not match its extension language if (lang != sourceLang) { @@ -1932,7 +1964,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( } clOptions.AddDefines(configDefines.c_str()); clOptions.SetConfiguration((*config).c_str()); - clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); + clOptions.PrependInheritedString("AdditionalOptions"); clOptions.OutputFlagMap(*this->BuildFileStream, " "); clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", "\n", lang); @@ -1995,6 +2027,19 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( return hasFlags; } +void cmVisualStudio10TargetGenerator::WriteExcludeFromBuild( + std::vector<size_t> const& exclude_configs) +{ + for (std::vector<size_t>::const_iterator ci = exclude_configs.begin(); + ci != exclude_configs.end(); ++ci) { + this->WriteString("", 3); + (*this->BuildFileStream) + << "<ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='" + << cmVS10EscapeXML(this->Configurations[*ci]) << "|" + << cmVS10EscapeXML(this->Platform) << "'\">true</ExcludedFromBuild>\n"; + } +} + void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() { cmStateEnums::TargetType ttype = this->GeneratorTarget->GetType(); @@ -2180,8 +2225,13 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( if (linkLanguage == "CXX") { clOptions.AddFlag("CompileAs", "CompileAsCpp"); } - this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, - linkLanguage, configName.c_str()); + if (linkLanguage != "CUDA") { + this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, + linkLanguage, configName.c_str()); + } + + // Check IPO related warning/error. + this->GeneratorTarget->IsIPOEnabled(configName); // Get preprocessor definitions for this directory. std::string defineFlags = @@ -2265,7 +2315,7 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( return; } this->WriteString("<ClCompile>\n", 2); - clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); + clOptions.PrependInheritedString("AdditionalOptions"); clOptions.AppendFlag("AdditionalIncludeDirectories", includes); clOptions.AppendFlag("AdditionalIncludeDirectories", "%(AdditionalIncludeDirectories)"); @@ -2369,12 +2419,111 @@ void cmVisualStudio10TargetGenerator::WriteRCOptions( rcOptions.AppendFlag("AdditionalIncludeDirectories", includes); rcOptions.AppendFlag("AdditionalIncludeDirectories", "%(AdditionalIncludeDirectories)"); + rcOptions.PrependInheritedString("AdditionalOptions"); rcOptions.OutputFlagMap(*this->BuildFileStream, " "); - rcOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); this->WriteString("</ResourceCompile>\n", 2); } +bool cmVisualStudio10TargetGenerator::ComputeCudaOptions() +{ + if (!this->GlobalGenerator->IsCudaEnabled()) { + return true; + } + for (std::vector<std::string>::const_iterator i = + this->Configurations.begin(); + i != this->Configurations.end(); ++i) { + if (!this->ComputeCudaOptions(*i)) { + return false; + } + } + return true; +} + +bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( + std::string const& configName) +{ + cmGlobalVisualStudio10Generator* gg = + static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); + CM_AUTO_PTR<Options> pOptions(new Options( + this->LocalGenerator, Options::CudaCompiler, gg->GetCudaFlagTable())); + Options& cudaOptions = *pOptions; + + // Get compile flags for CUDA in this directory. + std::string CONFIG = cmSystemTools::UpperCase(configName); + std::string configFlagsVar = std::string("CMAKE_CUDA_FLAGS_") + CONFIG; + std::string flags = + std::string(this->Makefile->GetSafeDefinition("CMAKE_CUDA_FLAGS")) + + std::string(" ") + + std::string(this->Makefile->GetSafeDefinition(configFlagsVar)); + + // Get preprocessor definitions for this directory. + std::string defineFlags = + this->GeneratorTarget->Target->GetMakefile()->GetDefineFlags(); + + cudaOptions.Parse(flags.c_str()); + cudaOptions.Parse(defineFlags.c_str()); + cudaOptions.ParseFinish(); + + if (this->GeneratorTarget->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) { + cudaOptions.AddFlag("GenerateRelocatableDeviceCode", "true"); + } else if (this->GeneratorTarget->GetPropertyAsBool( + "CUDA_PTX_COMPILATION")) { + cudaOptions.AddFlag("NvccCompilation", "ptx"); + // We drop the %(Extension) component as CMake expects all PTX files + // to not have the source file extension at all + cudaOptions.AddFlag("CompileOut", "$(IntDir)%(Filename).ptx"); + } + + // Convert the host compiler options to the toolset's abstractions + // using a secondary flag table. + cudaOptions.ClearTables(); + cudaOptions.AddTable(gg->GetCudaHostFlagTable()); + cudaOptions.Reparse("AdditionalCompilerOptions"); + + // `CUDA 8.0.targets` places these before nvcc! Just drop whatever + // did not parse and hope it works. + cudaOptions.RemoveFlag("AdditionalCompilerOptions"); + + cudaOptions.FixCudaCodeGeneration(); + + std::vector<std::string> targetDefines; + this->GeneratorTarget->GetCompileDefinitions(targetDefines, + configName.c_str(), "CUDA"); + cudaOptions.AddDefines(targetDefines); + + // Add a definition for the configuration name. + std::string configDefine = "CMAKE_INTDIR=\""; + configDefine += configName; + configDefine += "\""; + cudaOptions.AddDefine(configDefine); + if (const char* exportMacro = this->GeneratorTarget->GetExportMacro()) { + cudaOptions.AddDefine(exportMacro); + } + + this->CudaOptions[configName] = pOptions.release(); + return true; +} + +void cmVisualStudio10TargetGenerator::WriteCudaOptions( + std::string const& configName, std::vector<std::string> const& includes) +{ + if (!this->MSTools || !this->GlobalGenerator->IsCudaEnabled()) { + return; + } + this->WriteString("<CudaCompile>\n", 2); + + Options& cudaOptions = *(this->CudaOptions[configName]); + cudaOptions.AppendFlag("Include", includes); + cudaOptions.AppendFlag("Include", "%(Include)"); + cudaOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", + "\n", "CUDA"); + cudaOptions.PrependInheritedString("AdditionalOptions"); + cudaOptions.OutputFlagMap(*this->BuildFileStream, " "); + + this->WriteString("</CudaCompile>\n", 2); +} + bool cmVisualStudio10TargetGenerator::ComputeMasmOptions() { if (!this->GlobalGenerator->IsMasmEnabled()) { @@ -2427,12 +2576,77 @@ void cmVisualStudio10TargetGenerator::WriteMasmOptions( Options& masmOptions = *(this->MasmOptions[configName]); masmOptions.AppendFlag("IncludePaths", includes); masmOptions.AppendFlag("IncludePaths", "%(IncludePaths)"); + masmOptions.PrependInheritedString("AdditionalOptions"); masmOptions.OutputFlagMap(*this->BuildFileStream, " "); - masmOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); this->WriteString("</MASM>\n", 2); } +bool cmVisualStudio10TargetGenerator::ComputeNasmOptions() +{ + if (!this->GlobalGenerator->IsNasmEnabled()) { + return true; + } + for (std::vector<std::string>::const_iterator i = + this->Configurations.begin(); + i != this->Configurations.end(); ++i) { + if (!this->ComputeNasmOptions(*i)) { + return false; + } + } + return true; +} + +bool cmVisualStudio10TargetGenerator::ComputeNasmOptions( + std::string const& configName) +{ + cmGlobalVisualStudio10Generator* gg = + static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); + CM_AUTO_PTR<Options> pOptions(new Options( + this->LocalGenerator, Options::NasmCompiler, gg->GetNasmFlagTable())); + Options& nasmOptions = *pOptions; + + std::string CONFIG = cmSystemTools::UpperCase(configName); + std::string configFlagsVar = std::string("CMAKE_ASM_NASM_FLAGS_") + CONFIG; + std::string flags = + std::string(this->Makefile->GetSafeDefinition("CMAKE_ASM_NASM_FLAGS")) + + std::string(" -f") + std::string(this->Makefile->GetSafeDefinition( + "CMAKE_ASM_NASM_OBJECT_FORMAT")) + + std::string(" ") + + std::string(this->Makefile->GetSafeDefinition(configFlagsVar)); + nasmOptions.Parse(flags.c_str()); + this->NasmOptions[configName] = pOptions.release(); + return true; +} + +void cmVisualStudio10TargetGenerator::WriteNasmOptions( + std::string const& configName, std::vector<std::string> includes) +{ + if (!this->GlobalGenerator->IsNasmEnabled()) { + return; + } + this->WriteString("<NASM>\n", 2); + + Options& nasmOptions = *(this->NasmOptions[configName]); + for (size_t i = 0; i < includes.size(); i++) { + includes[i] += "\\"; + } + + nasmOptions.AppendFlag("IncludePaths", includes); + nasmOptions.AppendFlag("IncludePaths", "%(IncludePaths)"); + nasmOptions.OutputFlagMap(*this->BuildFileStream, " "); + nasmOptions.PrependInheritedString("AdditionalOptions"); + nasmOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", + "\n", "ASM_NASM"); + + // Preprocessor definitions and includes are shared with clOptions. + Options& clOptions = *(this->ClOptions[configName]); + clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", + "\n", "ASM_NASM"); + + this->WriteString("</NASM>\n", 2); +} + void cmVisualStudio10TargetGenerator::WriteLibOptions( std::string const& config) { @@ -2451,7 +2665,7 @@ void cmVisualStudio10TargetGenerator::WriteLibOptions( this->LocalGenerator, cmVisualStudioGeneratorOptions::Linker, gg->GetLibFlagTable(), 0, this); libOptions.Parse(libflags.c_str()); - libOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); + libOptions.PrependInheritedString("AdditionalOptions"); libOptions.OutputFlagMap(*this->BuildFileStream, " "); this->WriteString("</Lib>\n", 2); } @@ -2648,8 +2862,10 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( this->LocalGenerator, Options::Linker, gg->GetLinkFlagTable(), 0, this)); Options& linkOptions = *pOptions; - const std::string& linkLanguage = - this->GeneratorTarget->GetLinkerLanguage(config.c_str()); + cmGeneratorTarget::LinkClosure const* linkClosure = + this->GeneratorTarget->GetLinkClosure(config); + + const std::string& linkLanguage = linkClosure->LinkerLanguage; if (linkLanguage.empty()) { cmSystemTools::Error( "CMake can not determine linker language for target: ", @@ -2690,25 +2906,6 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( flags += " "; flags += flagsConfig; } - std::string standardLibsVar = "CMAKE_"; - standardLibsVar += linkLanguage; - standardLibsVar += "_STANDARD_LIBRARIES"; - std::string libs = - this->Makefile->GetSafeDefinition(standardLibsVar.c_str()); - // Remove trailing spaces from libs - std::string::size_type pos = libs.size() - 1; - if (!libs.empty()) { - while (libs[pos] == ' ') { - pos--; - } - } - if (pos != libs.size() - 1) { - libs = libs.substr(0, pos + 1); - } - // Replace spaces in libs with ; - std::replace(libs.begin(), libs.end(), ' ', ';'); - std::vector<std::string> libVec; - cmSystemTools::ExpandListArgument(libs, libVec); cmComputeLinkInformation* pcli = this->GeneratorTarget->GetLinkInformation(config.c_str()); @@ -2718,10 +2915,30 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( this->Name.c_str()); return false; } - // add the libraries for the target to libs string cmComputeLinkInformation& cli = *pcli; + + std::vector<std::string> libVec; std::vector<std::string> vsTargetVec; this->AddLibraries(cli, libVec, vsTargetVec); + if (std::find(linkClosure->Languages.begin(), linkClosure->Languages.end(), + "CUDA") != linkClosure->Languages.end()) { + switch (this->CudaOptions[config]->GetCudaRuntime()) { + case cmVisualStudioGeneratorOptions::CudaRuntimeStatic: + libVec.push_back("cudart_static.lib"); + break; + case cmVisualStudioGeneratorOptions::CudaRuntimeShared: + libVec.push_back("cudart.lib"); + break; + case cmVisualStudioGeneratorOptions::CudaRuntimeNone: + break; + } + } + std::string standardLibsVar = "CMAKE_"; + standardLibsVar += linkLanguage; + standardLibsVar += "_STANDARD_LIBRARIES"; + std::string const libs = + this->Makefile->GetSafeDefinition(standardLibsVar.c_str()); + cmSystemTools::ParseWindowsCommandLine(libs.c_str(), libVec); linkOptions.AddFlag("AdditionalDependencies", libVec); // Populate TargetsFileAndConfigsVec @@ -2803,8 +3020,8 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( std::string pdb = this->GeneratorTarget->GetPDBDirectory(config.c_str()); pdb += "/"; pdb += targetNamePDB; - std::string imLib = - this->GeneratorTarget->GetDirectory(config.c_str(), true); + std::string imLib = this->GeneratorTarget->GetDirectory( + config.c_str(), cmStateEnums::ImportLibraryArtifact); imLib += "/"; imLib += targetNameImport; @@ -2836,24 +3053,15 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( linkOptions.Parse(flags.c_str()); if (this->MSTools) { - if (cmSourceFile const* defsrc = - this->GeneratorTarget->GetModuleDefinitionFile("")) { - linkOptions.AddFlag("ModuleDefinitionFile", - defsrc->GetFullPath().c_str()); + cmGeneratorTarget::ModuleDefinitionInfo const* mdi = + this->GeneratorTarget->GetModuleDefinitionInfo(config); + if (mdi && !mdi->DefFile.empty()) { + linkOptions.AddFlag("ModuleDefinitionFile", mdi->DefFile.c_str()); } linkOptions.AppendFlag("IgnoreSpecificDefaultLibraries", "%(IgnoreSpecificDefaultLibraries)"); } - if ((this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY || - this->GeneratorTarget->IsExecutableWithExports()) && - this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) { - if (this->GeneratorTarget->GetPropertyAsBool( - "WINDOWS_EXPORT_ALL_SYMBOLS")) { - linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)exportall.def"); - } - } - // Hack to fix flag version selection in a common use case. // FIXME: Select flag table based on toolset instead of VS version. if (this->LocalGenerator->GetVersion() >= @@ -2940,7 +3148,7 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions( Options& linkOptions = *(this->LinkOptions[config]); this->WriteString("<Link>\n", 2); - linkOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); + linkOptions.PrependInheritedString("AdditionalOptions"); linkOptions.OutputFlagMap(*this->BuildFileStream, " "); this->WriteString("</Link>\n", 2); @@ -3063,7 +3271,9 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() this->WriteClOptions(*i, includes); // output rc compile flags <ResourceCompile></ResourceCompile> this->WriteRCOptions(*i, includes); + this->WriteCudaOptions(*i, includes); this->WriteMasmOptions(*i, includes); + this->WriteNasmOptions(*i, includes); } // output midl flags <Midl></Midl> this->WriteMidlOptions(*i, includes); @@ -3090,18 +3300,15 @@ void cmVisualStudio10TargetGenerator::WriteEvents( std::string const& configName) { bool addedPrelink = false; - if ((this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY || - this->GeneratorTarget->IsExecutableWithExports()) && - this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) { - if (this->GeneratorTarget->GetPropertyAsBool( - "WINDOWS_EXPORT_ALL_SYMBOLS")) { - addedPrelink = true; - std::vector<cmCustomCommand> commands = - this->GeneratorTarget->GetPreLinkCommands(); - this->GlobalGenerator->AddSymbolExportCommand(this->GeneratorTarget, - commands, configName); - this->WriteEvent("PreLinkEvent", commands, configName); - } + cmGeneratorTarget::ModuleDefinitionInfo const* mdi = + this->GeneratorTarget->GetModuleDefinitionInfo(configName); + if (mdi && mdi->DefFileGenerated) { + addedPrelink = true; + std::vector<cmCustomCommand> commands = + this->GeneratorTarget->GetPreLinkCommands(); + this->GlobalGenerator->AddSymbolExportCommand(this->GeneratorTarget, + commands, configName); + this->WriteEvent("PreLinkEvent", commands, configName); } if (!addedPrelink) { this->WriteEvent("PreLinkEvent", @@ -3985,3 +4192,14 @@ bool cmVisualStudio10TargetGenerator::ForceOld(const std::string& source) const CloseHandle(h); return true; } + +std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath( + const char* relativeFilePath) const +{ + // Always search in the standard modules location. + std::string path = cmSystemTools::GetCMakeRoot() + "/"; + path += relativeFilePath; + this->ConvertToWindowsSlash(path); + + return path; +} |