Browse Source

unify mayapath.cxx and mayaWrapper.cxx

David Rose 14 years ago
parent
commit
e893b91a17

+ 24 - 0
dtool/src/dtoolutil/filename.I

@@ -64,6 +64,18 @@ Filename(const Filename &copy) :
 {
 {
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: Filename::text_filename named constructor
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE Filename Filename::
+text_filename(const Filename &filename) {
+  Filename result(filename);
+  result.set_text();
+  return result;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Filename::text_filename named constructor
 //     Function: Filename::text_filename named constructor
 //       Access: Published
 //       Access: Published
@@ -76,6 +88,18 @@ text_filename(const string &filename) {
   return result;
   return result;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: Filename::binary_filename named constructor
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE Filename Filename::
+binary_filename(const Filename &filename) {
+  Filename result(filename);
+  result.set_binary();
+  return result;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Filename::binary_filename named constructor
 //     Function: Filename::binary_filename named constructor
 //       Access: Published
 //       Access: Published

+ 2 - 0
dtool/src/dtoolutil/filename.h

@@ -75,7 +75,9 @@ PUBLISHED:
   // Static constructors to explicitly create a filename that refers
   // Static constructors to explicitly create a filename that refers
   // to a text or binary file.  This is in lieu of calling set_text()
   // to a text or binary file.  This is in lieu of calling set_text()
   // or set_binary() or set_type().
   // or set_binary() or set_type().
+  INLINE static Filename text_filename(const Filename &filename);
   INLINE static Filename text_filename(const string &filename);
   INLINE static Filename text_filename(const string &filename);
+  INLINE static Filename binary_filename(const Filename &filename);
   INLINE static Filename binary_filename(const string &filename);
   INLINE static Filename binary_filename(const string &filename);
   INLINE static Filename dso_filename(const string &filename);
   INLINE static Filename dso_filename(const string &filename);
   INLINE static Filename executable_filename(const string &filename);
   INLINE static Filename executable_filename(const string &filename);

+ 33 - 24
makepanda/makepanda.py

@@ -5176,55 +5176,64 @@ for VER in MAYAVERSIONS:
     TargetAdd('libmayapview'+VNUM+'.mll', opts=['ADVAPI', VER])
     TargetAdd('libmayapview'+VNUM+'.mll', opts=['ADVAPI', VER])
 
 
     TargetAdd('maya2egg'+VNUM+'_mayaToEgg.obj', opts=OPTS, input='mayaToEgg.cxx')
     TargetAdd('maya2egg'+VNUM+'_mayaToEgg.obj', opts=OPTS, input='mayaToEgg.cxx')
-    TargetAdd('maya2egg'+VNUM+'-wrapped.exe', input='maya2egg'+VNUM+'_mayaToEgg.obj')
-    TargetAdd('maya2egg'+VNUM+'-wrapped.exe', input='libmayaegg'+VNUM+'.lib')
-    TargetAdd('maya2egg'+VNUM+'-wrapped.exe', input='libmaya'+VNUM+'.lib')
+    TargetAdd('maya2egg'+VNUM+'_bin.exe', input='maya2egg'+VNUM+'_mayaToEgg.obj')
+    TargetAdd('maya2egg'+VNUM+'_bin.exe', input='libmayaegg'+VNUM+'.lib')
+    TargetAdd('maya2egg'+VNUM+'_bin.exe', input='libmaya'+VNUM+'.lib')
     if (sys.platform.startswith("win")):
     if (sys.platform.startswith("win")):
-      TargetAdd('maya2egg'+VNUM+'-wrapped.exe', input=COMMON_EGG2X_LIBS_PYSTUB)
+      TargetAdd('maya2egg'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS_PYSTUB)
     else:
     else:
-      TargetAdd('maya2egg'+VNUM+'-wrapped.exe', input=COMMON_EGG2X_LIBS)
+      TargetAdd('maya2egg'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS)
     if (sys.platform == "darwin" and int(VNUM) >= 2009):
     if (sys.platform == "darwin" and int(VNUM) >= 2009):
-      TargetAdd('maya2egg'+VNUM+'-wrapped.exe', opts=['ADVAPI', 'NOPPC', VER])
+      TargetAdd('maya2egg'+VNUM+'_bin.exe', opts=['ADVAPI', 'NOPPC', VER])
     else:
     else:
-      TargetAdd('maya2egg'+VNUM+'-wrapped.exe', opts=['ADVAPI', VER])
+      TargetAdd('maya2egg'+VNUM+'_bin.exe', opts=['ADVAPI', VER])
 
 
     TargetAdd('egg2maya'+VNUM+'_eggToMaya.obj', opts=OPTS, input='eggToMaya.cxx')
     TargetAdd('egg2maya'+VNUM+'_eggToMaya.obj', opts=OPTS, input='eggToMaya.cxx')
-    TargetAdd('egg2maya'+VNUM+'-wrapped.exe', input='egg2maya'+VNUM+'_eggToMaya.obj')
-    TargetAdd('egg2maya'+VNUM+'-wrapped.exe', input='libmayaegg'+VNUM+'.lib')
-    TargetAdd('egg2maya'+VNUM+'-wrapped.exe', input='libmaya'+VNUM+'.lib')
+    TargetAdd('egg2maya'+VNUM+'_bin.exe', input='egg2maya'+VNUM+'_eggToMaya.obj')
+    TargetAdd('egg2maya'+VNUM+'_bin.exe', input='libmayaegg'+VNUM+'.lib')
+    TargetAdd('egg2maya'+VNUM+'_bin.exe', input='libmaya'+VNUM+'.lib')
     if (sys.platform.startswith("win")):
     if (sys.platform.startswith("win")):
-      TargetAdd('egg2maya'+VNUM+'-wrapped.exe', input=COMMON_EGG2X_LIBS_PYSTUB)
+      TargetAdd('egg2maya'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS_PYSTUB)
     else:
     else:
-      TargetAdd('egg2maya'+VNUM+'-wrapped.exe', input=COMMON_EGG2X_LIBS)
+      TargetAdd('egg2maya'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS)
     if (sys.platform == "darwin" and int(VNUM) >= 2009):
     if (sys.platform == "darwin" and int(VNUM) >= 2009):
-      TargetAdd('egg2maya'+VNUM+'-wrapped.exe', opts=['ADVAPI', 'NOPPC', VER])
+      TargetAdd('egg2maya'+VNUM+'_bin.exe', opts=['ADVAPI', 'NOPPC', VER])
     else:
     else:
-      TargetAdd('egg2maya'+VNUM+'-wrapped.exe', opts=['ADVAPI', VER])
+      TargetAdd('egg2maya'+VNUM+'_bin.exe', opts=['ADVAPI', VER])
 
 
     TargetAdd('mayacopy'+VNUM+'_mayaCopy.obj', opts=OPTS, input='mayaCopy.cxx')
     TargetAdd('mayacopy'+VNUM+'_mayaCopy.obj', opts=OPTS, input='mayaCopy.cxx')
-    TargetAdd('mayacopy'+VNUM+'-wrapped.exe', input='mayacopy'+VNUM+'_mayaCopy.obj')
-    TargetAdd('mayacopy'+VNUM+'-wrapped.exe', input='libp3cvscopy.lib')
-    TargetAdd('mayacopy'+VNUM+'-wrapped.exe', input='libmaya'+VNUM+'.lib')
+    TargetAdd('mayacopy'+VNUM+'_bin.exe', input='mayacopy'+VNUM+'_mayaCopy.obj')
+    TargetAdd('mayacopy'+VNUM+'_bin.exe', input='libp3cvscopy.lib')
+    TargetAdd('mayacopy'+VNUM+'_bin.exe', input='libmaya'+VNUM+'.lib')
     if sys.platform == "win32":
     if sys.platform == "win32":
-      TargetAdd('mayacopy'+VNUM+'-wrapped.exe', input=COMMON_EGG2X_LIBS_PYSTUB)
+      TargetAdd('mayacopy'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS_PYSTUB)
     else:
     else:
-      TargetAdd('mayacopy'+VNUM+'-wrapped.exe', input=COMMON_EGG2X_LIBS)
+      TargetAdd('mayacopy'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS)
     if (sys.platform == "darwin" and int(VNUM) >= 2009):
     if (sys.platform == "darwin" and int(VNUM) >= 2009):
-      TargetAdd('mayacopy'+VNUM+'-wrapped.exe', opts=['ADVAPI', 'NOPPC', VER])
+      TargetAdd('mayacopy'+VNUM+'_bin.exe', opts=['ADVAPI', 'NOPPC', VER])
     else:
     else:
-      TargetAdd('mayacopy'+VNUM+'-wrapped.exe', opts=['ADVAPI', VER])
+      TargetAdd('mayacopy'+VNUM+'_bin.exe', opts=['ADVAPI', VER])
 
 
     TargetAdd('mayasavepview'+VNUM+'_mayaSavePview.obj', opts=OPTS, input='mayaSavePview.cxx')
     TargetAdd('mayasavepview'+VNUM+'_mayaSavePview.obj', opts=OPTS, input='mayaSavePview.cxx')
     TargetAdd('libmayasavepview'+VNUM+'.mll', input='mayasavepview'+VNUM+'_mayaSavePview.obj')
     TargetAdd('libmayasavepview'+VNUM+'.mll', input='mayasavepview'+VNUM+'_mayaSavePview.obj')
     TargetAdd('libmayasavepview'+VNUM+'.mll', opts=['ADVAPI',  VER])
     TargetAdd('libmayasavepview'+VNUM+'.mll', opts=['ADVAPI',  VER])
 
 
-    TargetAdd('mayaWrapper'+VNUM+'.obj', opts=OPTS, input='mayaWrapper.cxx')
+    TargetAdd('mayapath'+VNUM+'.obj', opts=OPTS, input='mayapath.cxx')
 
 
-    TargetAdd('maya2egg'+VNUM+'.exe', input='mayaWrapper'+VNUM+'.obj')
+    TargetAdd('maya2egg'+VNUM+'.exe', input='mayapath'+VNUM+'.obj')
     TargetAdd('maya2egg'+VNUM+'.exe', opts=['ADVAPI'])
     TargetAdd('maya2egg'+VNUM+'.exe', opts=['ADVAPI'])
+    TargetAdd('maya2egg'+VNUM+'.exe', input=COMMON_DTOOL_LIBS)
+    TargetAdd('maya2egg'+VNUM+'.exe', input='libpandaexpress.dll')
 
 
-    TargetAdd('mayacopy'+VNUM+'.exe', input='mayaWrapper'+VNUM+'.obj')
+    TargetAdd('egg2maya'+VNUM+'.exe', input='mayapath'+VNUM+'.obj')
+    TargetAdd('egg2maya'+VNUM+'.exe', opts=['ADVAPI'])
+    TargetAdd('egg2maya'+VNUM+'.exe', input=COMMON_DTOOL_LIBS)
+    TargetAdd('egg2maya'+VNUM+'.exe', input='libpandaexpress.dll')
+
+    TargetAdd('mayacopy'+VNUM+'.exe', input='mayapath'+VNUM+'.obj')
     TargetAdd('mayacopy'+VNUM+'.exe', opts=['ADVAPI'])
     TargetAdd('mayacopy'+VNUM+'.exe', opts=['ADVAPI'])
+    TargetAdd('mayacopy'+VNUM+'.exe', input=COMMON_DTOOL_LIBS)
+    TargetAdd('mayacopy'+VNUM+'.exe', input='libpandaexpress.dll')
 
 
 #
 #
 # DIRECTORY: contrib/src/ai/
 # DIRECTORY: contrib/src/ai/

+ 1 - 0
panda/src/express/virtualFileSystem.cxx

@@ -1335,6 +1335,7 @@ do_get_file(const Filename &filename, int open_flags) const {
   }
   }
   pathname.standardize();
   pathname.standardize();
   Filename strpath = pathname.get_filename_index(0).get_fullpath().substr(1);
   Filename strpath = pathname.get_filename_index(0).get_fullpath().substr(1);
+  strpath.set_type(filename.get_type());
   // Also transparently look for a regular file suffixed .pz.
   // Also transparently look for a regular file suffixed .pz.
   Filename strpath_pz = strpath + ".pz";
   Filename strpath_pz = strpath + ".pz";
 
 

+ 8 - 4
pandatool/src/mayaprogs/Sources.pp

@@ -5,7 +5,8 @@
 #begin bin_target
 #begin bin_target
   #define TARGET maya2egg
   #define TARGET maya2egg
   #define OTHER_LIBS \
   #define OTHER_LIBS \
-    p3dtoolbase:c p3dtoolutil:c p3dtool:m p3prc:c p3dtoolconfig:m
+    p3dtoolbase:c p3dtoolutil:c p3dtool:m p3prc:c p3dtoolconfig:m \
+    p3express:c pandaexpress:m 
   #define SOURCES \
   #define SOURCES \
     mayapath.cxx
     mayapath.cxx
 #end bin_target
 #end bin_target
@@ -13,7 +14,8 @@
 #begin bin_target
 #begin bin_target
   #define TARGET maya2egg_server
   #define TARGET maya2egg_server
   #define OTHER_LIBS \
   #define OTHER_LIBS \
-    p3dtoolbase:c p3dtoolutil:c p3dtool:m p3prc:c p3dtoolconfig:m
+    p3dtoolbase:c p3dtoolutil:c p3dtool:m p3prc:c p3dtoolconfig:m \
+    p3express:c pandaexpress:m 
   #define SOURCES \
   #define SOURCES \
     mayapath.cxx
     mayapath.cxx
 #end bin_target
 #end bin_target
@@ -84,7 +86,8 @@
 #begin bin_target
 #begin bin_target
   #define TARGET egg2maya
   #define TARGET egg2maya
   #define OTHER_LIBS \
   #define OTHER_LIBS \
-    p3dtoolbase:c p3dtoolutil:c p3dtool:m p3prc:c p3dtoolconfig:m
+    p3dtoolbase:c p3dtoolutil:c p3dtool:m p3prc:c p3dtoolconfig:m \
+    p3express:c pandaexpress:m 
   #define SOURCES \
   #define SOURCES \
     mayapath.cxx
     mayapath.cxx
 #end bin_target
 #end bin_target
@@ -114,7 +117,8 @@
 #begin bin_target
 #begin bin_target
   #define TARGET mayacopy
   #define TARGET mayacopy
   #define OTHER_LIBS \
   #define OTHER_LIBS \
-    p3dtoolbase:c p3dtoolutil:c p3dtool:m p3prc:c p3dtoolconfig:m
+    p3dtoolbase:c p3dtoolutil:c p3dtool:m p3prc:c p3dtoolconfig:m \
+    p3express:c pandaexpress:m 
   #define SOURCES \
   #define SOURCES \
     mayapath.cxx
     mayapath.cxx
 #end bin_target
 #end bin_target

+ 0 - 353
pandatool/src/mayaprogs/mayaWrapper.cxx

@@ -1,353 +0,0 @@
-///////////////////////////////////////////////////////////////////////
-//
-// When multiple versions of maya are installed, maya2egg can
-// accidentally use the wrong version of the OpenMaya libraries.
-// This small wrapper program alters your PATH, MAYA_LOCATION, etc
-// environment variables in order to ensure that maya2egg finds the
-// right ligraries.
-//
-// To use this wrapper, maya2egg must be renamed to maya2egg-wrapped.
-// Then, this wrapper program must be installed as maya2egg.
-//
-///////////////////////////////////////////////////////////////////////
-
-
-#ifndef MAYAVERSION
-#error You must define the symbol MAYAVERSION when compiling mayawrapper.
-#endif
-
-#define QUOTESTR(x) #x
-#define TOSTRING(x) QUOTESTR(x)
-
-#define _CRT_SECURE_NO_DEPRECATE 1
-
-#ifdef _WIN32
-  #include <windows.h>
-  #include <winuser.h>
-  #include <process.h>
-#else
-  #include <string.h>
-  #include <sys/types.h>
-  #include <sys/stat.h>
-  #include <unistd.h>
-  #define _putenv putenv
-#endif
-#ifdef __APPLE__
-  #include <sys/malloc.h>
-#else
-  #include <malloc.h>
-#endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <limits.h>
-#define PATH_MAX 1024
-
-#ifdef __APPLE__
-  // This is for _NSGetExecutablePath().
-  #include <mach-o/dyld.h>
-#endif
-
-struct { char *ver, *key; } maya_versions[] = {
-  { "MAYA6",    "6.0" },
-  { "MAYA65",   "6.5" },
-  { "MAYA7",    "7.0" },
-  { "MAYA8",    "8.0" },
-  { "MAYA85",   "8.5" },
-  { "MAYA2008", "2008" },
-  { "MAYA2009", "2009" },
-  { "MAYA2010", "2010" },
-  { "MAYA2011", "2011"},
-  { "MAYA2012", "2012"},
-  { 0, 0 },
-};
-
-char *getVersionNumber(char *ver) {
-  for (int i=0; maya_versions[i].ver != 0; i++) {
-    if (strcmp(maya_versions[i].ver, ver)==0) {
-      return maya_versions[i].key;
-    }
-  }
-  return 0;
-}
-
-#if defined(_WIN32)
-void getMayaLocation(char *ver, char *loc)
-{
-  char fullkey[1024], *developer;
-  HKEY hkey; DWORD size, dtype; LONG res; int dev, hive;
-
-  for (dev=0; dev<3; dev++) {
-    switch (dev) {
-    case 0: developer="Alias|Wavefront"; break;
-    case 1: developer="Alias"; break;
-    case 2: developer="Autodesk"; break;
-    }
-    sprintf(fullkey, "SOFTWARE\\%s\\Maya\\%s\\Setup\\InstallPath", developer, ver);
-    for (hive=0; hive<2; hive++) {
-      loc[0] = 0;
-      res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | (hive ? 256:0), &hkey);
-      if (res == ERROR_SUCCESS) {
-        size=1024;
-        res = RegQueryValueEx(hkey, "MAYA_INSTALL_LOCATION", NULL, &dtype, (LPBYTE)loc, &size);
-        if ((res == ERROR_SUCCESS)&&(dtype == REG_SZ)) {
-          loc[size] = 0;
-          return;
-        } else {
-          loc[0] = 0;
-        }
-        RegCloseKey(hkey);
-      }
-    }
-  }
-}
-
-void getWrapperName(char *prog)
-{
-  DWORD res;
-  res = GetModuleFileName(NULL, prog, 1000);
-  if (res == 0) {
-    prog[0] = 0;
-    return;
-  }
-  int len = strlen(prog);
-  if (_stricmp(prog+len-4, ".exe")) {
-    prog[0] = 0;
-    return;
-  }
-  prog[len-4] = 0;
-}
-
-#elif defined(__APPLE__)
-void getMayaLocation(char *ver, char *loc)
-{
-  char mpath[64];
-  sprintf(mpath, "/Applications/Autodesk/maya%s/Maya.app/Contents", ver);
-  struct stat st;
-  if(stat(mpath, &st) == 0) {
-    strcpy(loc, mpath);
-  } else {
-    loc[0] = 0;
-  }
-}
-
-void getWrapperName(char *prog)
-{
-  char *pathbuf = new char[PATH_MAX];
-  uint32_t bufsize = PATH_MAX;
-  if (_NSGetExecutablePath(pathbuf, &bufsize) == 0) {
-    strcpy(prog, pathbuf);
-  } else {
-    prog[0] = 0;
-  }
-  delete[] pathbuf;
-}
-
-#else
-void getMayaLocation(char *ver, char *loc)
-{
-  char mpath[64];
-#if __WORDSIZE == 64
-  sprintf(mpath, "/usr/autodesk/maya%s-x64", ver);
-#else
-  sprintf(mpath, "/usr/autodesk/maya%s", ver);
-#endif
-  struct stat st;
-  if(stat(mpath, &st) == 0) {
-    strcpy(loc, mpath);
-  } else {
-#if __WORDSIZE == 64
-    sprintf(mpath, "/usr/aw/maya%s-x64", ver);
-#else
-    sprintf(mpath, "/usr/aw/maya%s", ver);
-#endif
-    if(stat(mpath, &st) == 0) {
-      strcpy(loc, mpath);
-    } else {
-      loc[0] = 0;
-    }
-  }
-}
-
-void getWrapperName(char *prog)
-{
-  char readlinkbuf[PATH_MAX];
-  int pathlen = readlink("/proc/self/exe", readlinkbuf, PATH_MAX-1);
-  if (pathlen > 0) {
-    readlinkbuf[pathlen] = 0;
-    strcpy(prog, readlinkbuf);
-  } else {
-    prog[0] = 0;
-  }
-}
-#endif
-
-int main(int argc, char **argv)
-{
-  char loc[PATH_MAX], prog[PATH_MAX];
-  char *key, *path, *env1, *env2, *env3, *env4;
-  int nLocLen;
-  
-  key = getVersionNumber(TOSTRING(MAYAVERSION));
-  if (key == 0) {
-    printf("MayaWrapper: unknown maya version %s\n", TOSTRING(MAYAVERSION));
-    exit(1);
-  }
-  
-  getMayaLocation(key, loc);
-  if (loc[0]==0) {
-    printf("Cannot locate %s - it does not appear to be installed\n", TOSTRING(MAYAVERSION));
-    exit(1);
-  }
-  
-  getWrapperName(prog);
-  if (prog[0]==0) {
-    printf("mayaWrapper cannot determine its own filename (bug)\n");
-    exit(1);
-  }  
-  
-#ifdef _WIN32
-  strcat(prog, "-wrapped.exe");
-#else
-  strcat(prog, "-wrapped");
-#endif
-
-  // "loc" == MAYA_LOCATION
-  // Now set PYTHONHOME & PYTHONPATH.  Maya requires this to be
-  // set and pointing within MAYA_LOCATION, or it might get itself
-  // confused with another Python installation (e.g. Panda's).
-  // Finally, prepend PATH with MAYA_LOCATION\bin; as well.
-
-// As of Sept. 2009, at least some WIN32 platforms had 
-// much difficulty with Maya 2009 egging, e.g., see forums:
-// http://www.panda3d.org/phpbb2/viewtopic.php?p=42790 
-// 
-// Historically:
-// http://www.panda3d.org/phpbb2/viewtopic.php?t=3842 
-// http://www.panda3d.org/phpbb2/viewtopic.php?t=6468 
-// http://www.panda3d.org/phpbb2/viewtopic.php?t=6533 
-// http://www.panda3d.org/phpbb2/viewtopic.php?t=5070 
-// 
-// Hoped solution:  carry over code that was in mayapath.cxx 
-// and use that here to set 4 important environment variables:
-// MAYA_LOCATION
-// PYTHONPATH
-// PYTHONHOME
-// PATH (add Maya bin to start of this)
-// BUT... mayapath.cxx makes use of FILENAME and other code
-// from the rest of the Panda build, so for now, to keep this
-// wrapper thinner, just correct/verify that the latter 3 environment
-// variables are set properly (as they are in mayapath.cxx)
-// for use with Maya under WIN32.
-// FIRST TRY, keeping PYTHONPATH simple, as just loc\Python, failed.
-// SECOND TRY, as coded formerly here (in mayaWrapper.cxx), also fails:
-//   PYTHONPATH=%s\\bin;%s\\Python;%s\\Python\\DLLs;%s\\Python\\lib;%s\\Python\\lib\\site-packages
-// Eventually, solution was found that has AT MOST this (which does NOT match mayapath.cxx....):
-//   PYTHONPATH=%s\\bin\\python25.zip;%s\\Python\\DLLs;%s\\Python\\lib;%s\\Python\\lib\\plat-win;%s\\Python\\lib\\lib-tk;%s\\bin;%s\\Python;%s\\Python\\lib\\site-packages", loc, loc, loc, loc, loc, loc, loc, loc);
-// One attempt to thin down to just the .zip file and the site-packages file works!  This seems to be minimum needed 
-// as removing the .zip file mentioned first will then break again with the dreaded:
-// "Invalid Python Environment: Python is unable to find Maya's Python modules"
-// Again, this minimal necessary set (for Maya 2009 32-bit at least) does NOT match mayapath.cxx....):
-//   PYTHONPATH=%s\\bin\\python25.zip;%s\\Python\\lib\\site-packages", loc, loc);
-// 
-
-#ifdef _WIN32
-  // Not sure of non-WIN32 environments, but for WIN32,
-  // verify that terminating directory/folder separator
-  // character \ is NOT found at end of "loc" string:
-  nLocLen = strlen(loc);
-  if (nLocLen > 0 && loc[nLocLen - 1] == '\\')
-  {
-    loc[nLocLen - 1] = '\0';
-  }
-  path = getenv("PATH");
-  if (path == 0) path = "";
-  env1 = (char*)malloc(100 + strlen(loc) + strlen(path));
-  sprintf(env1, "PATH=%s\\bin;%s", loc, path);
-  env2 = (char*)malloc(100 + strlen(loc));
-  sprintf(env2, "MAYA_LOCATION=%s", loc);
-  env3 = (char*)malloc(100 + strlen(loc));
-  sprintf(env3, "PYTHONHOME=%s\\Python", loc);
-  env4 = (char*)malloc(100 + 2*strlen(loc));
-  // FYI,  background on what does Maya (e.g., Maya 2009) expect
-  // in PYTHONPATH by doing a check of sys.paths in Python
-  // as discussed in 
-  // http://www.rtrowbridge.com/blog/2008/11/27/maya-python-import-scripts/
-  // gives this:
-  // C:\Program Files\Autodesk\Maya2009\bin\python25.zip
-  // C:\Program Files\Autodesk\Maya2009\Python\DLLs
-  // C:\Program Files\Autodesk\Maya2009\Python\lib
-  // C:\Program Files\Autodesk\Maya2009\Python\lib\plat-win
-  // C:\Program Files\Autodesk\Maya2009\Python\lib\lib-tk
-  // C:\Program Files\Autodesk\Maya2009\bin
-  // C:\Program Files\Autodesk\Maya2009\Python
-  // C:\Program Files\Autodesk\Maya2009\Python\lib\site-packages
-  // ...
-  // Experimenting and a check of 
-  // http://www.panda3d.org/phpbb2/viewtopic.php?t=3842
-  // leads to these 2 items being necessary and hopefully sufficient:
-  // bin\python25.zip (within loc)
-  // Python\lib\site-packages (within loc)
-  // ...so set PYTHONPATH accordingly:
-  if (strcmp(key, "2011") == 0 || strcmp(key, "2012") == 0) {
-    //Maya 2011 and 2012 are built against Python 2.6 so look for that one instead
-    sprintf(env4, "PYTHONPATH=%s\\bin\\python26.zip;%s\\Python\\lib\\site-packages", loc, loc);
-  } else {
-    sprintf(env4, "PYTHONPATH=%s\\bin\\python25.zip;%s\\Python\\lib\\site-packages", loc, loc);
-  }
-  // Set environment variables MAYA_LOCATION, PYTHONHOME, PYTHONPATH, PATH
-  _putenv(env2);
-  _putenv(env3);
-  _putenv(env4);
-  _putenv(env1);
-#else
-#ifdef __APPLE__
-  path = getenv("DYLD_LIBRARY_PATH");
-  if (path == 0) path = "";
-  env1 = (char*)malloc(100 + strlen(loc) + strlen(path));
-  sprintf(env1, "DYLD_LIBRARY_PATH=%s/MacOS:%s", loc, path);
-  env3 = (char*)malloc(100 + strlen(loc));
-  sprintf(env3, "PYTHONHOME=%s/Frameworks/Python.framework/Versions/Current", loc);
-  _putenv(env3);
-#else
-  path = getenv("LD_LIBRARY_PATH");
-  if (path == 0) path = "";
-  env1 = (char*)malloc(100 + strlen(loc) + strlen(path));
-  sprintf(env1, "LD_LIBRARY_PATH=%s/lib:%s", loc, path);
-#endif // __APPLE__
-  env2 = (char*)malloc(100 + strlen(loc));
-  sprintf(env2, "MAYA_LOCATION=%s", loc);
-  
-  _putenv(env1);
-  _putenv(env2);
-#endif // _WIN32
-
-  // When this is set, Panda3D will try not to use any functions from the
-  // CPython API.  This is necessary because Maya links with its own copy
-  // of Python, which may be incompatible with ours.
-  _putenv("PANDA_INCOMPATIBLE_PYTHON=1");
-  
-#ifdef _WIN32
-  STARTUPINFO si; PROCESS_INFORMATION pi;
-  char *cmd;
-  
-  cmd = GetCommandLine();
-  memset(&si, 0, sizeof(si));
-  si.cb = sizeof(STARTUPINFO);
-  if (CreateProcess(prog, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
-    WaitForSingleObject(pi.hProcess, INFINITE);
-    exit(0);
-  } else {
-    printf("Could not launch %s\n", prog);
-    exit(1);
-  }
-#else
-  if (execvp(prog, argv) == 0) {
-    exit(0);
-  } else {
-    printf("Could not launch %s\n", prog);
-    exit(1);
-  }
-#endif
-}
-

+ 238 - 22
pandatool/src/mayaprogs/mayapath.cxx

@@ -16,11 +16,31 @@
 // similar programs that invoke OpenMaya and require certain
 // similar programs that invoke OpenMaya and require certain
 // environment variables to be set first.
 // environment variables to be set first.
 
 
+// It used to duplicate code in mayaWrapper.cxx, but now the
+// functionality for these two separate programs are unified here.
+
+// If MAYAVERSION is defined at the time this is compiled, then that
+// particular version of Maya is insisted upon, and the desired Maya
+// location is found in the Registry; otherwise, we require that
+// $MAYA_LOCATION be set at runtime and points to the desired Maya
+// installation.
+
+// If MAYAVERSION is defined and $MAYA_LOCATION is also set, then we
+// check that definition of $MAYA_LOCATION is reasonable, which we
+// define as pointing to the same version of OpenMaya.dll.  If so,
+// then we use the runtime $MAYA_LOCATION, allowing the user to
+// (slightly) override the runtime Maya directory.  If $MAYA_LOCATION
+// is set but points to a different version of OpenMaya.dll, we ignore
+// it altogether and replace it with our registry data, which allows
+// the user to have MAYA_LOCATION pointing to a different version of
+// Maya without interfering with this program.
+
 #include "dtoolbase.h"
 #include "dtoolbase.h"
 #include "filename.h"
 #include "filename.h"
 #include "globPattern.h"
 #include "globPattern.h"
 #include "dSearchPath.h"
 #include "dSearchPath.h"
 #include "executionEnvironment.h"
 #include "executionEnvironment.h"
+#include "hashVal.h"
 #include <stdlib.h>
 #include <stdlib.h>
 
 
 #if defined(_WIN32)
 #if defined(_WIN32)
@@ -28,8 +48,17 @@
 #include <windows.h>
 #include <windows.h>
 #endif
 #endif
 
 
+#define QUOTESTR(x) #x
+#define TOSTRING(x) QUOTESTR(x)
+
+#ifdef IS_OSX
+static const Filename openmaya_filename = "MacOS/libOpenMaya.dylib";
+#else
+static const Filename openmaya_filename = "bin/OpenMaya.so";
+#endif  // IS_OSX
+
 // Searches for python26.zip or whatever version it is.
 // Searches for python26.zip or whatever version it is.
-Filename
+static Filename
 find_pyzip(const Filename &maya_location) {
 find_pyzip(const Filename &maya_location) {
   // This is where python26.zip appears on Windows.  Should it be in
   // This is where python26.zip appears on Windows.  Should it be in
   // other locations on other platforms?
   // other locations on other platforms?
@@ -44,6 +73,100 @@ find_pyzip(const Filename &maya_location) {
   return Filename();
   return Filename();
 }
 }
 
 
+struct { char *ver, *key; } maya_versions[] = {
+  { "MAYA6",    "6.0" },
+  { "MAYA65",   "6.5" },
+  { "MAYA7",    "7.0" },
+  { "MAYA8",    "8.0" },
+  { "MAYA85",   "8.5" },
+  { "MAYA2008", "2008" },
+  { "MAYA2009", "2009" },
+  { "MAYA2010", "2010" },
+  { "MAYA2011", "2011"},
+  { "MAYA2012", "2012"},
+  { 0, 0 },
+};
+
+static char *
+get_version_number(const char *ver) {
+  for (int i=0; maya_versions[i].ver != 0; i++) {
+    if (strcmp(maya_versions[i].ver, ver)==0) {
+      return maya_versions[i].key;
+    }
+  }
+  return 0;
+}
+
+#if defined(_WIN32)
+static void
+get_maya_location(const char *ver, string &loc) {
+  char fullkey[1024];
+  const char *developer;
+  LONG res;
+
+  for (int dev=0; dev<3; dev++) {
+    switch (dev) {
+    case 0: developer="Alias|Wavefront"; break;
+    case 1: developer="Alias"; break;
+    case 2: developer="Autodesk"; break;
+    }
+    sprintf(fullkey, "SOFTWARE\\%s\\Maya\\%s\\Setup\\InstallPath", developer, ver);
+    for (int hive=0; hive<2; hive++) {
+      HKEY hkey;
+      res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | (hive ? 256:0), &hkey);
+      if (res == ERROR_SUCCESS) {
+        DWORD dtype; 
+        DWORD size = 4096;
+        char result[4096 + 1];
+        res = RegQueryValueEx(hkey, "MAYA_INSTALL_LOCATION", NULL, &dtype, (LPBYTE)result, &size);
+        if ((res == ERROR_SUCCESS)&&(dtype == REG_SZ)) {
+          result[size] = 0;
+          loc = result;
+        }
+        RegCloseKey(hkey);
+      }
+    }
+  }
+}
+
+#elif defined(__APPLE__)
+static void
+get_maya_location(const char *ver, string &loc) {
+  char mpath[64];
+  sprintf(mpath, "/Applications/Autodesk/maya%s/Maya.app/Contents", ver);
+  struct stat st;
+  if(stat(mpath, &st) == 0) {
+    loc = mpath;
+  }
+}
+
+#else  // _WIN32
+static void
+get_maya_location(const char *ver, string &loc) {
+  char mpath[64];
+#if __WORDSIZE == 64
+  sprintf(mpath, "/usr/autodesk/maya%s-x64", ver);
+#else
+  sprintf(mpath, "/usr/autodesk/maya%s", ver);
+#endif
+  struct stat st;
+  if(stat(mpath, &st) == 0) {
+    loc = mpath;
+  } else {
+#if __WORDSIZE == 64
+    sprintf(mpath, "/usr/aw/maya%s-x64", ver);
+#else
+    sprintf(mpath, "/usr/aw/maya%s", ver);
+#endif
+    if(stat(mpath, &st) == 0) {
+      loc = mpath;
+    }
+  }
+}
+
+#endif  // _WIN32
+
+
 int 
 int 
 main(int argc, char *argv[]) {
 main(int argc, char *argv[]) {
   // First, get the command line and append _bin, so we will actually
   // First, get the command line and append _bin, so we will actually
@@ -70,41 +193,134 @@ main(int argc, char *argv[]) {
 #endif
 #endif
   string os_command = command.to_os_specific();
   string os_command = command.to_os_specific();
 
 
+  // First start with $PANDA_MAYA_LOCATION.  If it is set, it
+  // overrides everything else.
+  Filename maya_location = Filename::expand_from("$PANDA_MAYA_LOCATION");
+  if (!maya_location.empty()) {
+    // Reset maya_location to its full long name, because Maya
+    // requires this.
+    maya_location.make_canonical();
+    maya_location = Filename::from_os_specific(maya_location.to_os_long_name());
+
+  } else {
+    // $PANDA_MAYA_LOCATION wasn't set, so check the normal locations.
+    // First, we get the standard location, as a point of reference.
+    Filename standard_maya_location;
+#ifdef MAYAVERSION
+    const char *key = get_version_number(TOSTRING(MAYAVERSION));
+    if (key == NULL) {
+      cerr << "Unknown Maya version: " << TOSTRING(MAYAVERSION) << "\n";
+    } else {
+      string loc;
+      get_maya_location(key, loc);
+      if (loc.empty()) {
+        cerr << "Cannot locate " << TOSTRING(MAYAVERSION) << ": it does not appear to be installed.\n";
+      } else {
+        standard_maya_location = Filename::from_os_specific(loc);
+      }
+    }
+    if (!standard_maya_location.empty()) {
+      // Reset standard_maya_location to its full long name, so we can
+      // compare reliably to the given version.
+      standard_maya_location.make_canonical();
+      standard_maya_location = Filename::from_os_specific(standard_maya_location.to_os_long_name());
+    }
+#endif  // MAYAVERSION
+
+    // Now check if $MAYA_LOCATION is set.  If it is, and it's
+    // consistent with the standard location, we respect it.
+    maya_location = Filename::expand_from("$MAYA_LOCATION");
+    if (!maya_location.empty()) {
+      // Reset maya_location to its full long name, so we can compare
+      // it reliably to the standard location; and also because Maya
+      // requires this.
+      maya_location.make_canonical();
+      maya_location = Filename::from_os_specific(maya_location.to_os_long_name());
+    }
+    
+    if (maya_location.empty()) {
+      // If it is not set, we use the standard version instead.
+      maya_location = standard_maya_location;
+
+    } else if (maya_location != standard_maya_location) {
+      // If it *is* set, we verify that OpenMaya.dll matches the
+      // standard version.
+      Filename openmaya_given = Filename::dso_filename(Filename(maya_location, openmaya_filename));
+      Filename openmaya_standard = Filename::dso_filename(Filename(standard_maya_location, openmaya_filename));
+
+      if (openmaya_given != openmaya_standard) {
+#ifdef HAVE_OPENSSL
+        // If we have OpenSSL, we can use it to check the md5 hashes of
+        // the DLL.
+        HashVal hash_given, hash_standard;
+        if (!hash_standard.hash_file(openmaya_standard)) {
+          // Couldn't read the standard file, so use the given one.
+
+        } else {
+          if (!hash_given.hash_file(openmaya_given)) {
+            // Couldn't even read the given file; use the standard one
+            // instead.
+            maya_location = standard_maya_location;
+
+          } else {
+            if (hash_standard != hash_given) {
+              // No match; it must be the wrong version.
+              cerr << "$MAYA_LOCATION points to wrong version; using standard location instead.\n";
+              maya_location = standard_maya_location;
+            } else {
+              // The hash matches; keep the given MAYA_LOCATION setting.
+            }
+          }
+        }
+#else // HAVE_OPENSSL
+      // Without OpenSSL, just check the DLL filesize only.
+        off_t size_given, size_standard;
+        size_standard = openmaya_standard.get_file_size();
+        if (size_standard == 0) {
+          // Couldn't read the standard file, so use the given one.
+
+        } else {
+          size_given = openmaya_given.get_file_size();
+          if (size_given == 0) {
+            // Couldn't even read the given file; use the standard one
+            // instead.
+            maya_location = standard_maya_location;
+
+          } else {
+            if (size_standard != size_given) {
+              // No match; it must be the wrong version.
+              cerr << "$MAYA_LOCATION points to wrong version; using standard location instead.\n";
+              maya_location = standard_maya_location;
+
+            } else {
+              // The size matches; keep the given MAYA_LOCATION setting.
+            }
+          }
+        }
+
+#endif  // HAVE_OPENSSL
+      }
+    }
+  }
 
 
-  // Now look up $MAYA_LOCATION.  We insist that it be set and
-  // pointing to an actual Maya installation.
-  Filename maya_location = Filename::expand_from("$MAYA_LOCATION");
-  cerr << "MAYA_LOCATION: " << maya_location << endl;
   if (maya_location.empty()) {
   if (maya_location.empty()) {
     cerr << "$MAYA_LOCATION is not set!\n";
     cerr << "$MAYA_LOCATION is not set!\n";
     exit(1);
     exit(1);
   }
   }
+
+  cerr << "MAYA_LOCATION: " << maya_location.to_os_specific() << endl;
   if (!maya_location.is_directory()) {
   if (!maya_location.is_directory()) {
     cerr << "The directory referred to by $MAYA_LOCATION does not exist!\n";
     cerr << "The directory referred to by $MAYA_LOCATION does not exist!\n";
     exit(1);
     exit(1);
   }
   }
-
-  // Reset maya_location to its full long name, since Maya seems to
-  // require that.
-  maya_location.make_canonical();
-  maya_location = Filename::from_os_specific(maya_location.to_os_long_name());
   
   
   // Look for OpenMaya.dll as a sanity check.
   // Look for OpenMaya.dll as a sanity check.
-#ifdef IS_OSX
-  Filename openMaya = Filename::dso_filename(Filename(maya_location, "MacOS/libOpenMaya.dylib"));
-  if (!openMaya.is_regular_file()) {
-    cerr << "Could not find $MAYA_LOCATION/MacOS/" << openMaya.get_basename() << "!\n";
+  Filename openmaya = Filename::dso_filename(Filename(maya_location, openmaya_filename));
+  if (!openmaya.is_regular_file()) {
+    cerr << "Could not find $MAYA_LOCATION/" << Filename::dso_filename(openmaya_filename).to_os_specific() << "!\n";
     exit(1); 
     exit(1); 
   }
   }
 
 
-#else  // IS_OSX
-  Filename openMaya = Filename::dso_filename(Filename(maya_location, "bin/OpenMaya.so"));
-  if (!openMaya.is_regular_file()) {
-    cerr << "Could not find $MAYA_LOCATION/bin/" << Filename(openMaya.get_basename()).to_os_specific() << "!\n";
-    exit(1);
-  }
-#endif
-
   // Re-set MAYA_LOCATION to its properly sanitized form.
   // Re-set MAYA_LOCATION to its properly sanitized form.
   {
   {
     string putenv_str = "MAYA_LOCATION=" + maya_location.to_os_specific();
     string putenv_str = "MAYA_LOCATION=" + maya_location.to_os_specific();