00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "dtoolbase.h"
00039 #include "filename.h"
00040 #include "globPattern.h"
00041 #include "dSearchPath.h"
00042 #include "executionEnvironment.h"
00043 #include "hashVal.h"
00044 #include <stdlib.h>
00045
00046 #if defined(_WIN32)
00047 #define WIN32_LEAN_AND_MEAN
00048 #include <windows.h>
00049 #endif
00050
00051 #define QUOTESTR(x) #x
00052 #define TOSTRING(x) QUOTESTR(x)
00053
00054 #if defined(_WIN32)
00055
00056 static const Filename openmaya_filename = "bin/OpenMaya.so";
00057 #elif defined(IS_OSX)
00058 static const Filename openmaya_filename = "MacOS/libOpenMaya.dylib";
00059 #else
00060 static const Filename openmaya_filename = "lib/libOpenMaya.so";
00061 #endif // _WIN32
00062
00063
00064 static Filename
00065 find_pyzip(const Filename &maya_location) {
00066
00067
00068 Filename dirname(maya_location, "bin");
00069
00070 vector_string results;
00071 GlobPattern glob("python*.zip");
00072 if (glob.match_files(results, dirname) != 0) {
00073 return Filename(dirname, results[0]);
00074 }
00075
00076 return Filename();
00077 }
00078
00079 struct { char *ver, *key; } maya_versions[] = {
00080 { "MAYA6", "6.0" },
00081 { "MAYA65", "6.5" },
00082 { "MAYA7", "7.0" },
00083 { "MAYA8", "8.0" },
00084 { "MAYA85", "8.5" },
00085 { "MAYA2008", "2008"},
00086 { "MAYA2009", "2009"},
00087 { "MAYA2010", "2010"},
00088 { "MAYA2011", "2011"},
00089 { "MAYA2012", "2012"},
00090 { "MAYA2013", "2013"},
00091 { 0, 0 },
00092 };
00093
00094 static char *
00095 get_version_number(const char *ver) {
00096 for (int i=0; maya_versions[i].ver != 0; i++) {
00097 if (strcmp(maya_versions[i].ver, ver)==0) {
00098 return maya_versions[i].key;
00099 }
00100 }
00101 return 0;
00102 }
00103
00104 #if defined(_WIN32)
00105 static void
00106 get_maya_location(const char *ver, string &loc) {
00107 char fullkey[1024];
00108 const char *developer;
00109 LONG res;
00110
00111 for (int dev=0; dev<3; dev++) {
00112 switch (dev) {
00113 case 0: developer="Alias|Wavefront"; break;
00114 case 1: developer="Alias"; break;
00115 case 2: developer="Autodesk"; break;
00116 }
00117 sprintf(fullkey, "SOFTWARE\\%s\\Maya\\%s\\Setup\\InstallPath", developer, ver);
00118 for (int hive=0; hive<2; hive++) {
00119 HKEY hkey;
00120 res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | (hive ? 256:0), &hkey);
00121 if (res == ERROR_SUCCESS) {
00122 DWORD dtype;
00123 DWORD size = 4096;
00124 char result[4096 + 1];
00125 res = RegQueryValueEx(hkey, "MAYA_INSTALL_LOCATION", NULL, &dtype, (LPBYTE)result, &size);
00126 if ((res == ERROR_SUCCESS)&&(dtype == REG_SZ)) {
00127 result[size] = 0;
00128 loc = result;
00129 }
00130 RegCloseKey(hkey);
00131 }
00132 }
00133 }
00134 }
00135
00136 #elif defined(__APPLE__)
00137 static void
00138 get_maya_location(const char *ver, string &loc) {
00139 char mpath[64];
00140 sprintf(mpath, "/Applications/Autodesk/maya%s/Maya.app/Contents", ver);
00141 struct stat st;
00142 if(stat(mpath, &st) == 0) {
00143 loc = mpath;
00144 }
00145 }
00146
00147 #else // _WIN32
00148 static void
00149 get_maya_location(const char *ver, string &loc) {
00150 char mpath[64];
00151 #if __WORDSIZE == 64
00152 sprintf(mpath, "/usr/autodesk/maya%s-x64", ver);
00153 #else
00154 sprintf(mpath, "/usr/autodesk/maya%s", ver);
00155 #endif
00156 struct stat st;
00157 if(stat(mpath, &st) == 0) {
00158 loc = mpath;
00159 } else {
00160 #if __WORDSIZE == 64
00161 sprintf(mpath, "/usr/aw/maya%s-x64", ver);
00162 #else
00163 sprintf(mpath, "/usr/aw/maya%s", ver);
00164 #endif
00165 if(stat(mpath, &st) == 0) {
00166 loc = mpath;
00167 }
00168 }
00169 }
00170
00171 #endif // _WIN32
00172
00173
00174 int
00175 main(int argc, char *argv[]) {
00176
00177
00178 Filename command = Filename::from_os_specific(argv[0]);
00179 if (!command.is_fully_qualified()) {
00180 DSearchPath path;
00181 path.append_path(ExecutionEnvironment::get_environment_variable("PATH"));
00182 #ifdef _WIN32
00183 command.set_extension("exe");
00184 #endif
00185 command.resolve_filename(path);
00186 }
00187
00188 #ifdef _WIN32
00189 if (command.get_extension() == "exe") {
00190 command.set_extension("");
00191 }
00192 #endif
00193
00194 command = command.get_fullpath() + string("_bin");
00195 #ifdef _WIN32
00196 command.set_extension("exe");
00197 #endif
00198 string os_command = command.to_os_specific();
00199
00200
00201
00202 Filename maya_location = Filename::expand_from("$PANDA_MAYA_LOCATION");
00203 if (!maya_location.empty()) {
00204
00205
00206 maya_location.make_canonical();
00207 maya_location = Filename::from_os_specific(maya_location.to_os_long_name());
00208
00209 } else {
00210
00211
00212 Filename standard_maya_location;
00213 #ifdef MAYAVERSION
00214 const char *key = get_version_number(TOSTRING(MAYAVERSION));
00215 if (key == NULL) {
00216 cerr << "Unknown Maya version: " << TOSTRING(MAYAVERSION) << "\n";
00217 } else {
00218 string loc;
00219 get_maya_location(key, loc);
00220 if (loc.empty()) {
00221 cerr << "Cannot locate " << TOSTRING(MAYAVERSION) << ": it does not appear to be installed.\n";
00222 } else {
00223 standard_maya_location = Filename::from_os_specific(loc);
00224 }
00225 }
00226 if (!standard_maya_location.empty()) {
00227
00228
00229 standard_maya_location.make_canonical();
00230 standard_maya_location = Filename::from_os_specific(standard_maya_location.to_os_long_name());
00231 }
00232 #endif // MAYAVERSION
00233
00234
00235
00236 maya_location = Filename::expand_from("$MAYA_LOCATION");
00237 if (!maya_location.empty()) {
00238
00239
00240
00241 maya_location.make_canonical();
00242 maya_location = Filename::from_os_specific(maya_location.to_os_long_name());
00243 }
00244
00245 if (maya_location.empty()) {
00246
00247 maya_location = standard_maya_location;
00248
00249 } else if (maya_location != standard_maya_location) {
00250
00251
00252 Filename openmaya_given = Filename::dso_filename(Filename(maya_location, openmaya_filename));
00253 Filename openmaya_standard = Filename::dso_filename(Filename(standard_maya_location, openmaya_filename));
00254
00255 if (openmaya_given != openmaya_standard) {
00256 #ifdef HAVE_OPENSSL
00257
00258
00259 HashVal hash_given, hash_standard;
00260 if (!hash_standard.hash_file(openmaya_standard)) {
00261
00262
00263 } else {
00264 if (!hash_given.hash_file(openmaya_given)) {
00265
00266
00267 maya_location = standard_maya_location;
00268
00269 } else {
00270 if (hash_standard != hash_given) {
00271
00272 cerr << "$MAYA_LOCATION points to wrong version; using standard location instead.\n";
00273 maya_location = standard_maya_location;
00274 } else {
00275
00276 }
00277 }
00278 }
00279 #else // HAVE_OPENSSL
00280
00281 off_t size_given, size_standard;
00282 size_standard = openmaya_standard.get_file_size();
00283 if (size_standard == 0) {
00284
00285
00286 } else {
00287 size_given = openmaya_given.get_file_size();
00288 if (size_given == 0) {
00289
00290
00291 maya_location = standard_maya_location;
00292
00293 } else {
00294 if (size_standard != size_given) {
00295
00296 cerr << "$MAYA_LOCATION points to wrong version; using standard location instead.\n";
00297 maya_location = standard_maya_location;
00298
00299 } else {
00300
00301 }
00302 }
00303 }
00304
00305 #endif // HAVE_OPENSSL
00306 }
00307 }
00308 }
00309
00310 if (maya_location.empty()) {
00311 cerr << "$MAYA_LOCATION is not set!\n";
00312 exit(1);
00313 }
00314
00315 cerr << "MAYA_LOCATION: " << maya_location.to_os_specific() << endl;
00316 if (!maya_location.is_directory()) {
00317 cerr << "The directory referred to by $MAYA_LOCATION does not exist!\n";
00318 exit(1);
00319 }
00320
00321
00322 Filename openmaya = Filename::dso_filename(Filename(maya_location, openmaya_filename));
00323 if (!openmaya.is_regular_file()) {
00324 cerr << "Could not find $MAYA_LOCATION/" << Filename::dso_filename(openmaya_filename).to_os_specific() << "!\n";
00325 exit(1);
00326 }
00327
00328
00329 {
00330 string putenv_str = "MAYA_LOCATION=" + maya_location.to_os_specific();
00331 char *putenv_cstr = strdup(putenv_str.c_str());
00332 putenv(putenv_cstr);
00333 }
00334
00335 #ifdef WIN32
00336 string sep = ";";
00337 #else
00338 string sep = ":";
00339 #endif
00340
00341
00342
00343
00344 Filename python = Filename(maya_location, "Python");
00345 if (python.is_directory()) {
00346 {
00347 string putenv_str = "PYTHONHOME=" + python.to_os_specific();
00348 char *putenv_cstr = strdup(putenv_str.c_str());
00349 putenv(putenv_cstr);
00350 }
00351 {
00352 string putenv_str = "PYTHONPATH=" + python.to_os_specific();
00353
00354 Filename pyzip = find_pyzip(maya_location);
00355 if (!pyzip.empty() && pyzip.exists()) {
00356 putenv_str += sep;
00357 putenv_str += pyzip.to_os_specific();
00358 }
00359
00360 Filename site_packages(python, "lib/site-packages");
00361 if (site_packages.is_directory()) {
00362 putenv_str += sep;
00363 putenv_str += site_packages.to_os_specific();
00364 }
00365
00366 char *putenv_cstr = strdup(putenv_str.c_str());
00367 putenv(putenv_cstr);
00368 }
00369 }
00370
00371
00372 Filename bin = Filename(maya_location, "bin");
00373 if (bin.is_directory()) {
00374 char *path = getenv("PATH");
00375 if (path == NULL) {
00376 path = "";
00377 }
00378 string putenv_str = "PATH=" + bin.to_os_specific() + sep + path;
00379 char *putenv_cstr = strdup(putenv_str.c_str());
00380 putenv(putenv_cstr);
00381 }
00382
00383 #ifdef IS_OSX
00384
00385 if (bin.is_directory()) {
00386 char *path = getenv("DYLD_LIBRARY_PATH");
00387 if (path == NULL) {
00388 path = "";
00389 }
00390 string sep = ":";
00391 string putenv_str = "DYLD_LIBRARY_PATH=" + bin.to_os_specific() + sep + path;
00392 char *putenv_cstr = strdup(putenv_str.c_str());
00393 putenv(putenv_cstr);
00394 }
00395
00396 #elif !defined(_WIN32)
00397
00398 if (bin.is_directory()) {
00399 char *path = getenv("LD_LIBRARY_PATH");
00400 if (path == NULL) {
00401 path = "";
00402 }
00403 string sep = ":";
00404 string putenv_str = "LD_LIBRARY_PATH=" + bin.to_os_specific() + sep + path;
00405 char *putenv_cstr = strdup(putenv_str.c_str());
00406 putenv(putenv_cstr);
00407 }
00408
00409 #endif // IS_OSX
00410
00411
00412
00413
00414 putenv("PANDA_INCOMPATIBLE_PYTHON=1");
00415
00416
00417
00418
00419 #ifdef _WIN32
00420
00421 char *command_line = strdup(GetCommandLine());
00422 STARTUPINFO startup_info;
00423 PROCESS_INFORMATION process_info;
00424 GetStartupInfo(&startup_info);
00425 BOOL result = CreateProcess(os_command.c_str(),
00426 command_line,
00427 NULL, NULL, true, 0,
00428 NULL, NULL,
00429 &startup_info,
00430 &process_info);
00431 if (result) {
00432 WaitForSingleObject(process_info.hProcess, INFINITE);
00433 DWORD exit_code = 0;
00434
00435 if (GetExitCodeProcess(process_info.hProcess, &exit_code)) {
00436 if (exit_code != 0) {
00437 cerr << "Program exited with status " << exit_code << "\n";
00438 }
00439 }
00440
00441 CloseHandle(process_info.hProcess);
00442 CloseHandle(process_info.hThread);
00443 exit(exit_code);
00444 }
00445 cerr << "Couldn't execute " << command << ": " << GetLastError() << "\n";
00446
00447 #else
00448
00449 execvp(os_command.c_str(), argv);
00450 #endif
00451
00452
00453 return 1;
00454 }