kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #00227
[patch 1/1] kicad-python-support.patch Python Binding Start
-
To:
kicad-devel@xxxxxxxxxxxxxxx
-
From:
Florian Delizy <fdy@...>
-
Date:
Thu, 19 Apr 2007 20:46:24 +0200
-
User-agent:
Icedove 1.5.0.10 (X11/20070328)
Here is the (final?) version of this patch, for now Kicad with minor
fixes, next patches will stack on it.
At kicad start time, python scripts are executed in this order:
%KICADDATA%/scripts/kicad_startup.py
%KICADDATA%/plugins/<name>/*.py
%USERDIR%/.kicad.d/scripts/kicad_startup.py
%USERDIR%/.kicad.d/plugins/<name>/*.py
%USERDIR%/.kicad_d/scripts/kicad_startup.py
%USERDIR%/_kicad_d/plugins/<name>/*.py
where
%KICADDATA% stands for the data directory of kicad
%USERDIR% stands for the current user home directory
<name> stands for the current kicad app (namely, kicad, eeschema ...)
The python binding is quite limited yet, there is only one variable set
'kicadApp' which is the name of the current kicad application.
in a very near future, I'll add an online (English/French) HTML
documentation file, but since the documentation is not part of the
source archive, I am wondering where to put it ... can somebody point me
the right path for it ?
Florian
---
3d-viewer/makefile.gtk | 1
3d-viewer/makefile.include | 2
common/edaappl.cpp | 14 +++
common/makefile.include | 8 +-
common/pyhandler.cpp | 148 ++++++++++++++++++++++++++++++++++++++++++
cvpcb/makefile.include | 2
eeschema/makefile.include | 2
eeschema/plugins/makefile.gtk | 2
gerbview/makefile.include | 2
include/appl_wxstruct.h | 1
include/pyhandler.h | 47 +++++++++++++
kicad/makefile.include | 2
libs.linux | 17 ++++
pcbnew/makefile.include | 2
share/infospgm.cpp | 11 +++
15 files changed, 251 insertions(+), 10 deletions(-)
This patch adds a PyHandler class to handle all python bindings, and
modify the build system (currently only for linux gtk) to handle python
2.4 libs
to compile with python you'll first need to have boost.python installed
on your system (with its dev files) as well as python itself, then edit
libs.linux
and set KICAD_PYTHON to 1 (or to anything)
then you'll just have to build it
At running time, kcad now looks for a script 'scripts/kicad_startup.py'
in it's data directory, and 'scripts/.py', where is the app name, then
run all those scripts.
There is currently nothing exposed from Kicad to Python (more to come)
--------------080605030407010308020200 Content-Type: text/x-patch;
name="kicad-python-support.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: inline;
filename="kicad-python-support.patch"
Subject: [patch @num@/@total@] @name@ Python Binding Start
---
3d-viewer/makefile.gtk | 1
3d-viewer/makefile.include | 2
common/edaappl.cpp | 14 ++++
common/makefile.include | 8 ++
common/pyhandler.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++
cvpcb/makefile.include | 2
eeschema/makefile.include | 2
eeschema/plugins/makefile.gtk | 2
gerbview/makefile.include | 2
include/appl_wxstruct.h | 1
include/pyhandler.h | 43 +++++++++++++
kicad/makefile.include | 2
libs.linux | 17 ++++-
pcbnew/makefile.include | 2
share/infospgm.cpp | 11 +++
15 files changed, 233 insertions(+), 10 deletions(-)
This patch adds a PyHandler class to handle all python bindings, and modify the build system (currently only for linux gtk) to handle python 2.4 libs
to compile with python you'll first need to have boost.python installed on your system (with its dev files) as well as python itself, then edit libs.linux
and set KICAD_PYTHON to 1 (or to anything)
then you'll just have to build it
At running time, kcad now looks for a script 'scripts/kicad_startup.py' in it's data directory, and 'scripts/<name>.py', where <name> is the app name, then run all those scripts.
There is currently nothing exposed from Kicad to Python (more to come)
Index: kicad-dev/libs.linux
===================================================================
--- kicad-dev.orig/libs.linux 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/libs.linux 2007-04-18 20:54:26.000000000 +0200
@@ -7,6 +7,8 @@
OBJSUFF = .o
FINAL = 1
+# You must comment or uncommen tthis line to disable/enable python support
+KICAD_PYTHON = 1
# You must comment or uncomment this line for dynamic or static link
# dynamic link is less difficult than static link
@@ -69,11 +71,22 @@
endif
+#ifdef KICAD_PYTHON
+
+PYLIBS= -L/usr/lib
+PYLIBS+= -L /usr/include/python
+PYLIBS+= -lpython2.4
+PYLIBS+= -lboost_python
+EXTRACPPFLAGS+=-I /usr/include/python2.4 -DKICAD_PYTHON -fno-strict-aliasing -ggdb
+
+#endif
+
# attention à l'ordre des libairies
LIBS = -L/usr/local/lib -L/usr/X11R6/lib\
$(EXTRALIBS) $(WXSYSLIB)\
- $(LIBSTDC)
+ $(LIBSTDC) $(PYLIBS)
LIBS_WITH_GL = -L/usr/local/lib -L/usr/X11R6/lib\
$(EXTRALIBS) $(WXSYSLIB_WITH_GL)\
- $(LIBSTDC)
+ $(LIBSTDC) $(PYLIBS)
+
Index: kicad-dev/eeschema/plugins/makefile.gtk
===================================================================
--- kicad-dev.orig/eeschema/plugins/makefile.gtk 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/eeschema/plugins/makefile.gtk 2007-04-18 20:54:26.000000000 +0200
@@ -16,7 +16,7 @@
all: netlist_form_pads-pcb
netlist_form_pads-pcb: netlist_form_pads-pcb.cpp makefile.gtk
- gcc -D__UNIX__ -Wall netlist_form_pads-pcb.cpp -o netlist_form_pads-pcb $(LIBSTDC)
+ gcc -D__UNIX__ -Wall netlist_form_pads-pcb.cpp -o netlist_form_pads-pcb $(LIBSTDC) $(CXXFLAGS)
install:
cp -v netlist_form_pads-pcb $(KICAD_BIN)/plugins/
Index: kicad-dev/common/makefile.include
===================================================================
--- kicad-dev.orig/common/makefile.include 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/common/makefile.include 2007-04-18 20:54:26.000000000 +0200
@@ -1,4 +1,4 @@
-EXTRACPPFLAGS= -I$(SYSINCLUDE) -I./ -Ibitmaps -I../include
+EXTRACPPFLAGS+= -I$(SYSINCLUDE) -I./ -Ibitmaps -I../include
COMMON = ../include/colors.h
@@ -34,6 +34,10 @@
base_screen.o\
dcsvg.o
+ifdef KICAD_PYTHON
+OBJECTS+= pyhandler.o
+endif
+
gr_basic.o: gr_basic.cpp ../include/gr_basic.h $(DEPEND)
confirm.o: confirm.cpp $(COMMON)
@@ -85,3 +89,5 @@
eda_dde.o: eda_dde.cpp $(COMMON) ../include/eda_dde.h
displlst.o: displlst.cpp $(COMMON)
+
+pyhandler.o: pyhandler.cpp $(COMMON) ../include/pyhandler.h
Index: kicad-dev/3d-viewer/makefile.include
===================================================================
--- kicad-dev.orig/3d-viewer/makefile.include 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/3d-viewer/makefile.include 2007-04-18 20:54:26.000000000 +0200
@@ -1,5 +1,5 @@
EXTRALIBS =
-EXTRACPPFLAGS= -I./ -I../include -I../common -I../pcbnew
+EXTRACPPFLAGS+= -I./ -I../include -I../common -I../pcbnew
OBJECTS3D = 3d_frame.o 3d_read_mesh.o 3d_canvas.o trackball.o 3d_aux.o\
3d_draw.o 3d_toolbar.o 3d_class.o
Index: kicad-dev/cvpcb/makefile.include
===================================================================
--- kicad-dev.orig/cvpcb/makefile.include 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/cvpcb/makefile.include 2007-04-18 20:54:26.000000000 +0200
@@ -1,7 +1,7 @@
# makefile pour cvpcb (mingw)
OBJSUFF = o
-EXTRACPPFLAGS = -DCVPCB -I./ -I../cvpcb -I../include -Ibitmaps -I../pcbnew -I../3d-viewer
+EXTRACPPFLAGS += -DCVPCB -I./ -I../cvpcb -I../include -Ibitmaps -I../pcbnew -I../3d-viewer
EXTRALIBS = ../common/common.a
LIBVIEWER3D = ../3d-viewer/3d-viewer.a
Index: kicad-dev/eeschema/makefile.include
===================================================================
--- kicad-dev.orig/eeschema/makefile.include 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/eeschema/makefile.include 2007-04-18 20:54:26.000000000 +0200
@@ -3,7 +3,7 @@
FINAL = 1
EESCHEMA_FLAGS= -DEESCHEMA
-EXTRACPPFLAGS=$(KICAD_FLAGS) $(EESCHEMA_FLAGS) -I./ -Ibitmaps -I../include -I../eeschema
+EXTRACPPFLAGS+=$(KICAD_FLAGS) $(EESCHEMA_FLAGS) -I./ -Ibitmaps -I../include -I../eeschema
EXTRALIBS = ../common/common.a
# DEPEND = program.h general.h
Index: kicad-dev/gerbview/makefile.include
===================================================================
--- kicad-dev.orig/gerbview/makefile.include 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/gerbview/makefile.include 2007-04-18 20:54:26.000000000 +0200
@@ -1,5 +1,5 @@
EXTRALIBS = ../common/common.a
-EXTRACPPFLAGS= -DGERBVIEW -DPCBNEW -I./ -I../gerbview -I../include\
+EXTRACPPFLAGS+= -DGERBVIEW -DPCBNEW -I./ -I../gerbview -I../include\
-I../share -I../pcbnew -I../3d-viewer
#COMMON = pcbnew.h struct.h
Index: kicad-dev/kicad/makefile.include
===================================================================
--- kicad-dev.orig/kicad/makefile.include 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/kicad/makefile.include 2007-04-18 20:54:26.000000000 +0200
@@ -1,5 +1,5 @@
EXTRALIBS = ../common/common.a
-EXTRACPPFLAGS= -DKICAD -I./ -Ibitmaps -I../include -I../kicad -I../share
+EXTRACPPFLAGS+= -DKICAD -I./ -Ibitmaps -I../include -I../kicad -I../share
DEPEND =
Index: kicad-dev/pcbnew/makefile.include
===================================================================
--- kicad-dev.orig/pcbnew/makefile.include 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/pcbnew/makefile.include 2007-04-18 20:54:26.000000000 +0200
@@ -1,5 +1,5 @@
EXTRALIBS = ../common/common.a
-EXTRACPPFLAGS= -DPCBNEW -I./ -Ibitmaps -I../include -I../share -I../pcbnew -I../3d-viewer
+EXTRACPPFLAGS+= -DPCBNEW -I./ -Ibitmaps -I../include -I../share -I../pcbnew -I../3d-viewer
#COMMON = pcbnew.h struct.h class_pad.h class_module.h class_text_mod.h \
# class_edge_mod.h class_equipot.h
Index: kicad-dev/common/pyhandler.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kicad-dev/common/pyhandler.cpp 2007-04-18 21:03:19.000000000 +0200
@@ -0,0 +1,134 @@
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+// for all others, include the necessary headers (this file is usually all you
+// need because it includes almost all "standard" wxWindows headers
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#include <wx/dir.h>
+
+#include <pyhandler.h>
+#include <iostream>
+
+#include "fctsys.h"
+#include "common.h"
+
+using namespace boost::python;
+
+PyHandler* PyHandler::m_instance = NULL;
+
+PyHandler * PyHandler::GetInstance()
+/* Singleton implementation */
+{
+ if ( !PyHandler::m_instance )
+ {
+ PyHandler::m_instance = new PyHandler();
+ }
+ return PyHandler::m_instance;
+}
+
+PyHandler::PyHandler()
+/* Init the Python env */
+{
+ Py_Initialize();
+}
+
+PyHandler::~PyHandler()
+/* Closes the Python env */
+{
+ Py_Finalize();
+}
+
+void PyHandler::RunScripts()
+/* Run application startup scripts */
+{
+ // SYSTEMWIDE :
+
+ wxString dataPath = ReturnKicadDatasPath();
+
+ // check if we can have a kicad_startup.py around ?
+ wxString script = dataPath + wxString::FromAscii( "scripts/kicad_startup.py" );
+
+ // First find scripts/<name>.py and run it if found :
+
+ script = wxString::FromAscii( "scripts/" ) + m_appName + wxString::FromAscii(".py");
+ if ( wxFileExists( dataPath + script ) ) RunScript( script );
+
+ // Now lets see if we can find a suitable plugin directory (plugin/<name>) somewhere
+
+ wxString pluginDir = wxString::FromAscii( "plugins/" ) + m_appName;
+ if ( wxDirExists( dataPath + pluginDir ) )
+ {
+ // We do have a systemwide plugin dir, let's find files in it
+ wxArrayString pluginList;
+ wxDir::GetAllFiles( pluginDir, &pluginList, wxString::FromAscii("*.py") );
+
+ for ( unsigned int i = 0; i < pluginList.Count() ; i++ )
+ {
+ RunScript( pluginList[i] );
+ }
+
+ }
+
+ // We did read all systemwide scripts, let's have a look at user's ones
+
+
+ // USER Scripts
+
+}
+
+bool PyHandler::RunScript( const wxString & name )
+/* Run the script specified by 'name' */
+{
+ object module(( handle<>(borrowed(PyImport_AddModule("__main__")))));
+ object ns = module.attr( "__dict__" );
+
+ FILE * file = fopen( name.fn_str(), "r" );
+
+ if ( !file )
+ {
+ // do something
+ std::cout << "Unable to Load " << name.fn_str() << "\n";
+ return false;
+ }
+
+ try
+ {
+ handle<> ignored( ( PyRun_File( file, name.fn_str(), Py_file_input, ns.ptr(), ns.ptr() ) ) );
+ }
+ catch ( error_already_set )
+ {
+ PyErr_Print(); // should be printed into an error message ...
+ fclose( file );
+ return false;
+ }
+
+ fclose( file );
+ return true;
+}
+
+void PyHandler::SetAppName( const wxString & name )
+/* Set the application name in the python scope */
+{
+ m_appName = name;
+ object module(( handle<>(borrowed(PyImport_AddModule("__main__")))));
+ object ns = module.attr( "__dict__" );
+ try {
+ ns["kicadApp"] = std::string( name.ToAscii() );
+ }
+ catch (error_already_set)
+ {
+ PyErr_Print();
+ }
+}
+
+const char * PyHandler::GetVersion()
+{
+ return Py_GetVersion();
+}
+// vim: set tabstop=4 :
Index: kicad-dev/include/pyhandler.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kicad-dev/include/pyhandler.h 2007-04-18 20:54:26.000000000 +0200
@@ -0,0 +1,43 @@
+ /****************************/
+ /* pyhandler.h */
+ /****************************/
+
+#ifndef PYHANDLER_H
+#define PYHANDLER_H
+
+#include <boost/python.hpp>
+#include <Python.h>
+
+#include <wx/string.h>
+
+class PyHandler
+{
+
+ private:
+ static PyHandler * m_instance;
+
+ protected:
+ PyHandler();
+
+ wxString m_appName;
+
+ public:
+ static PyHandler * GetInstance();
+
+ ~PyHandler();
+
+ void SetAppName( const wxString & name );
+
+ void RunScripts();
+ bool RunScript( const wxString & name );
+
+ void AddModule( void (* initfunc)(void) );
+
+ const char * GetVersion();
+};
+
+
+#define KICAD_PY_BIND_MODULE( mod ) PyHandler::GetInstance()->AddModule( init#mod )
+
+// vim: set tabstop=4 :
+#endif
Index: kicad-dev/share/infospgm.cpp
===================================================================
--- kicad-dev.orig/share/infospgm.cpp 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/share/infospgm.cpp 2007-04-18 20:54:26.000000000 +0200
@@ -7,6 +7,10 @@
#include "gr_basic.h"
#include "common.h"
+#ifdef KICAD_PYTHON
+#include <pyhandler.h>
+#endif
+
// Import:
extern wxString g_Main_Title;
@@ -47,6 +51,13 @@
#else
Msg << wxT(" - Ansi version");
#endif
+
+#ifdef KICAD_PYTHON
+ Msg << wxT("\n");
+ Msg << wxT( "python : " );
+ Msg << wxString::FromAscii( PyHandler::GetInstance()->GetVersion() );
+#endif
+
Msg << wxT("\n\n") << _("Author:");
Msg << wxT("JP CHARRAS\n\n") << _("Based on wxWidgets ");
Msg << wxMAJOR_VERSION << wxT(".") <<
Index: kicad-dev/3d-viewer/makefile.gtk
===================================================================
--- kicad-dev.orig/3d-viewer/makefile.gtk 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/3d-viewer/makefile.gtk 2007-04-18 20:54:26.000000000 +0200
@@ -17,6 +17,7 @@
include makefile.include
+CPPFLAGS+= $(EXTRACPPFLAGS)
$(TARGET).a: $(OBJECTS3D) makefile.gtk makefile.include
rm -f $@
Index: kicad-dev/common/edaappl.cpp
===================================================================
--- kicad-dev.orig/common/edaappl.cpp 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/common/edaappl.cpp 2007-04-18 20:54:26.000000000 +0200
@@ -8,6 +8,10 @@
#define EDA_BASE
#define COMMON_GLOBL
+#ifdef KICAD_PYTHON
+#include <pyhandler.h>
+#endif
+
#include "fctsys.h"
#include <wx/image.h>
#include "wx/html/htmlwin.h"
@@ -166,6 +170,7 @@
if ( atof("0,1") ) g_FloatSeparator = ','; // Nombres flottants = 0,1
else g_FloatSeparator = '.';
+ PyHandler::GetInstance()->SetAppName( name );
}
@@ -590,3 +595,12 @@
}
+int WinEDA_App::OnRun(void)
+/* Run init scripts */
+{
+ #ifdef KICAD_PYTHON
+ PyHandler::GetInstance()->RunScripts();
+ #endif
+ return wxApp::OnRun();
+}
+
Index: kicad-dev/include/appl_wxstruct.h
===================================================================
--- kicad-dev.orig/include/appl_wxstruct.h 2007-04-18 20:54:12.000000000 +0200
+++ kicad-dev/include/appl_wxstruct.h 2007-04-18 20:54:26.000000000 +0200
@@ -63,6 +63,7 @@
WinEDA_App(void);
~WinEDA_App(void);
bool OnInit(void);
+ int OnRun(void);
bool SetBinDir(void);
void InitEDA_Appl(const wxString & name);
--------------080605030407010308020200--