wxPython find and version loading fixes. (fixes lp:1408060)

* Add test to CMakeLists.txt to verify wxPython is installed when
  KICAD_SCRIPTING_WXPYTHON=ON.
* Add test to make sure wxPython version major and minor numbers match
  the version of wxWidgets found.
* Add code to set the correct version of wxPython to the python scripting
  initialization code.
* Minor code simplification in Pcbnew KIFACE main window creation.
This commit is contained in:
Wayne Stambaugh 2015-02-14 19:23:54 -05:00
parent 1a74913063
commit 69553d6fa3
4 changed files with 79 additions and 44 deletions

View File

@ -635,7 +635,6 @@ if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
# FindPythonInterp unless the user specifically defined a custom path.
if( NOT PYTHON_SITE_PACKAGE_PATH )
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.sysconfig;print\"%s\"%distutils.sysconfig.get_python_lib(plat_specific=0, standard_lib=0, prefix='')"
# execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.sysconfig;print\"%s\"%distutils.sysconfig.get_python_lib()"
OUTPUT_VARIABLE PYTHON_SITE_PACKAGE_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
@ -662,6 +661,33 @@ if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
find_package( PythonLibs 2.6 )
if( KICAD_SCRIPTING_WXPYTHON )
# Check to see if the correct version of wxPython is installed based on the version of
# wxWidgets found. At least the major an minor version should match.
set( _wxpy_version "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}" )
set( _py_cmd "import wxversion;print wxversion.checkInstalled('${_wxpy_version}')" )
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${_py_cmd}"
RESULT_VARIABLE WXPYTHON_VERSION_RESULT
OUTPUT_VARIABLE WXPYTHON_VERSION_FOUND
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# message( STATUS "WXPYTHON_VERSION_FOUND: ${WXPYTHON_VERSION_FOUND}" )
# message( STATUS "WXPYTHON_VERSION_RESULT: ${WXPYTHON_VERSION_RESULT}" )
# Check to see if any version of wxPython is installed on the system.
if( WXPYTHON_VERSION_RESULT GREATER 0 )
message( FATAL_ERROR "wxPython does not appear to be installed on the system." )
endif()
if( NOT WXPYTHON_VERSION_FOUND STREQUAL "True" )
message( FATAL_ERROR "wxPython version ${_wxpy_version} does not appear to be installed on the system." )
else()
set( WXPYTHON_VERSION_FOUND "${_wxpy_version}"
CACHE STRING "wxPython version found." )
endif()
endif()
#message( STATUS "PYTHON_INCLUDE_DIRS:${PYTHON_INCLUDE_DIRS}" )
# Infrequently needed headers go at end of search paths, append to INC_AFTER which

View File

@ -70,6 +70,11 @@
#define KICAD_DATA_PATH "@CMAKE_INSTALL_PREFIX@/@KICAD_DATA@"
#endif
/// The wxPython version found during configuration.
#if defined( KICAD_SCRIPTING_WXPYTHON )
#define WXPYTHON_VERSION "@WXPYTHON_VERSION_FOUND@"
#endif
/// When defined, build the GITHUB_PLUGIN for pcbnew.
#cmakedefine BUILD_GITHUB_PLUGIN

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -109,57 +109,46 @@ static struct IFACE : public KIFACE_I
wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 )
{
wxWindow* frame = NULL;
switch( aClassId )
{
case FRAME_PCB:
{
PCB_EDIT_FRAME* frame = new PCB_EDIT_FRAME( aKiway, aParent );
frame = dynamic_cast< wxWindow* >( new PCB_EDIT_FRAME( aKiway, aParent ) );
#if defined(KICAD_SCRIPTING)
// give the scripting helpers access to our frame
ScriptingSetPcbEditFrame( frame );
#if defined( KICAD_SCRIPTING )
// give the scripting helpers access to our frame
ScriptingSetPcbEditFrame( (PCB_EDIT_FRAME*) frame );
#endif
if( Kiface().IsSingle() )
{
// only run this under single_top, not under a project manager.
CreateServer( frame, KICAD_PCB_PORT_SERVICE_NUMBER );
}
return frame;
if( Kiface().IsSingle() )
{
// only run this under single_top, not under a project manager.
CreateServer( frame, KICAD_PCB_PORT_SERVICE_NUMBER );
}
break;
case FRAME_PCB_MODULE_EDITOR:
{
FOOTPRINT_EDIT_FRAME* frame = new FOOTPRINT_EDIT_FRAME( aKiway, aParent );
return frame;
}
frame = dynamic_cast< wxWindow* >( new FOOTPRINT_EDIT_FRAME( aKiway, aParent ) );
break;
case FRAME_PCB_MODULE_VIEWER:
case FRAME_PCB_MODULE_VIEWER_MODAL:
{
FOOTPRINT_VIEWER_FRAME* frame = new FOOTPRINT_VIEWER_FRAME(
aKiway, aParent, FRAME_T( aClassId ) );
return frame;
}
frame = dynamic_cast< wxWindow* >( new FOOTPRINT_VIEWER_FRAME( aKiway, aParent,
FRAME_T( aClassId ) ) );
break;
case FRAME_PCB_FOOTPRINT_WIZARD_MODAL:
{
FOOTPRINT_WIZARD_FRAME* frame = new FOOTPRINT_WIZARD_FRAME(
aKiway, aParent, FRAME_T( aClassId ) );
return frame;
}
frame = dynamic_cast< wxWindow* >( new FOOTPRINT_WIZARD_FRAME( aKiway, aParent,
FRAME_T( aClassId ) ) );
break;
default:
;
}
return NULL;
return frame;
}
/**
@ -193,13 +182,13 @@ KIFACE_I& Kiface() { return kiface; }
// KIFACE_GETTER's actual spelling is a substitution macro found in kiway.h.
// KIFACE_GETTER will not have name mangling due to declaration in kiway.h.
MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BASE* aProgram )
MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BASE* aProgram )
{
process = (PGM_BASE*) aProgram;
return &kiface;
}
#if defined(BUILD_KIWAY_DLL)
#if defined( BUILD_KIWAY_DLL )
PGM_BASE& Pgm()
{
wxASSERT( process ); // KIFACE_GETTER has already been called.
@ -208,7 +197,7 @@ PGM_BASE& Pgm()
#endif
#if defined(KICAD_SCRIPTING)
#if defined( KICAD_SCRIPTING )
static bool scriptingSetup()
{
wxString path_frag;
@ -218,7 +207,7 @@ static bool scriptingSetup()
const wxString python_us( "python27_us" );
// Build our python path inside kicad
wxString kipython = FindKicadFile( python_us + wxT("/python.exe") );
wxString kipython = FindKicadFile( python_us + wxT( "/python.exe" ) );
//we need only the path:
wxFileName fn( kipython );
@ -231,19 +220,20 @@ static bool scriptingSetup()
if( !wxGetEnv( wxT( "PYTHONPATH" ), &ppath ) || !ppath.Contains( python_us ) )
{
ppath << kipython << wxT("/pylib;");
ppath << kipython << wxT("/lib;");
ppath << kipython << wxT("/dll");
ppath << kipython << wxT( "/pylib;" );
ppath << kipython << wxT( "/lib;" );
ppath << kipython << wxT( "/dll" );
wxSetEnv( wxT( "PYTHONPATH" ), ppath );
DBG( std::cout << "set PYTHONPATH to " << TO_UTF8(ppath) << "\n"; )
// DBG( std::cout << "set PYTHONPATH to " << TO_UTF8( ppath ) << "\n"; )
// Add python executable path:
wxGetEnv( wxT( "PATH" ), &ppath );
if( !ppath.Contains( python_us ) )
{
kipython << wxT(";") << ppath;
kipython << wxT( ";" ) << ppath;
wxSetEnv( wxT( "PATH" ), kipython );
DBG( std::cout << "set PATH to " << TO_UTF8(kipython) << "\n"; )
// DBG( std::cout << "set PATH to " << TO_UTF8( kipython ) << "\n"; )
}
}
}
@ -263,14 +253,20 @@ static bool scriptingSetup()
// Add default paths to PYTHONPATH
wxString pypath;
// User scripting folder (~/Library/Application Support/kicad/scripting/plugins)
pypath = GetOSXKicadUserDataDir() + wxT( "/scripting/plugins" );
// Machine scripting folder (/Library/Application Support/kicad/scripting/plugins)
pypath += wxT( ":" ) + GetOSXKicadMachineDataDir() + wxT( "/scripting/plugins" );
// Bundle scripting folder (<kicad.app>/Contents/SharedSupport/scripting/plugins)
pypath += wxT( ":" ) + GetOSXKicadDataDir() + wxT( "/scripting/plugins" );
// Bundle wxPython folder (<kicad.app>/Contents/Frameworks/python/site-packages)
pypath += wxT( ":" ) + Pgm().GetExecutablePath() + wxT( "Contents/Frameworks/python/site-packages" );
pypath += wxT( ":" ) + Pgm().GetExecutablePath() +
wxT( "Contents/Frameworks/python/site-packages" );
// Original content of $PYTHONPATH
if( wxGetenv("PYTHONPATH") != NULL )
{
@ -289,6 +285,7 @@ static bool scriptingSetup()
wxLogSysError( wxT( "pcbnewInitPythonScripting() failed." ) );
return false;
}
return true;
}
#endif // KICAD_SCRIPTING

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <miguelangel@nbee.es>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -68,7 +68,7 @@ static void swigAddModule( const char* name, void (* initfunc)() )
}
/* Add the builting python modules */
/* Add the builtin python modules */
static void swigAddBuiltin()
{
@ -140,6 +140,13 @@ bool pcbnewInitPythonScripting( const char * aUserPluginsPath )
#ifdef KICAD_SCRIPTING_WXPYTHON
PyEval_InitThreads();
char cmd[1024];
// Make sure that that the correct version of wxPython is loaded. In systems where there
// are different versions of wxPython installed this can lead to select wrong wxPython
// version being selected.
snprintf( cmd, 1023, "import wxversion; wxversion.select('%s')", WXPYTHON_VERSION );
PyRun_SimpleString( cmd );
// Load the wxPython core API. Imports the wx._core_ module and sets a
// local pointer to a function table located there. The pointer is used
// internally by the rest of the API functions.
@ -181,7 +188,7 @@ void pcbnewFinishPythonScripting()
}
#if defined(KICAD_SCRIPTING_WXPYTHON)
#if defined( KICAD_SCRIPTING_WXPYTHON )
void RedirectStdio()
{