| Attached Files | MixedFortran.zip [^] (676 bytes) 2010-02-24 13:27
VisualStudio.zip [^] (413,867 bytes) 2010-02-24 21:11
vs_mixedfortran.v2.patch [^] (17,468 bytes) 2010-06-08 22:59 [Show Content] [Hide Content]diff -ur cmake-2.8.0.orig/Source/cmGlobalVisualStudio10Win64Generator.h cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudio10Win64Generator.h
--- cmake-2.8.0.orig/Source/cmGlobalVisualStudio10Win64Generator.h 2009-11-13 10:32:56.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudio10Win64Generator.h 2010-03-02 07:25:54.000000000 -0800
@@ -32,5 +32,7 @@
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *, bool optional);
+protected:
+ virtual bool IsWin64() const { return true; }
};
#endif
diff -ur cmake-2.8.0.orig/Source/cmGlobalVisualStudio7Generator.cxx cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudio7Generator.cxx
--- cmake-2.8.0.orig/Source/cmGlobalVisualStudio7Generator.cxx 2009-11-13 10:32:56.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudio7Generator.cxx 2010-03-03 15:07:27.000000000 -0800
@@ -14,6 +14,7 @@
#include "cmGeneratedFileStream.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
+#include "cmSourceFile.h"
#include "cmake.h"
cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator()
@@ -597,6 +598,9 @@
this->CreateGUID("EDIT_CACHE");
this->CreateGUID("REBUILD_CACHE");
this->CreateGUID("PACKAGE");
+
+ // Fix targets with mixed C/C++ and Fortran code into separate projects
+ this->FixMixedFortranTargets();
}
//----------------------------------------------------------------------------
@@ -637,6 +641,106 @@
return true;
}
+void cmGlobalVisualStudio7Generator::FixMixedFortranTargets()
+{
+ std::vector<cmLocalGenerator*> lgs = this->GetLocalGenerators();
+ for(std::vector<cmLocalGenerator*>::const_iterator lgl = lgs.begin(); lgl != lgs.end(); lgl++)
+ {
+ cmLocalGenerator *lg = *lgl;
+ cmMakefile *mf = lg->GetMakefile();
+ cmTargets &tgts = mf->GetTargets();
+ for(cmTargets::iterator tl = tgts.begin(); tl != tgts.end(); tl++)
+ {
+ cmTarget& target = tl->second;
+ switch(target.GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::EXECUTABLE:
+ // See if any of the source files for the target are Fortran files
+ const std::vector<cmSourceFile*> sfiles = target.GetSourceFiles();
+ std::vector<cmSourceFile*> fortran_files, non_fortran_files;
+ for(std::vector<cmSourceFile*>::const_iterator sfl = sfiles.begin(); sfl != sfiles.end(); sfl++)
+ {
+ cmSourceFile* sf = *sfl;
+ const char* sflang = sf->GetLanguage();
+ if(sflang == 0)
+ continue;
+ if(strcmp(sflang, "Fortran") != 0)
+ {
+ non_fortran_files.push_back(sf);
+ }
+ else
+ {
+ fortran_files.push_back(sf);
+ }
+ }
+
+ // If we found both Fortran and non-Fortran files, we need to create a new target
+ if(fortran_files.size() != 0 && non_fortran_files.size() != 0)
+ {
+ cmTarget fortran_target = cmTarget(target);
+
+ // Set the name of the target
+ std::string fortran_name = fortran_target.GetName();
+ fortran_name += ".Fortran";
+ fortran_target.SetType(cmTarget::STATIC_LIBRARY, fortran_name.c_str());
+
+ // Set the output directory to the original target's work dir
+ std::string outdir = mf->GetStartOutputDirectory();
+ outdir += "/";
+ outdir += lg->GetTargetDirectory(target);
+ fortran_target.SetProperty("ARCHIVE_OUTPUT_DIRECTORY", outdir.c_str());
+
+ // Clear old sources and add in the found Fortran files
+ fortran_target.ClearSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator ffl = fortran_files.begin(); ffl != fortran_files.end(); ffl++)
+ {
+ fortran_target.AddSourceFile(*ffl);
+ }
+
+ // Add the new Fortran target to the Makefile
+ mf->AddExistingTarget(fortran_name.c_str(), fortran_target);
+ this->CreateGUID(fortran_name.c_str());
+
+ // Make our new Fortran target linked into the old target.
+ mf->AddLinkLibraryForTarget(target.GetName(), fortran_name.c_str(), cmTarget::GENERAL);
+ if(target.GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ std::string fort_static_lib = mf->GetStartOutputDirectory();
+ fort_static_lib += "\\$(IntDir)\\";
+ fort_static_lib += fortran_name;
+ fort_static_lib += ".lib";
+ target.SetProperty("STATIC_LIBRARY_DEPENDENCIES", fort_static_lib.c_str());
+ }
+ target.AddUtility(fortran_name.c_str());
+
+ // Add an explicit reference to the Fortran compiler's lib directory to pick up compiler libraries
+ std::vector<std::string> ifort_reg_keys;
+ cmSystemTools::EnumerateRegistryKeys("HKEY_LOCAL_MACHINE\\SOFTWARE\\Intel\\Compilers\\Fortran", ifort_reg_keys, cmSystemTools::KeyWOW64_32);
+ std::vector<std::string>::iterator i = std::max_element(ifort_reg_keys.begin(), ifort_reg_keys.end());
+ if(i != ifort_reg_keys.end())
+ {
+ std::string valuename = *i, ifort_dir;
+ valuename += ";ProductDir";
+ cmSystemTools::ReadRegistryValue(valuename.c_str(), ifort_dir, cmSystemTools::KeyWOW64_32);
+ if(this->IsWin64())
+ {
+ ifort_dir += "lib\\intel64";
+ }
+ else
+ {
+ ifort_dir += "lib\\ia32";
+ }
+ mf->AddLinkDirectoryForTarget(target.GetName(), ifort_dir.c_str());
+ }
+ }
+ }
+ }
+ }
+}
+
//----------------------------------------------------------------------------
static cmVS7FlagTable cmVS7ExtraFlagTable[] =
{
diff -ur cmake-2.8.0.orig/Source/cmGlobalVisualStudio7Generator.h cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudio7Generator.h
--- cmake-2.8.0.orig/Source/cmGlobalVisualStudio7Generator.h 2009-11-13 10:32:56.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudio7Generator.h 2010-03-01 18:56:40.000000000 -0800
@@ -145,6 +145,8 @@
// Set during OutputSLNFile with the name of the current project.
// There is one SLN file per project.
std::string CurrentProject;
+
+ void FixMixedFortranTargets();
};
#define CMAKE_CHECK_BUILD_SYSTEM_TARGET "ZERO_CHECK"
diff -ur cmake-2.8.0.orig/Source/cmGlobalVisualStudio8Win64Generator.h cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudio8Win64Generator.h
--- cmake-2.8.0.orig/Source/cmGlobalVisualStudio8Win64Generator.h 2009-11-13 10:32:56.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudio8Win64Generator.h 2010-03-02 07:26:01.000000000 -0800
@@ -45,5 +45,7 @@
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *, bool optional);
+protected:
+ virtual bool IsWin64() const { return true; }
};
#endif
diff -ur cmake-2.8.0.orig/Source/cmGlobalVisualStudio9Win64Generator.h cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudio9Win64Generator.h
--- cmake-2.8.0.orig/Source/cmGlobalVisualStudio9Win64Generator.h 2009-11-13 10:32:56.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudio9Win64Generator.h 2010-03-02 07:26:08.000000000 -0800
@@ -45,5 +45,7 @@
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *, bool optional);
+protected:
+ virtual bool IsWin64() const { return true; }
};
#endif
diff -ur cmake-2.8.0.orig/Source/cmGlobalVisualStudioGenerator.h cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudioGenerator.h
--- cmake-2.8.0.orig/Source/cmGlobalVisualStudioGenerator.h 2009-11-13 10:32:56.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmGlobalVisualStudioGenerator.h 2010-03-02 07:25:35.000000000 -0800
@@ -74,6 +74,7 @@
virtual bool VSLinksDependencies() const { return true; }
virtual const char* GetIDEVersion() = 0;
+ virtual bool IsWin64() const { return false; }
struct TargetCompare
{
diff -ur cmake-2.8.0.orig/Source/cmLocalVisualStudio7Generator.cxx cmake-2.8.0.mixedfortran/Source/cmLocalVisualStudio7Generator.cxx
--- cmake-2.8.0.orig/Source/cmLocalVisualStudio7Generator.cxx 2009-11-13 10:32:57.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmLocalVisualStudio7Generator.cxx 2010-03-03 13:00:47.000000000 -0800
@@ -915,6 +915,10 @@
{
fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
}
+ if(const char* libdepends = target.GetProperty("STATIC_LIBRARY_DEPENDENCIES"))
+ {
+ fout << "\t\t\t\tAdditionalDependencies=\"" << libdepends<< "\"\n";
+ }
fout << "\t\t\t\tOutputFile=\""
<< this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
break;
diff -ur cmake-2.8.0.orig/Source/cmMakefile.cxx cmake-2.8.0.mixedfortran/Source/cmMakefile.cxx
--- cmake-2.8.0.orig/Source/cmMakefile.cxx 2009-11-13 10:32:57.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmMakefile.cxx 2010-03-01 13:39:28.000000000 -0800
@@ -1799,6 +1799,15 @@
return &it->second;
}
+//----------------------------------------------------------------------------
+void
+cmMakefile::AddExistingTarget(const char* name, cmTarget& target)
+{
+ cmTargets::iterator it =
+ this->Targets.insert(cmTargets::value_type(name, target)).first;
+ this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it);
+}
+
cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
{
std::string name = cname;
diff -ur cmake-2.8.0.orig/Source/cmMakefile.h cmake-2.8.0.mixedfortran/Source/cmMakefile.h
--- cmake-2.8.0.orig/Source/cmMakefile.h 2009-11-13 10:32:57.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmMakefile.h 2010-03-01 13:39:30.000000000 -0800
@@ -198,6 +198,8 @@
cmTarget* AddImportedTarget(const char* name, cmTarget::TargetType type);
cmTarget* AddNewTarget(cmTarget::TargetType type, const char* name);
+
+ void AddExistingTarget(const char* name, cmTarget& target);
/**
* Add an executable to the build.
diff -ur cmake-2.8.0.orig/Source/cmTarget.cxx cmake-2.8.0.mixedfortran/Source/cmTarget.cxx
--- cmake-2.8.0.orig/Source/cmTarget.cxx 2009-11-13 10:32:58.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmTarget.cxx 2010-03-01 11:26:27.000000000 -0800
@@ -1401,6 +1401,13 @@
}
//----------------------------------------------------------------------------
+void cmTarget::ClearSourceFiles()
+{
+ this->SourceFiles.clear();
+ this->Internal->SourceEntries.clear();
+}
+
+//----------------------------------------------------------------------------
std::vector<cmSourceFile*> const*
cmTarget::GetSourceDepends(cmSourceFile* sf)
{
diff -ur cmake-2.8.0.orig/Source/cmTarget.h cmake-2.8.0.mixedfortran/Source/cmTarget.h
--- cmake-2.8.0.orig/Source/cmTarget.h 2009-11-13 10:32:58.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/cmTarget.h 2010-03-01 07:45:34.000000000 -0800
@@ -118,6 +118,8 @@
std::vector<cmSourceFile*> const& GetSourceFiles();
void AddSourceFile(cmSourceFile* sf);
+ void ClearSourceFiles();
+
/** Get sources that must be built before the given source. */
std::vector<cmSourceFile*> const* GetSourceDepends(cmSourceFile* sf);
diff -ur cmake-2.8.0.orig/Source/kwsys/SystemTools.cxx cmake-2.8.0.mixedfortran/Source/kwsys/SystemTools.cxx
--- cmake-2.8.0.orig/Source/kwsys/SystemTools.cxx 2009-11-13 10:33:02.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/kwsys/SystemTools.cxx 2010-03-02 11:33:54.000000000 -0800
@@ -838,6 +838,182 @@
}
#endif
+// Enumerate all keys under a registry key.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+bool SystemTools::EnumerateRegistryKeys(const char *key, kwsys_stl::vector<kwsys_stl::string>& keys, KeyWOW64 view)
+{
+ bool valueset = true;
+ kwsys_stl::string primary = key;
+ kwsys_stl::string second;
+
+ size_t start = primary.find("\\");
+ if (start == kwsys_stl::string::npos)
+ {
+ return false;
+ }
+
+ second = primary.substr(start+1);
+ primary = primary.substr(0, start);
+
+ HKEY primaryKey = HKEY_CURRENT_USER;
+ if (primary == "HKEY_CURRENT_USER")
+ {
+ primaryKey = HKEY_CURRENT_USER;
+ }
+ if (primary == "HKEY_CURRENT_CONFIG")
+ {
+ primaryKey = HKEY_CURRENT_CONFIG;
+ }
+ if (primary == "HKEY_CLASSES_ROOT")
+ {
+ primaryKey = HKEY_CLASSES_ROOT;
+ }
+ if (primary == "HKEY_LOCAL_MACHINE")
+ {
+ primaryKey = HKEY_LOCAL_MACHINE;
+ }
+ if (primary == "HKEY_USERS")
+ {
+ primaryKey = HKEY_USERS;
+ }
+
+ HKEY hKey;
+ if(RegOpenKeyEx(primaryKey,
+ second.c_str(),
+ 0,
+ SystemToolsMakeRegistryMode(KEY_READ, view),
+ &hKey) != ERROR_SUCCESS)
+ {
+ return false;
+ }
+ else
+ {
+ DWORD dwSize, dwKeyCount, dwMaxLen;
+ dwSize = 1023;
+ if(RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwKeyCount, &dwMaxLen, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+ {
+ for(DWORD i = 0; i < dwKeyCount; i++)
+ {
+ TCHAR tStr[256];
+ dwSize = 256;
+ if(RegEnumKeyEx(hKey, i, tStr, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+ {
+ kwsys_stl::string subkey = key;
+ subkey += "\\";
+ subkey += tStr;
+ keys.push_back(subkey);
+ }
+ else
+ {
+ valueset = false;
+ }
+ }
+ }
+ else
+ {
+ valueset = false;
+ }
+
+ RegCloseKey(hKey);
+ }
+
+ return valueset;
+}
+#else
+bool SystemTools::EnumerateRegistryKeys(const char *, kwsys_stl::vector<kwsys_stl::string>&, KeyWOW64)
+{
+ return false;
+}
+#endif
+
+// Enumerate all values under a registry key.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+bool SystemTools::EnumerateRegistryValues(const char *key, kwsys_stl::vector<kwsys_stl::string>& values, KeyWOW64 view)
+{
+ bool valueset = true;
+ kwsys_stl::string primary = key;
+ kwsys_stl::string second;
+
+ size_t start = primary.find("\\");
+ if (start == kwsys_stl::string::npos)
+ {
+ return false;
+ }
+
+ second = primary.substr(start+1);
+ primary = primary.substr(0, start);
+
+ HKEY primaryKey = HKEY_CURRENT_USER;
+ if (primary == "HKEY_CURRENT_USER")
+ {
+ primaryKey = HKEY_CURRENT_USER;
+ }
+ if (primary == "HKEY_CURRENT_CONFIG")
+ {
+ primaryKey = HKEY_CURRENT_CONFIG;
+ }
+ if (primary == "HKEY_CLASSES_ROOT")
+ {
+ primaryKey = HKEY_CLASSES_ROOT;
+ }
+ if (primary == "HKEY_LOCAL_MACHINE")
+ {
+ primaryKey = HKEY_LOCAL_MACHINE;
+ }
+ if (primary == "HKEY_USERS")
+ {
+ primaryKey = HKEY_USERS;
+ }
+
+ HKEY hKey;
+ if(RegOpenKeyEx(primaryKey,
+ second.c_str(),
+ 0,
+ SystemToolsMakeRegistryMode(KEY_READ, view),
+ &hKey) != ERROR_SUCCESS)
+ {
+ return false;
+ }
+ else
+ {
+ DWORD dwSize, dwValueCount, dwMaxLen;
+ dwSize = 1023;
+ if(RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwValueCount, &dwMaxLen, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+ {
+ for(DWORD i = 0; i < dwValueCount; i++)
+ {
+ TCHAR tStr[16384];
+ dwSize = 16384;
+ if(RegEnumValue(hKey, i, tStr, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+ {
+ kwsys_stl::string value = key;
+ value += ";";
+ value += tStr;
+ values.push_back(value);
+ }
+ else
+ {
+ valueset = false;
+ }
+ }
+ }
+ else
+ {
+ valueset = false;
+ }
+
+ RegCloseKey(hKey);
+ }
+
+ return valueset;
+}
+#else
+bool SystemTools::EnumerateRegistryValues(const char *, kwsys_stl::vector<kwsys_stl::string>&, KeyWOW64)
+{
+ return false;
+}
+#endif
+
bool SystemTools::SameFile(const char* file1, const char* file2)
{
#ifdef _WIN32
diff -ur cmake-2.8.0.orig/Source/kwsys/SystemTools.hxx.in cmake-2.8.0.mixedfortran/Source/kwsys/SystemTools.hxx.in
--- cmake-2.8.0.orig/Source/kwsys/SystemTools.hxx.in 2009-11-13 10:33:02.000000000 -0800
+++ cmake-2.8.0.mixedfortran/Source/kwsys/SystemTools.hxx.in 2010-03-03 07:37:35.000000000 -0800
@@ -743,6 +743,20 @@
static bool DeleteRegistryValue(const char *key,
KeyWOW64 view = KeyWOW64_Default);
+ /**
+ * Enumerate all registry keys under a given key
+ */
+ static bool EnumerateRegistryKeys(const char *key,
+ kwsys_stl::vector<kwsys_stl::string>& keys,
+ KeyWOW64 view = KeyWOW64_Default);
+
+ /**
+ * Enumerate all registry values under a given key
+ */
+ static bool EnumerateRegistryValues(const char *key,
+ kwsys_stl::vector<kwsys_stl::string>& values,
+ KeyWOW64 view = KeyWOW64_Default);
+
/** -----------------------------------------------------------------
* Environment Manipulation Routines
* -----------------------------------------------------------------
|