Skip to content

Commit

Permalink
Merge topic 'fix_python_paths'
Browse files Browse the repository at this point in the history
4d2eed2 Fix OsX path issue.
e367127 Don't popup output window for empty text.
b0aff1a Fix Python path issue on Windows VS builds.
11e32d1 ParaView binaries weren't using packaged Python.
cd77d5c Cleanup Python sys.path setup in ParaView.
  • Loading branch information
utkarshayachit authored and kwrobot committed May 21, 2013
2 parents 330203a + 4d2eed2 commit 7fa64f3
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 140 deletions.
16 changes: 14 additions & 2 deletions ParaViewCore/ClientServerCore/Core/vtkProcessModule.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,20 @@ bool vtkProcessModule::InitializePythonEnvironment(int argc, char** argv)
vtkProcessModule::FinalizePython = true;
}

std::string self_dir = vtksys::SystemTools::CollapseFullPath(
vtksys::SystemTools::GetFilenamePath(argv[0]).c_str());
std::string self_dir, programname;

if (argc > 0)
{
programname = vtksys::SystemTools::CollapseFullPath(argv[0]);
self_dir = vtksys::SystemTools::GetFilenamePath(programname.c_str());
}
else
{
self_dir = vtksys::SystemTools::GetCurrentWorkingDirectory(/*collapse=*/true);
programname = self_dir + "/unknown_exe";
}

vtkPythonInterpreter::SetProgramName(programname.c_str());
vtkPythonAppInitPrependPath(self_dir.c_str());
#endif
(void)argc;
Expand Down
301 changes: 170 additions & 131 deletions ParaViewCore/ClientServerCore/Core/vtkProcessModuleInitializePython.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
#ifndef __vtkProcessModulePythonInitializePython_h
#define __vtkProcessModulePythonInitializePython_h


#include <vtksys/SystemTools.hxx>
#include <algorithm>
#include <string>
#include "vtkPythonInterpreter.h"
#include <string>
#include <vtksys/SystemTools.hxx>

/* The maximum length of a file name. */
#if defined(PATH_MAX)
Expand All @@ -31,157 +29,198 @@
#endif
namespace
{
// This is code that used to reside in vtkPVPythonInterpretor. We should
// sanitize and clean it up. Since I don't want to muck with the search paths
// close to a release, I am leaving this untouched.
// ParaView should setup Python Path to find the modules in the following
// locations for various platforms. There are always two cases to handle: when
// running from build-location and when running from installed-location.

// THIS NEEDS TO BE CLEANED LIKE THE PLAGUE!!!
//----------------------------------------------------------------------------
void vtkPythonAppInitPrependPythonPath(const char* dir)
void vtkPythonAppInitPrependPythonPath(const std::string& dir)
{
vtkPythonInterpreter::PrependPythonPath(dir);
if (dir != "")
{
std::string collapsed_dir =
vtksys::SystemTools::CollapseFullPath(dir.c_str());
if (vtksys::SystemTools::FileIsDirectory(collapsed_dir.c_str()))
{
vtkPythonInterpreter::PrependPythonPath(collapsed_dir.c_str());
}
}
}

//----------------------------------------------------------------------------
bool vtkPythonAppInitPrependPath2(const std::string& prefix, const std::string& path)
//===========================================================================
// Linux/UNIX (not OsX)
// Key:
// - SELF_DIR: directory containing the pvserver/pvpython/paraview
// executables. For installed locations, this corresponds to the "real"
// executable, not the shared-forwarded executable (if applicable).
//---------------------------------------------------------------------------
// + BUILD_LOCATION
// + ParaView C/C++ library location
// - SELF_DIR/../lib
// + ParaView Python modules
// - SELF_DIR/../lib/site-packages
// + INSTALL_LOCATION
// + ParaView C/C++ library location
// - SELF_DIR
// + ParaView Python modules
// - SELF_DIR/site-packages
void vtkPythonAppInitPrependPathLinux(const std::string& SELF_DIR)
{
std::string package_dir = prefix + path;
package_dir = vtksys::SystemTools::CollapseFullPath(package_dir.c_str());
if (!vtksys::SystemTools::FileIsDirectory(package_dir.c_str()))
// Determine if running from build or install dir.
// If SELF_DIR/site-packages exists, it must be running from an installed
// location.
bool is_build_dir = vtksys::SystemTools::FileExists(
(SELF_DIR + "/site-packages").c_str()) == false;
if (is_build_dir)
{
package_dir = prefix + "/../" + path;
package_dir = vtksys::SystemTools::CollapseFullPath(package_dir.c_str());
vtkPythonAppInitPrependPythonPath(SELF_DIR + "/../lib");
vtkPythonAppInitPrependPythonPath(SELF_DIR + "/../lib/site-packages");
}

if (!vtksys::SystemTools::FileIsDirectory(package_dir.c_str()))
else
{
// This is the right path for app bundles on OS X
package_dir = prefix + "/../../../../" + path;
package_dir = vtksys::SystemTools::CollapseFullPath(package_dir.c_str());
vtkPythonAppInitPrependPythonPath(SELF_DIR);
vtkPythonAppInitPrependPythonPath(SELF_DIR + "/site-packages");
}

if(vtksys::SystemTools::FileIsDirectory(package_dir.c_str()))
}
//===========================================================================


//===========================================================================
// Windows
// Key:
// - SELF_DIR: directory containing the pvserver/pvpython/paraview
// executables.
//---------------------------------------------------------------------------
// + BUILD_LOCATION
// + ParaView C/C++ library location
// - SELF_DIR
// + ParaView Python modules
// - SELF_DIR/site-packages (when CMAKE_INTDIR is not defined).
// OR
// - SELF_DIR/../site-packages (when CMAKE_INTDIR is defined).
// + INSTALL_LOCATION
// + ParaView C/C++ library location
// - SELF_DIR
// - SELF_DIR/../lib/paraview-<major>.<minor>/
// + ParaView Python modules
// - SELF_DIR/../lib/paraview-<major>.<minor>/site-packages
//===========================================================================
void vtkPythonAppInitPrependPathWindows(const std::string& SELF_DIR)
{
std::string build_dir_site_packages;
#if defined(CMAKE_INTDIR)
build_dir_site_packages = SELF_DIR + "/../site-packages";
#else
build_dir_site_packages = SELF_DIR + "/site-packages";
#endif
bool is_build_dir =
vtksys::SystemTools::FileExists(build_dir_site_packages.c_str());
if (is_build_dir)
{
// This executable is running from the build tree. Prepend the
// library directory and package directory to the search path.
vtkPythonAppInitPrependPythonPath(package_dir.c_str());
return true;
vtkPythonAppInitPrependPythonPath(SELF_DIR);
vtkPythonAppInitPrependPythonPath(build_dir_site_packages);
}
else
{
vtkPythonAppInitPrependPythonPath(SELF_DIR);
vtkPythonAppInitPrependPythonPath(
SELF_DIR + "/../lib/paraview-" PARAVIEW_VERSION);
vtkPythonAppInitPrependPythonPath(
SELF_DIR + "/../lib/paraview-" PARAVIEW_VERSION "/site-packages");
}
return false;
}

//----------------------------------------------------------------------------
void vtkPythonAppInitPrependPath(const char* self_dir)
//===========================================================================
// OsX
// Key:
// - SELF_DIR: directory containing the pvserver/pvpython/paraview
// executables. This is different for app and non-app executables.
//---------------------------------------------------------------------------
// + BUILD_LOCATION
// - LIB_DIR
// - SELF_DIR/../lib (when executable is not APP, e.g pvpython)
// OR
// - SELF_DIR/../../../../lib (when executable is APP, e.g. paraview)
// + ParaView C/C++ library location
// - LIB_DIR
// + ParaView Python modules
// - LIB_DIR/site-packages
// + INSTALL_LOCATION
// - APP_ROOT
// - SELF_DIR/../.. (this is same for paraview and pvpython)
// - ParaView C/C++ library location
// - APP_ROOT/Contents/Libraries/
// - ParaView Python modules
// - APP_ROOT/Contents/Python
//===========================================================================
void vtkPythonAppInitPrependPathOsX(const std::string &SELF_DIR)
{
// Try to put the VTK python module location in sys.path.
std::string pkg_prefix = self_dir;
#if defined(CMAKE_INTDIR)
pkg_prefix += "/..";
#endif
vtkPythonAppInitPrependPath2(pkg_prefix, "/site-packages");
vtkPythonAppInitPrependPath2(pkg_prefix, "/lib/site-packages");
vtkPythonAppInitPrependPath2(pkg_prefix, "/../lib/site-packages");
vtkPythonAppInitPrependPath2(pkg_prefix, "/lib");
vtkPythonAppInitPrependPath2(pkg_prefix, "/../lib");
bool is_app = false;
{
// if SELF_DIR/../ is named "Contents", we are in an App.
std::string contents_dir = vtksys::SystemTools::CollapseFullPath(
(SELF_DIR + "/..").c_str());
is_app = (vtksys::SystemTools::GetFilenameName(contents_dir) == "Contents");
}

std::string lib_dir = (is_app==false)? (SELF_DIR + "/../lib") :
(SELF_DIR + "/../../../../lib");
lib_dir = vtksys::SystemTools::CollapseFullPath(lib_dir.c_str());

if (vtkPythonAppInitPrependPath2(pkg_prefix, "Utilities/VTKPythonWrapping/site-packages"))
bool is_build_dir = vtksys::SystemTools::FileExists(lib_dir.c_str());
if (is_build_dir)
{
// This executable is running from the build tree. Prepend the
// library directory to the search path.
//vtkPythonAppInitPrependPythonPath(VTK_PYTHON_LIBRARY_DIR);
vtkPythonAppInitPrependPythonPath(lib_dir);
vtkPythonAppInitPrependPythonPath(lib_dir + "/site-packages");
}
else
{
// This executable is running from an install tree. Check for
// possible VTK python module locations. See
// http://python.org/doc/2.4.1/inst/alt-install-windows.html for
// information about possible install locations. If the user
// changes the prefix to something other than VTK's prefix or
// python's native prefix then he/she will have to get the
// packages in sys.path himself/herself.
const char* inst_dirs[] = {
"/paraview",
"/../Python/paraview", // MacOS bundle
"/../lib/paraview-" PARAVIEW_VERSION "/paraview",
"/../../lib/paraview-" PARAVIEW_VERSION "/paraview",
"/lib/python/paraview", // UNIX --home
"/Lib/site-packages/paraview", "/Lib/paraview", // Windows
"/site-packages/paraview", "/paraview", // Windows
"/../lib/paraview-" PARAVIEW_VERSION "/site-packages/paraview",
"/../lib/paraview-" PARAVIEW_VERSION "/site-packages",
0
};

std::string prefix = self_dir;
vtkPythonAppInitPrependPythonPath(self_dir); // Propbably not needed any longer.

#if defined(WIN32)
// for when running from installed location.
std::string lib_dir = std::string(prefix + "/../lib/paraview-" + PARAVIEW_VERSION);
lib_dir = vtksys::SystemTools::CollapseFullPath( lib_dir.c_str());
vtkPythonAppInitPrependPythonPath(lib_dir.c_str());
vtkPythonAppInitPrependPythonPath( (lib_dir + "/site-packages").c_str() );
#endif
std::string app_root = SELF_DIR + "/../..";
app_root = vtksys::SystemTools::CollapseFullPath(app_root.c_str());
// The Contents/Libraries may not be needed. We should verify that.
vtkPythonAppInitPrependPythonPath(app_root + "/Contents/Libraries");
vtkPythonAppInitPrependPythonPath(app_root + "/Contents/Python");
}
}

// These two directories should be all that is necessary when running the
// python interpreter in a build tree.
//vtkPythonAppInitPrependPythonPath(PV_PYTHON_PACKAGE_DIR "/site-packages");
//vtkPythonAppInitPrependPythonPath(VTK_PYTHON_LIBRARY_DIR "/site-packages");
//vtkPythonAppInitPrependPythonPath(VTK_PYTHON_LIBRARY_DIR);

#if defined(__APPLE__)
// On OS X distributions, the libraries are in a different directory
// than the module. They are in a place relative to the executable.
std::string libs_dir = std::string(self_dir) + "/../Libraries";
libs_dir = vtksys::SystemTools::CollapseFullPath(libs_dir.c_str());
if(vtksys::SystemTools::FileIsDirectory(libs_dir.c_str()))
{
vtkPythonAppInitPrependPythonPath(libs_dir.c_str());
}
vtkPythonAppInitPrependPath2(prefix, "/../Python");
#endif
for(const char** dir = inst_dirs; *dir; ++dir)
{
std::string package_dir;
package_dir = prefix;
package_dir += *dir;
package_dir = vtksys::SystemTools::CollapseFullPath(package_dir.c_str());
if(vtksys::SystemTools::FileIsDirectory(package_dir.c_str()))
{
// We found the modules. Add the location to sys.path, but
// without the "/vtk" suffix.
std::string path_dir =
vtksys::SystemTools::GetFilenamePath(package_dir);
vtkPythonAppInitPrependPythonPath(path_dir.c_str());
break;
}
}
// This executable does not actually link to the python wrapper
// libraries, though it probably should now that the stub-modules
// are separated from them. Since it does not we have to make
// sure the wrapper libraries can be found by the dynamic loader
// when the stub-modules are loaded. On UNIX this executable must
// be running in an environment where the main VTK libraries (to
// which this executable does link) have been found, so the
// wrapper libraries will also be found. On Windows this
// executable may have simply found its .dll files next to itself
// so the wrapper libraries may not be found when the wrapper
// modules are loaded. Solve this problem by adding this
// executable's location to the system PATH variable. Note that
// this need only be done for an installed VTK because in the
// build tree the wrapper modules are in the same directory as the
// wrapper libraries.
//----------------------------------------------------------------------------
void vtkPythonAppInitPrependPath(const std::string &SELF_DIR)
{
#if defined(_WIN32)
static char system_path[(VTK_PYTHON_MAXPATH+1)*10] = "PATH=";
strcat(system_path, self_dir);
if(char* oldpath = getenv("PATH"))
{
strcat(system_path, ";");
strcat(system_path, oldpath);
}
putenv(system_path);
vtkPythonAppInitPrependPathWindows(SELF_DIR);
#elif defined(__APPLE__)
vtkPythonAppInitPrependPathOsX(SELF_DIR);
#else
vtkPythonAppInitPrependPathLinux(SELF_DIR);
#endif

// *** The following maybe obsolete. Need to verify and remove. ***

// This executable does not actually link to the python wrapper
// libraries, though it probably should now that the stub-modules
// are separated from them. Since it does not we have to make
// sure the wrapper libraries can be found by the dynamic loader
// when the stub-modules are loaded. On UNIX this executable must
// be running in an environment where the main VTK libraries (to
// which this executable does link) have been found, so the
// wrapper libraries will also be found. On Windows this
// executable may have simply found its .dll files next to itself
// so the wrapper libraries may not be found when the wrapper
// modules are loaded. Solve this problem by adding this
// executable's location to the system PATH variable. Note that
// this need only be done for an installed VTK because in the
// build tree the wrapper modules are in the same directory as the
// wrapper libraries.
#if defined(_WIN32)
static char system_path[(VTK_PYTHON_MAXPATH+1)*10] = "PATH=";
strcat(system_path, SELF_DIR.c_str());
if(char* oldpath = getenv("PATH"))
{
strcat(system_path, ";");
strcat(system_path, oldpath);
}
putenv(system_path);
#endif
}
}

Expand Down
Loading

0 comments on commit 7fa64f3

Please sign in to comment.