From e893b91a17c88881e89eeef76ac04ab629f1af5d Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 2 Feb 2012 17:45:48 +0000 Subject: [PATCH] unify mayapath.cxx and mayaWrapper.cxx --- dtool/src/dtoolutil/filename.I | 24 ++ dtool/src/dtoolutil/filename.h | 2 + makepanda/makepanda.py | 57 ++-- panda/src/express/virtualFileSystem.cxx | 1 + pandatool/src/mayaprogs/Sources.pp | 12 +- pandatool/src/mayaprogs/mayaWrapper.cxx | 353 ------------------------ pandatool/src/mayaprogs/mayapath.cxx | 260 +++++++++++++++-- 7 files changed, 306 insertions(+), 403 deletions(-) delete mode 100644 pandatool/src/mayaprogs/mayaWrapper.cxx diff --git a/dtool/src/dtoolutil/filename.I b/dtool/src/dtoolutil/filename.I index 7d89d9d1b2..675eb5afc6 100644 --- a/dtool/src/dtoolutil/filename.I +++ b/dtool/src/dtoolutil/filename.I @@ -64,6 +64,18 @@ Filename(const Filename ©) : { } +//////////////////////////////////////////////////////////////////// +// 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 // Access: Published @@ -76,6 +88,18 @@ text_filename(const string &filename) { 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 // Access: Published diff --git a/dtool/src/dtoolutil/filename.h b/dtool/src/dtoolutil/filename.h index 5cd92c685b..e053b38818 100644 --- a/dtool/src/dtoolutil/filename.h +++ b/dtool/src/dtoolutil/filename.h @@ -75,7 +75,9 @@ PUBLISHED: // Static constructors to explicitly create a filename that refers // to a text or binary file. This is in lieu of calling set_text() // 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 binary_filename(const Filename &filename); INLINE static Filename binary_filename(const string &filename); INLINE static Filename dso_filename(const string &filename); INLINE static Filename executable_filename(const string &filename); diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index e1a176946d..359d613eba 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -5176,55 +5176,64 @@ for VER in MAYAVERSIONS: TargetAdd('libmayapview'+VNUM+'.mll', opts=['ADVAPI', VER]) 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")): - TargetAdd('maya2egg'+VNUM+'-wrapped.exe', input=COMMON_EGG2X_LIBS_PYSTUB) + TargetAdd('maya2egg'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS_PYSTUB) 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): - TargetAdd('maya2egg'+VNUM+'-wrapped.exe', opts=['ADVAPI', 'NOPPC', VER]) + TargetAdd('maya2egg'+VNUM+'_bin.exe', opts=['ADVAPI', 'NOPPC', VER]) 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+'-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")): - TargetAdd('egg2maya'+VNUM+'-wrapped.exe', input=COMMON_EGG2X_LIBS_PYSTUB) + TargetAdd('egg2maya'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS_PYSTUB) 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): - TargetAdd('egg2maya'+VNUM+'-wrapped.exe', opts=['ADVAPI', 'NOPPC', VER]) + TargetAdd('egg2maya'+VNUM+'_bin.exe', opts=['ADVAPI', 'NOPPC', VER]) 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+'-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": - TargetAdd('mayacopy'+VNUM+'-wrapped.exe', input=COMMON_EGG2X_LIBS_PYSTUB) + TargetAdd('mayacopy'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS_PYSTUB) 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): - TargetAdd('mayacopy'+VNUM+'-wrapped.exe', opts=['ADVAPI', 'NOPPC', VER]) + TargetAdd('mayacopy'+VNUM+'_bin.exe', opts=['ADVAPI', 'NOPPC', VER]) 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('libmayasavepview'+VNUM+'.mll', input='mayasavepview'+VNUM+'_mayaSavePview.obj') 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', 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', input=COMMON_DTOOL_LIBS) + TargetAdd('mayacopy'+VNUM+'.exe', input='libpandaexpress.dll') # # DIRECTORY: contrib/src/ai/ diff --git a/panda/src/express/virtualFileSystem.cxx b/panda/src/express/virtualFileSystem.cxx index 75ba3aeea1..1b84db4092 100644 --- a/panda/src/express/virtualFileSystem.cxx +++ b/panda/src/express/virtualFileSystem.cxx @@ -1335,6 +1335,7 @@ do_get_file(const Filename &filename, int open_flags) const { } pathname.standardize(); 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. Filename strpath_pz = strpath + ".pz"; diff --git a/pandatool/src/mayaprogs/Sources.pp b/pandatool/src/mayaprogs/Sources.pp index 0b8162adaa..85fc9b8085 100644 --- a/pandatool/src/mayaprogs/Sources.pp +++ b/pandatool/src/mayaprogs/Sources.pp @@ -5,7 +5,8 @@ #begin bin_target #define TARGET maya2egg #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 \ mayapath.cxx #end bin_target @@ -13,7 +14,8 @@ #begin bin_target #define TARGET maya2egg_server #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 \ mayapath.cxx #end bin_target @@ -84,7 +86,8 @@ #begin bin_target #define TARGET egg2maya #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 \ mayapath.cxx #end bin_target @@ -114,7 +117,8 @@ #begin bin_target #define TARGET mayacopy #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 \ mayapath.cxx #end bin_target diff --git a/pandatool/src/mayaprogs/mayaWrapper.cxx b/pandatool/src/mayaprogs/mayaWrapper.cxx deleted file mode 100644 index 9a70626572..0000000000 --- a/pandatool/src/mayaprogs/mayaWrapper.cxx +++ /dev/null @@ -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 - #include - #include -#else - #include - #include - #include - #include - #define _putenv putenv -#endif -#ifdef __APPLE__ - #include -#else - #include -#endif -#include -#include -#include -#include -#define PATH_MAX 1024 - -#ifdef __APPLE__ - // This is for _NSGetExecutablePath(). - #include -#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 -} - diff --git a/pandatool/src/mayaprogs/mayapath.cxx b/pandatool/src/mayaprogs/mayapath.cxx index 2e1cd1b8f8..87a1234ef2 100755 --- a/pandatool/src/mayaprogs/mayapath.cxx +++ b/pandatool/src/mayaprogs/mayapath.cxx @@ -16,11 +16,31 @@ // similar programs that invoke OpenMaya and require certain // 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 "filename.h" #include "globPattern.h" #include "dSearchPath.h" #include "executionEnvironment.h" +#include "hashVal.h" #include #if defined(_WIN32) @@ -28,8 +48,17 @@ #include #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. -Filename +static Filename find_pyzip(const Filename &maya_location) { // This is where python26.zip appears on Windows. Should it be in // other locations on other platforms? @@ -44,6 +73,100 @@ find_pyzip(const Filename &maya_location) { 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 main(int argc, char *argv[]) { // First, get the command line and append _bin, so we will actually @@ -70,41 +193,134 @@ main(int argc, char *argv[]) { #endif 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()) { cerr << "$MAYA_LOCATION is not set!\n"; exit(1); } + + cerr << "MAYA_LOCATION: " << maya_location.to_os_specific() << endl; if (!maya_location.is_directory()) { cerr << "The directory referred to by $MAYA_LOCATION does not exist!\n"; 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. -#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); } -#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. { string putenv_str = "MAYA_LOCATION=" + maya_location.to_os_specific();