From 10c91ded4feda7eb027bc601f2047154cdcba776 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Wed, 30 Apr 2008 13:26:04 -0400 Subject: [PATCH] ENH: add support for Intel Fortran Visual studio IDE --- Source/cmGlobalVisualStudio71Generator.cxx | 13 +- Source/cmGlobalVisualStudio7Generator.cxx | 19 +- Source/cmGlobalVisualStudioGenerator.cxx | 15 ++ Source/cmGlobalVisualStudioGenerator.h | 3 + Source/cmLocalGenerator.cxx | 2 +- Source/cmLocalVisualStudio7Generator.cxx | 300 +++++++++++++++++++-- Source/cmLocalVisualStudio7Generator.h | 3 + Source/cmMakefile.cxx | 2 +- 8 files changed, 320 insertions(+), 37 deletions(-) diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index b3abec7a2..78bc0ec74 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -153,10 +153,19 @@ cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout, const char* dir, cmTarget& t) { - fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"" + // check to see if this is a fortran build + const char* ext = ".vcproj"; + const char* project = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""; + if(this->TargetIsFortranOnly(t)) + { + ext = ".vfproj"; + project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \""; + } + + fout << project << dspname << "\", \"" << this->ConvertToSolutionPath(dir) - << "\\" << dspname << ".vcproj\", \"{" + << "\\" << dspname << ext << "\", \"{" << this->GetGUID(dspname) << "}\"\n"; fout << "\tProjectSection(ProjectDependencies) = postProject\n"; this->WriteProjectDepends(fout, dspname, dir, t); diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 3432622d6..fa883392d 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -35,7 +35,7 @@ void cmGlobalVisualStudio7Generator mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl"); mf->AddDefinition("CMAKE_GENERATOR_RC", "rc"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); - mf->AddDefinition("CMAKE_GENERATOR_Fortran", "ifort"); + mf->AddDefinition("CMAKE_GENERATOR_FC", "ifort"); this->AddPlatformDefinitions(mf); @@ -482,12 +482,21 @@ cmGlobalVisualStudio7Generator::ConvertToSolutionPath(const char* path) // the libraries it uses are also done here void cmGlobalVisualStudio7Generator::WriteProject(std::ostream& fout, const char* dspname, - const char* dir, cmTarget&) -{ - fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"" + const char* dir, cmTarget& target) +{ + // check to see if this is a fortran build + const char* ext = ".vcproj"; + const char* project = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""; + if(this->TargetIsFortranOnly(target)) + { + ext = ".vfproj"; + project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \""; + } + + fout << project << dspname << "\", \"" << this->ConvertToSolutionPath(dir) - << "\\" << dspname << ".vcproj\", \"{" + << "\\" << dspname << ext << "\", \"{" << this->GetGUID(dspname) << "}\"\nEndProject\n"; } diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index efa9adfbc..6dd2f1f13 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -704,3 +704,18 @@ void RegisterVisualStudioMacros(const std::string& macrosFile, } } } +bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget& target) +{ + // check to see if this is a fortran build + std::set languages; + target.GetLanguages(languages); + const char* ext = ".vcproj"; + if(languages.size() == 1) + { + if(*languages.begin() == "Fortran") + { + return true; + } + } + return false; +} diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index 750418c20..ce03049f1 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -63,6 +63,9 @@ public: */ virtual void CallVisualStudioMacro(MacroName m, const char* vsSolutionFile = 0); + + // return true if target is fortran only + bool TargetIsFortranOnly(cmTarget& t); protected: virtual void CreateGUID(const char*) {} diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 9c183fc7e..b934126f9 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2616,7 +2616,7 @@ std::string cmLocalGenerator::EscapeForShell(const char* str, bool makeVars, else { cmsysSystem_Shell_GetArgumentForUnix(str, &arg[0], flags); - } + } return std::string(&arg[0]); } diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 8c5b87f87..d25962ba0 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -68,6 +68,7 @@ void cmLocalVisualStudio7Generator::AddHelperCommands() lang.insert("RC"); lang.insert("IDL"); lang.insert("DEF"); + lang.insert("Fortran"); this->CreateCustomTargetsAndCommands(lang); this->FixGlobalTargets(); } @@ -200,6 +201,9 @@ void cmLocalVisualStudio7Generator::WriteStampFiles() void cmLocalVisualStudio7Generator ::CreateSingleVCProj(const char *lname, cmTarget &target) { + this->FortranProject = + static_cast(this->GlobalGenerator) + ->TargetIsFortranOnly(target); // add to the list of projects std::string pname = lname; target.SetProperty("GENERATOR_FILE_NAME",lname); @@ -208,7 +212,14 @@ void cmLocalVisualStudio7Generator fname = this->Makefile->GetStartOutputDirectory(); fname += "/"; fname += lname; - fname += ".vcproj"; + if(this->FortranProject) + { + fname += ".vfproj"; + } + else + { + fname += ".vcproj"; + } // Generate the project file and replace it atomically with // copy-if-different. We use a separate timestamp so that the IDE @@ -286,7 +297,61 @@ void cmLocalVisualStudio7Generator::WriteConfigurations(std::ostream& fout, } fout << "\t\n"; } +cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] = +{ + {"Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0}, + {"SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0}, + {"DebugInformationFormat", "Zi", "full debug", "debugEnabled", 0}, + {"DebugInformationFormat", "debug:full", "full debug", "debugEnabled", 0}, + {"DebugInformationFormat", "Z7", "c7 compat", "debugOldStyleInfo", 0}, + {"DebugInformationFormat", "Zd", "line numbers", "debugLineInfoOnly", 0}, + {"Optimization", "Od", "disable optimization", "optimizeDisabled", 0}, + {"Optimization", "O1", "min space", "optimizeMinSpace", 0}, + {"Optimization", "O3", "full optimize", "optimizeFull", 0}, + {"GlobalOptimizations", "Og", "global optimize", "true", 0}, + {"InlineFunctionExpansion", "Ob0", "", "expandDisable", 0}, + {"InlineFunctionExpansion", "Ob1", "", "expandOnlyInline", 0}, + {"FavorSizeOrSpeed", "Os", "", "favorSize", 0}, + {"OmitFramePointers", "Oy-", "", "false", 0}, + {"OptimizeForProcessor", "GB", "", "procOptimizeBlended", 0}, + {"OptimizeForProcessor", "G5", "", "procOptimizePentium", 0}, + {"OptimizeForProcessor", "G6", "", "procOptimizePentiumProThruIII", 0}, + {"UseProcessorExtensions", "QzxK", "", "codeForStreamingSIMD", 0}, + {"OptimizeForProcessor", "QaxN", "", "codeForPentium4", 0}, + {"OptimizeForProcessor", "QaxB", "", "codeForPentiumM", 0}, + {"OptimizeForProcessor", "QaxP", "", "codeForCodeNamedPrescott", 0}, + {"OptimizeForProcessor", "QaxT", "", "codeForCore2Duo", 0}, + {"OptimizeForProcessor", "QxK", "", "codeExclusivelyStreamingSIMD", 0}, + {"OptimizeForProcessor", "QxN", "", "codeExclusivelyPentium4", 0}, + {"OptimizeForProcessor", "QxB", "", "codeExclusivelyPentiumM", 0}, + {"OptimizeForProcessor", "QxP", "", "codeExclusivelyCodeNamedPrescott", 0}, + {"OptimizeForProcessor", "QxT", "", "codeExclusivelyCore2Duo", 0}, + {"OptimizeForProcessor", "QxO", "", "codeExclusivelyCore2StreamingSIMD", 0}, + {"OptimizeForProcessor", "QxS", "", "codeExclusivelyCore2StreamingSIMD4", 0}, + {"ModulePath", "module:", "", "", + cmVS7FlagTable::UserValueRequired}, + {"LoopUnrolling", "Qunroll:", "", "", + cmVS7FlagTable::UserValueRequired}, + {"AutoParallelThreshold", "Qpar-threshold:", "", "", + cmVS7FlagTable::UserValueRequired}, + {"HeapArrays", "heap-arrays:", "", "", + cmVS7FlagTable::UserValueRequired}, + {"ObjectText", "bintext:", "", "", + cmVS7FlagTable::UserValueRequired}, + {"Parallelization", "Qparallel", "", "true", 0}, + {"PrefetchInsertion", "Qprefetch-", "", "false", 0}, + {"BufferedIO", "assume:buffered_io", "", "true", 0}, + {"CallingConvention", "iface:stdcall", "", "callConventionStdCall", 0}, + {"CallingConvention", "iface:cref", "", "callConventionCRef", 0}, + {"CallingConvention", "iface:stdref", "", "callConventionStdRef", 0}, + {"CallingConvention", "iface:stdcall", "", "callConventionStdCall", 0}, + {"CallingConvention", "iface:cvf", "", "callConventionCVF", 0}, + {"EnableRecursion", "recursive", "", "true", 0}, + {"ReentrantCode", "reentrancy", "", "true", 0}, + // done up to Language + {0,0,0,0,0} +}; // fill the table here currently the comment field is not used for // anything other than documentation NOTE: Make sure the longer // commandFlag comes FIRST! @@ -379,6 +444,8 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] = {0,0,0,0,0} }; + + cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] = { // option flags (some flags map to the same option) @@ -404,7 +471,8 @@ public: enum Tool { Compiler, - Linker + Linker, + FortranCompiler }; cmLocalVisualStudio7GeneratorOptions(cmLocalVisualStudio7Generator* lg, int version, @@ -485,13 +553,16 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // 1 == executable // 10 == utility const char* configType = "10"; + const char* projectType = 0; switch(target.GetType()) { case cmTarget::STATIC_LIBRARY: + projectType = "typeStaticLibrary"; configType = "4"; break; case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: + projectType = "typeDynamicLibrary"; configType = "2"; break; case cmTarget::EXECUTABLE: @@ -503,7 +574,10 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, default: break; } - + if(this->FortranProject && projectType) + { + configType = projectType; + } std::string flags; if(strcmp(configType, "10") != 0) { @@ -516,7 +590,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, target.GetName()); return; } - if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0) + if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0 + || strcmp(linkLanguage, "Fortran") == 0) { std::string baseFlagVar = "CMAKE_"; baseFlagVar += linkLanguage; @@ -551,9 +626,12 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // Get preprocessor definitions for this directory. std::string defineFlags = this->Makefile->GetDefineFlags(); - - // Construct a set of build options for this target. - Options targetOptions(this, this->Version, Options::Compiler, this->ExtraFlagTable); + Options::Tool t = Options::Compiler; + if(this->FortranProject) + { + t = Options::FortranCompiler; + } + Options targetOptions(this, this->Version, t, this->ExtraFlagTable); targetOptions.FixExceptionHandlingDefault(); targetOptions.Parse(flags.c_str()); targetOptions.Parse(defineFlags.c_str()); @@ -599,9 +677,31 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, { fout << "\t\t\tCharacterSet=\"2\">\n"; } - + const char* tool = "VCCLCompilerTool"; + if(this->FortranProject) + { + tool = "VFFortranCompilerTool"; + } fout << "\t\t\tFortranProject) + { + const char* target_mod_dir = + target.GetProperty("Fortran_MODULE_DIRECTORY"); + std::string modDir; + if(target_mod_dir) + { + modDir = this->Convert(target_mod_dir, + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::UNCHANGED); + } + else + { + modDir = "."; + } + fout << "\t\t\t\tModulePath=\"" + << this->ConvertToXMLOutputPath(modDir.c_str()) << "\\$(ConfigurationName)\"\n"; + } targetOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n"); fout << "\t\t\t\tAdditionalIncludeDirectories=\""; std::vector includes; @@ -609,8 +709,18 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, std::vector::iterator i = includes.begin(); for(;i != includes.end(); ++i) { + // output the include path std::string ipath = this->ConvertToXMLOutputPath(i->c_str()); fout << ipath << ";"; + // if this is fortran then output the include with + // a ConfigurationName on the end of it. + if(this->FortranProject) + { + ipath = i->c_str(); + ipath += "/$(ConfigurationName)"; + ipath = this->ConvertToXMLOutputPath(ipath.c_str()); + fout << ipath << ";"; + } } fout << "\"\n"; targetOptions.OutputFlagMap(fout, "\t\t\t\t"); @@ -629,8 +739,18 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, << target.GetPDBName(configName) << "\"\n"; } fout << "/>\n"; // end of \n"; - fout << "\t\t\tFortranProject) + { + tool = "VFCustomBuildTool"; + } + fout << "\t\t\t\n"; + tool = "VCResourceCompilerTool"; + if(this->FortranProject) + { + tool = "VFResourceCompilerTool"; + } + fout << "\t\t\t\n"; - - fout << "\t\t\tFortranProject) + { + tool = "VFMIDLTool"; + } + fout << "\t\t\tPlatformName == "x64" ) @@ -675,8 +799,13 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // Add a flag telling the manifest tool to use a workaround // for FAT32 file systems, which can cause an empty manifest // to be embedded into the resulting executable. See CMake - // bug #2617. - fout << "\t\t\tFortranProject) + { + tool = "VFManifestTool"; + } + fout << "\t\t\t\n"; } @@ -757,8 +886,13 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, std::string libpath = target.GetDirectory(configName); libpath += "/"; libpath += targetNameFull; + const char* tool = "VCLibrarianTool"; + if(this->FortranProject) + { + tool = "VFLibrarianTool"; + } fout << "\t\t\tFortranProject) + { + tool = "VFLinkerTool"; + } fout << "\t\t\tFortranProject) + { + tool = "VFLinkerTool"; + } fout << "\t\t\tFortranProject) + { + aCompilerTool = "VFMIDLTool"; + } } if(ext == "rc") { - aCompilerTool = "VCResourceCompilerTool"; + aCompilerTool = "VCResourceCompilerTool"; + if(this->FortranProject) + { + aCompilerTool = "VFResourceCompilerTool"; + } } if(ext == "def") { aCompilerTool = "VCCustomBuildTool"; + if(this->FortranProject) + { + aCompilerTool = "VFCustomBuildTool"; + } } for(std::map::const_iterator fci = fcinfo.FileConfigMap.begin(); @@ -1346,7 +1500,16 @@ WriteCustomRule(std::ostream& fout, std::vector *configs = static_cast (this->GlobalGenerator)->GetConfigurations(); - + const char* compileTool = "VCCLCompilerTool"; + if(this->FortranProject) + { + compileTool = "VFCLCompilerTool"; + } + const char* customTool = "VCCustomBuildTool"; + if(this->FortranProject) + { + customTool = "VFCustomBuildTool"; + } for(i = configs->begin(); i != configs->end(); ++i) { cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[*i]; @@ -1355,7 +1518,7 @@ WriteCustomRule(std::ostream& fout, if(!fc.CompileFlags.empty()) { fout << "\t\t\t\t\tEscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n"; } @@ -1367,7 +1530,7 @@ WriteCustomRule(std::ostream& fout, command.GetEscapeOldStyle(), command.GetEscapeAllowMakeVars()); fout << "\t\t\t\t\tEscapeForXML(comment.c_str()) << "\"\n" << "\t\t\t\t\tCommandLine=\"" @@ -1450,9 +1613,13 @@ void cmLocalVisualStudio7Generator { return; } - + const char* tool = "VCPreBuildEventTool"; + if(this->FortranProject) + { + tool = "VFPreBuildEventTool"; + } // add the pre build rules - fout << "\t\t\t::const_iterator cr = target.GetPreBuildCommands().begin(); @@ -1488,7 +1655,12 @@ void cmLocalVisualStudio7Generator fout << "/>\n"; // add the pre Link rules - fout << "\t\t\tFortranProject) + { + tool = "VFPreLinkEventTool"; + } + fout << "\t\t\t::const_iterator cr = target.GetPreLinkCommands().begin(); @@ -1524,7 +1696,12 @@ void cmLocalVisualStudio7Generator fout << "/>\n"; // add the PostBuild rules - fout << "\t\t\tFortranProject) + { + tool = "VFPostBuildEventTool"; + } + fout << "\t\t\t::const_iterator cr = target.GetPostBuildCommands().begin(); @@ -1560,12 +1737,77 @@ void cmLocalVisualStudio7Generator fout << "/>\n"; } +void +cmLocalVisualStudio7Generator +::WriteProjectStartFortran(std::ostream& fout, + const char *libName, + cmTarget & target) +{ + + cmGlobalVisualStudio7Generator* gg = + static_cast(this->GlobalGenerator); + fout << "\n" + << "\n"; + } + fout<< "\tKeyword=\"" << keyword << "\">\n" + << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\">\n" + << "\t\n" + << "\t\tPlatformName << "\"/>\n" + << "\t\n"; +} + + void cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout, const char *libName, cmTarget & target, std::vector &) { + if(this->FortranProject) + { + this->WriteProjectStartFortran(fout, libName, target); + return; + } fout << "\n" << "FlagTable = cmLocalVisualStudio7GeneratorFlagTable; break; case Linker: this->FlagTable = cmLocalVisualStudio7GeneratorLinkFlagTable; break; + case FortranCompiler: + this->FlagTable = cmLocalVisualStudio7GeneratorFortranFlagTable; default: break; } } diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index b59936245..edb90aa87 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -102,6 +102,8 @@ private: void OutputModuleDefinitionFile(std::ostream& fout, cmTarget &target); void WriteProjectStart(std::ostream& fout, const char *libName, cmTarget &tgt, std::vector &sgs); + void WriteProjectStartFortran(std::ostream& fout, const char *libName, + cmTarget &tgt); void WriteVCProjBeginGroup(std::ostream& fout, const char* group, const char* filter); @@ -124,6 +126,7 @@ private: cmVS7FlagTable const* ExtraFlagTable; std::string ModuleDefinitionFile; int Version; + bool FortranProject; std::string PlatformName; // Win32 or x64 cmLocalVisualStudio7GeneratorInternals* Internal; }; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 3a208c30d..4cd9d0a9c 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -83,7 +83,7 @@ cmMakefile::cmMakefile() this->AddSourceGroup("", "^.*$"); this->AddSourceGroup ("Source Files", - "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat)$"); + "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|f|f90|for|fpp|ftn|m|mm|rc|def|r|odl|idl|hpj|bat)$"); this->AddSourceGroup("Header Files", "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$"); this->AddSourceGroup("CMake Rules", "\\.rule$");