Merge ~pointhi/kicad:wx-python into ~kicad-product-committers/kicad:master
- Git
- lp:~pointhi/kicad
- wx-python
- Merge into master
Status: | Merged |
---|---|
Merge reported by: | Maciej Suminski |
Merged at revision: | 00511f2a7f7811e1fe8cfbbaa1664edaaba25d91 |
Proposed branch: | ~pointhi/kicad:wx-python |
Merge into: | ~kicad-product-committers/kicad:master |
Diff against target: |
274 lines (+95/-43) 6 files modified
CMakeLists.txt (+26/-2) Documentation/development/compiling.md (+5/-0) common/dialog_about/dialog_about.cpp (+7/-0) pcbnew/python/kicad_pyshell/__init__.py (+5/-0) pcbnew/swig/python_scripting.cpp (+47/-40) pcbnew/swig/python_scripting.h (+5/-1) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Wayne Stambaugh | Approve | ||
Maciej Suminski | Approve | ||
Seth Hillbrand | Approve | ||
Review via email: mp+357605@code.launchpad.net |
Commit message
Add optional wxPhoenix support
Description of the change
Based on the work of @mmccoo:
* https:/
and this additional patchset to remove wxpy_api.h dependency:
* http://
It adds wxPhoenix support to KiCad while keeping support for the old wxPython binding. All known are resolved now. In my case testing took place with wx3.0.4+GTK3 on Python2+wxPython as well as Python3+wxPhoenix on Linux. It would be nice to get testing done on Windows as well as Mac at least with the old wxPython version to ensure nothing breaks. While there are currently some compiler problems to get wxPhoenix running on Windows, adding this would benefit especially Linux users on Python3 only systems to get shell support.
Thomas Pointhuber (pointhi) wrote : | # |
Seth Hillbrand (sethh) wrote : | # |
Looks good. Tested on Debian Buster and works smoothly.
Maciej Suminski (orsonmmz) wrote : | # |
I have briefly tested the branch with Phoenix/
Wayne Stambaugh (stambaughw) wrote : | # |
It doesn't build on msys2 when python 3 is enabled. It finds the python 3 interpreter without any issue but it fails finding the python3 library path. Here is the config error:
-- Found PythonInterp: C:/msys64/
-- Check for installed Python Interpreter -- found
-- Python module install path: lib/python3.
CMake Error at C:/msys64/
Could NOT find PythonLibs (missing: PYTHON_
least version "3.3")
Call Stack (most recent call first):
C:/msys64/
CMakeModules/
CMakeLists.
-- Configuring incomplete, errors occurred!
Thomas Pointhuber (pointhi) wrote : | # |
> It doesn't build on msys2 when python 3 is enabled. It finds the python 3
> interpreter without any issue but it fails finding the python3 library path.
> Here is the config error:
>
> -- Found PythonInterp: C:/msys64/
> version "3.7.1", minimum required is "3.3")
> -- Check for installed Python Interpreter -- found
> -- Python module install path: lib/python3.
> CMake Error at C:/msys64/
> ndardArgs.cmake:137 (message):
> Could NOT find PythonLibs (missing: PYTHON_
> least version "3.3")
> Call Stack (most recent call first):
> C:/msys64/
> ke:378 (_FPHSA_
> CMakeModules/
> CMakeLists.txt:750 (find_package)
>
>
> -- Configuring incomplete, errors occurred!
That's weird because this patch should not change Python3 stuff. Can you verify this problem does not exist upstream?
Nick Østergaard (nickoe) wrote : | # |
@Wayne, try to add -DPYTHON_
Nick Østergaard (nickoe) wrote : | # |
Or probably 3.7m in your case.
Wayne Stambaugh (stambaughw) wrote : | # |
@Nick, thanks for the tip. That did it. Do you have any idea why the 'm' suffix is added to the python include path? This should be easy enough to fix by updating our FindPythonLib.cmake file to look in the python version path with the 'm' suffix. I also built and tested the python 3 support and to make sure the python 2 support still works on msys2/mingw32/
Maciej Suminski (orsonmmz) wrote : | # |
Thank you Thomas!
Preview Diff
1 | diff --git a/CMakeLists.txt b/CMakeLists.txt | |||
2 | index cf55d49..42e4c60 100644 | |||
3 | --- a/CMakeLists.txt | |||
4 | +++ b/CMakeLists.txt | |||
5 | @@ -82,6 +82,10 @@ option( KICAD_SCRIPTING_WXPYTHON | |||
6 | 82 | "Build wxPython implementation for wx interface building in Python and py.shell (default ON)." | 82 | "Build wxPython implementation for wx interface building in Python and py.shell (default ON)." |
7 | 83 | ON ) | 83 | ON ) |
8 | 84 | 84 | ||
9 | 85 | option( KICAD_SCRIPTING_WXPYTHON_PHOENIX | ||
10 | 86 | "Use new wxPython binding (default OFF)." | ||
11 | 87 | OFF ) | ||
12 | 88 | |||
13 | 85 | option( KICAD_SCRIPTING_ACTION_MENU | 89 | option( KICAD_SCRIPTING_ACTION_MENU |
14 | 86 | "Build a tools menu with registered python plugins: actions plugins (default ON)." | 90 | "Build a tools menu with registered python plugins: actions plugins (default ON)." |
15 | 87 | ON ) | 91 | ON ) |
16 | @@ -389,6 +393,10 @@ if( KICAD_SCRIPTING_WXPYTHON ) | |||
17 | 389 | add_definitions( -DKICAD_SCRIPTING_WXPYTHON ) | 393 | add_definitions( -DKICAD_SCRIPTING_WXPYTHON ) |
18 | 390 | endif() | 394 | endif() |
19 | 391 | 395 | ||
20 | 396 | if( KICAD_SCRIPTING_WXPYTHON_PHOENIX ) | ||
21 | 397 | add_definitions( -DKICAD_SCRIPTING_WXPYTHON_PHOENIX ) | ||
22 | 398 | endif() | ||
23 | 399 | |||
24 | 392 | if( KICAD_SCRIPTING_ACTION_MENU ) | 400 | if( KICAD_SCRIPTING_ACTION_MENU ) |
25 | 393 | add_definitions( -DKICAD_SCRIPTING_ACTION_MENU ) | 401 | add_definitions( -DKICAD_SCRIPTING_ACTION_MENU ) |
26 | 394 | endif() | 402 | endif() |
27 | @@ -747,8 +755,24 @@ if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES ) | |||
28 | 747 | if( KICAD_SCRIPTING_WXPYTHON ) | 755 | if( KICAD_SCRIPTING_WXPYTHON ) |
29 | 748 | # Check to see if the correct version of wxPython is installed based on the version of | 756 | # Check to see if the correct version of wxPython is installed based on the version of |
30 | 749 | # wxWidgets found. At least the major an minor version should match. | 757 | # wxWidgets found. At least the major an minor version should match. |
33 | 750 | set( _wxpy_version "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}" ) | 758 | if( KICAD_SCRIPTING_WXPYTHON_PHOENIX ) |
34 | 751 | set( _py_cmd "import wxversion;print(wxversion.checkInstalled('${_wxpy_version}'))" ) | 759 | set( _py_cmd "import wx;print(wx.version())" ) |
35 | 760 | execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${_py_cmd}" | ||
36 | 761 | RESULT_VARIABLE WXPYTHON_VERSION_RESULT | ||
37 | 762 | OUTPUT_VARIABLE WXPYTHON_VERSION_FOUND | ||
38 | 763 | OUTPUT_STRIP_TRAILING_WHITESPACE | ||
39 | 764 | ) | ||
40 | 765 | # Check to see if any version of wxPython is installed on the system. | ||
41 | 766 | if( WXPYTHON_VERSION_RESULT GREATER 0 ) | ||
42 | 767 | message( FATAL_ERROR "wxPython does not appear to be installed on the system." ) | ||
43 | 768 | endif() | ||
44 | 769 | set( _wxpy_version ${WXPYTHON_VERSION_FOUND} ) | ||
45 | 770 | set( _py_cmd "import wx;import re;print(re.search('wxWidgets ${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}', wx.wxWidgets_version) != None)" ) | ||
46 | 771 | else() | ||
47 | 772 | set( _wxpy_version "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}" ) | ||
48 | 773 | set( _py_cmd "import wxversion;print(wxversion.checkInstalled('${_wxpy_version}'))" ) | ||
49 | 774 | endif() | ||
50 | 775 | |||
51 | 752 | 776 | ||
52 | 753 | # Add user specified Python site package path. | 777 | # Add user specified Python site package path. |
53 | 754 | if( PYTHON_SITE_PACKAGE_PATH ) | 778 | if( PYTHON_SITE_PACKAGE_PATH ) |
54 | diff --git a/Documentation/development/compiling.md b/Documentation/development/compiling.md | |||
55 | index 4de0def..9af2fe5 100644 | |||
56 | --- a/Documentation/development/compiling.md | |||
57 | +++ b/Documentation/development/compiling.md | |||
58 | @@ -166,6 +166,11 @@ of Python 2. This option is disabled by default. | |||
59 | 166 | The KICAD_SCRIPTING_WXPYTHON option is used to enable building the wxPython interface into | 166 | The KICAD_SCRIPTING_WXPYTHON option is used to enable building the wxPython interface into |
60 | 167 | Pcbnew including the wxPython console. This option is enabled by default. | 167 | Pcbnew including the wxPython console. This option is enabled by default. |
61 | 168 | 168 | ||
62 | 169 | ## wxPython Phoenix Scripting Support ## {#wxpython_phoenix} | ||
63 | 170 | |||
64 | 171 | The KICAD_SCRIPTING_WXPYTHON_PHOENIX option is used to enable building the wxPython interface with | ||
65 | 172 | the new Phoenix binding instead of the legacy one. This option is disabled by default. | ||
66 | 173 | |||
67 | 169 | ## GitHub Plugin ## {#github_opt} | 174 | ## GitHub Plugin ## {#github_opt} |
68 | 170 | 175 | ||
69 | 171 | The BUILD_GITHUB_PLUGIN option is used to control if the GitHub plug in is built. This option is | 176 | The BUILD_GITHUB_PLUGIN option is used to control if the GitHub plug in is built. This option is |
70 | diff --git a/common/dialog_about/dialog_about.cpp b/common/dialog_about/dialog_about.cpp | |||
71 | index 0af42f8..9fc8233 100644 | |||
72 | --- a/common/dialog_about/dialog_about.cpp | |||
73 | +++ b/common/dialog_about/dialog_about.cpp | |||
74 | @@ -554,6 +554,13 @@ void DIALOG_ABOUT::buildVersionInfoData( wxString& aMsg, bool aFormatHtml ) | |||
75 | 554 | aMsg << OFF; | 554 | aMsg << OFF; |
76 | 555 | #endif | 555 | #endif |
77 | 556 | 556 | ||
78 | 557 | aMsg << indent4 << "KICAD_SCRIPTING_WXPYTHON_PHOENIX="; | ||
79 | 558 | #ifdef KICAD_SCRIPTING_WXPYTHON_PHOENIX | ||
80 | 559 | aMsg << ON; | ||
81 | 560 | #else | ||
82 | 561 | aMsg << OFF; | ||
83 | 562 | #endif | ||
84 | 563 | |||
85 | 557 | aMsg << indent4 << "KICAD_SCRIPTING_ACTION_MENU="; | 564 | aMsg << indent4 << "KICAD_SCRIPTING_ACTION_MENU="; |
86 | 558 | #ifdef KICAD_SCRIPTING_ACTION_MENU | 565 | #ifdef KICAD_SCRIPTING_ACTION_MENU |
87 | 559 | aMsg << ON; | 566 | aMsg << ON; |
88 | diff --git a/pcbnew/python/kicad_pyshell/__init__.py b/pcbnew/python/kicad_pyshell/__init__.py | |||
89 | index 7f476d5..91bca5b 100644 | |||
90 | --- a/pcbnew/python/kicad_pyshell/__init__.py | |||
91 | +++ b/pcbnew/python/kicad_pyshell/__init__.py | |||
92 | @@ -86,6 +86,11 @@ class PcbnewPyShell(editor.EditorNotebookFrame): | |||
93 | 86 | self.autoSaveHistory = False | 86 | self.autoSaveHistory = False |
94 | 87 | self.LoadSettings() | 87 | self.LoadSettings() |
95 | 88 | 88 | ||
96 | 89 | # in case of wxPhoenix we need to create a wxApp first and store it | ||
97 | 90 | # to prevent removal by gabage collector | ||
98 | 91 | if 'phoenix' in wx.PlatformInfo: | ||
99 | 92 | self.theApp = wx.App() | ||
100 | 93 | |||
101 | 89 | self.crust = crust.Crust(parent=self.notebook, | 94 | self.crust = crust.Crust(parent=self.notebook, |
102 | 90 | intro=intro, locals=namespace, | 95 | intro=intro, locals=namespace, |
103 | 91 | rootLabel="locals()", | 96 | rootLabel="locals()", |
104 | diff --git a/pcbnew/swig/python_scripting.cpp b/pcbnew/swig/python_scripting.cpp | |||
105 | index 4577406..17c3ee0 100644 | |||
106 | --- a/pcbnew/swig/python_scripting.cpp | |||
107 | +++ b/pcbnew/swig/python_scripting.cpp | |||
108 | @@ -30,6 +30,7 @@ | |||
109 | 30 | #include <python_scripting.h> | 30 | #include <python_scripting.h> |
110 | 31 | #include <stdlib.h> | 31 | #include <stdlib.h> |
111 | 32 | #include <string.h> | 32 | #include <string.h> |
112 | 33 | #include <sstream> | ||
113 | 33 | 34 | ||
114 | 34 | #include <fctsys.h> | 35 | #include <fctsys.h> |
115 | 35 | #include <eda_base_frame.h> | 36 | #include <eda_base_frame.h> |
116 | @@ -162,6 +163,7 @@ bool pcbnewInitPythonScripting( const char * aUserScriptingPath ) | |||
117 | 162 | #ifdef KICAD_SCRIPTING_WXPYTHON | 163 | #ifdef KICAD_SCRIPTING_WXPYTHON |
118 | 163 | PyEval_InitThreads(); | 164 | PyEval_InitThreads(); |
119 | 164 | 165 | ||
120 | 166 | #ifndef KICAD_SCRIPTING_WXPYTHON_PHOENIX | ||
121 | 165 | #ifndef __WINDOWS__ // import wxversion.py currently not working under winbuilder, and not useful. | 167 | #ifndef __WINDOWS__ // import wxversion.py currently not working under winbuilder, and not useful. |
122 | 166 | char cmd[1024]; | 168 | char cmd[1024]; |
123 | 167 | // Make sure that that the correct version of wxPython is loaded. In systems where there | 169 | // Make sure that that the correct version of wxPython is loaded. In systems where there |
124 | @@ -190,13 +192,14 @@ bool pcbnewInitPythonScripting( const char * aUserScriptingPath ) | |||
125 | 190 | Py_Finalize(); | 192 | Py_Finalize(); |
126 | 191 | return false; | 193 | return false; |
127 | 192 | } | 194 | } |
128 | 195 | #endif | ||
129 | 193 | 196 | ||
130 | 194 | wxPythonLoaded = true; | 197 | wxPythonLoaded = true; |
131 | 195 | 198 | ||
132 | 196 | // Save the current Python thread state and release the | 199 | // Save the current Python thread state and release the |
133 | 197 | // Global Interpreter Lock. | 200 | // Global Interpreter Lock. |
134 | 201 | g_PythonMainTState = PyEval_SaveThread(); | ||
135 | 198 | 202 | ||
136 | 199 | g_PythonMainTState = wxPyBeginAllowThreads(); | ||
137 | 200 | #endif // ifdef KICAD_SCRIPTING_WXPYTHON | 203 | #endif // ifdef KICAD_SCRIPTING_WXPYTHON |
138 | 201 | 204 | ||
139 | 202 | // load pcbnew inside python, and load all the user plugins, TODO: add system wide plugins | 205 | // load pcbnew inside python, and load all the user plugins, TODO: add system wide plugins |
140 | @@ -298,7 +301,7 @@ void pcbnewGetWizardsBackTrace( wxString& aNames ) | |||
141 | 298 | void pcbnewFinishPythonScripting() | 301 | void pcbnewFinishPythonScripting() |
142 | 299 | { | 302 | { |
143 | 300 | #ifdef KICAD_SCRIPTING_WXPYTHON | 303 | #ifdef KICAD_SCRIPTING_WXPYTHON |
145 | 301 | wxPyEndAllowThreads( g_PythonMainTState ); | 304 | PyEval_RestoreThread( g_PythonMainTState ); |
146 | 302 | #endif | 305 | #endif |
147 | 303 | Py_Finalize(); | 306 | Py_Finalize(); |
148 | 304 | } | 307 | } |
149 | @@ -325,15 +328,25 @@ void RedirectStdio() | |||
150 | 325 | 328 | ||
151 | 326 | wxWindow* CreatePythonShellWindow( wxWindow* parent, const wxString& aFramenameId ) | 329 | wxWindow* CreatePythonShellWindow( wxWindow* parent, const wxString& aFramenameId ) |
152 | 327 | { | 330 | { |
159 | 328 | const char* pcbnew_pyshell = | 331 | // parent is actually *PCB_EDIT_FRAME |
160 | 329 | "import kicad_pyshell\n" | 332 | const int parentId = parent->GetId(); |
161 | 330 | "\n" | 333 | { |
162 | 331 | "def makeWindow(parent):\n" | 334 | wxWindow* parent2 = wxWindow::FindWindowById( parentId ); |
163 | 332 | " return kicad_pyshell.makePcbnewShellWindow(parent)\n" | 335 | wxASSERT( parent2 == parent ); |
164 | 333 | "\n"; | 336 | } |
165 | 334 | 337 | ||
168 | 335 | wxWindow* window = NULL; | 338 | // passing window ids instead of pointers is because wxPython is not |
169 | 336 | PyObject* result; | 339 | // exposing the needed c++ apis to make that possible. |
170 | 340 | std::stringstream pcbnew_pyshell_one_step; | ||
171 | 341 | pcbnew_pyshell_one_step << "import kicad_pyshell\n"; | ||
172 | 342 | pcbnew_pyshell_one_step << "import wx\n"; | ||
173 | 343 | pcbnew_pyshell_one_step << "\n"; | ||
174 | 344 | pcbnew_pyshell_one_step << "parent = wx.FindWindowById( " << parentId << " )\n"; | ||
175 | 345 | pcbnew_pyshell_one_step << "newshell = kicad_pyshell.makePcbnewShellWindow( parent )\n"; | ||
176 | 346 | pcbnew_pyshell_one_step << "newshell.SetName( \"" << aFramenameId << "\" )\n"; | ||
177 | 347 | // return value goes into a "global". It's not actually global, but rather | ||
178 | 348 | // the dict that is passed to PyRun_String | ||
179 | 349 | pcbnew_pyshell_one_step << "retval = newshell.GetId()\n"; | ||
180 | 337 | 350 | ||
181 | 338 | // As always, first grab the GIL | 351 | // As always, first grab the GIL |
182 | 339 | PyLOCK lock; | 352 | PyLOCK lock; |
183 | @@ -354,7 +367,7 @@ wxWindow* CreatePythonShellWindow( wxWindow* parent, const wxString& aFramenameI | |||
184 | 354 | Py_DECREF( builtins ); | 367 | Py_DECREF( builtins ); |
185 | 355 | 368 | ||
186 | 356 | // Execute the code to make the makeWindow function we defined above | 369 | // Execute the code to make the makeWindow function we defined above |
188 | 357 | result = PyRun_String( pcbnew_pyshell, Py_file_input, globals, globals ); | 370 | PyObject* result = PyRun_String( pcbnew_pyshell_one_step.str().c_str(), Py_file_input, globals, globals ); |
189 | 358 | 371 | ||
190 | 359 | // Was there an exception? | 372 | // Was there an exception? |
191 | 360 | if( !result ) | 373 | if( !result ) |
192 | @@ -365,43 +378,37 @@ wxWindow* CreatePythonShellWindow( wxWindow* parent, const wxString& aFramenameI | |||
193 | 365 | 378 | ||
194 | 366 | Py_DECREF( result ); | 379 | Py_DECREF( result ); |
195 | 367 | 380 | ||
200 | 368 | // Now there should be an object named 'makeWindow' in the dictionary that | 381 | result = PyDict_GetItemString( globals, "retval" ); |
197 | 369 | // we can grab a pointer to: | ||
198 | 370 | PyObject* func = PyDict_GetItemString( globals, "makeWindow" ); | ||
199 | 371 | wxASSERT( PyCallable_Check( func ) ); | ||
201 | 372 | 382 | ||
205 | 373 | // Now build an argument tuple and call the Python function. Notice the | 383 | #if PY_MAJOR_VERSION >= 3 |
206 | 374 | // use of another wxPython API to take a wxWindows object and build a | 384 | if( !PyLong_Check( result ) ) |
207 | 375 | // wxPython object that wraps it. | 385 | #else |
208 | 386 | if( !PyInt_Check( result ) ) | ||
209 | 387 | #endif | ||
210 | 388 | { | ||
211 | 389 | wxLogError("creation of scripting window didn't return a number"); | ||
212 | 390 | return NULL; | ||
213 | 391 | } | ||
214 | 376 | 392 | ||
217 | 377 | PyObject* arg = wxPyMake_wxObject( parent, false ); | 393 | #if PY_MAJOR_VERSION >= 3 |
218 | 378 | wxASSERT( arg != NULL ); | 394 | const long windowId = PyLong_AsLong( result ); |
219 | 395 | #else | ||
220 | 396 | const long windowId = PyInt_AsLong( result ); | ||
221 | 397 | #endif | ||
222 | 379 | 398 | ||
225 | 380 | PyObject* tuple = PyTuple_New( 1 ); | 399 | // It's important not to decref globals before extracting the window id. |
226 | 381 | PyTuple_SET_ITEM( tuple, 0, arg ); | 400 | // If you do it early, globals, and the retval int it contains, may/will be garbage collected. |
227 | 401 | // We do not need to decref result, because GetItemString returns a borrowed reference. | ||
228 | 402 | Py_DECREF( globals ); | ||
229 | 382 | 403 | ||
231 | 383 | result = PyEval_CallObject( func, tuple ); | 404 | wxWindow* window = wxWindow::FindWindowById( windowId ); |
232 | 384 | 405 | ||
237 | 385 | // Was there an exception? | 406 | if( !window ) |
234 | 386 | if( !result ) | ||
235 | 387 | PyErr_Print(); | ||
236 | 388 | else | ||
238 | 389 | { | 407 | { |
248 | 390 | // Otherwise, get the returned window out of Python-land and | 408 | wxLogError("unable to find pyshell window with id %d", windowId); |
249 | 391 | // into C++-ville... | 409 | return NULL; |
241 | 392 | bool success = wxPyConvertSwigPtr( result, (void**) &window, "wxWindow" ); | ||
242 | 393 | (void) success; | ||
243 | 394 | |||
244 | 395 | wxASSERT_MSG( success, "Returned object was not a wxWindow!" ); | ||
245 | 396 | Py_DECREF( result ); | ||
246 | 397 | |||
247 | 398 | window->SetName( aFramenameId ); | ||
250 | 399 | } | 410 | } |
251 | 400 | 411 | ||
252 | 401 | // Release the python objects we still have | ||
253 | 402 | Py_DECREF( globals ); | ||
254 | 403 | Py_DECREF( tuple ); | ||
255 | 404 | |||
256 | 405 | return window; | 412 | return window; |
257 | 406 | } | 413 | } |
258 | 407 | 414 | ||
259 | diff --git a/pcbnew/swig/python_scripting.h b/pcbnew/swig/python_scripting.h | |||
260 | index 373cc66..2cc53b8 100644 | |||
261 | --- a/pcbnew/swig/python_scripting.h | |||
262 | +++ b/pcbnew/swig/python_scripting.h | |||
263 | @@ -39,7 +39,11 @@ | |||
264 | 39 | 39 | ||
265 | 40 | #ifndef NO_WXPYTHON_EXTENSION_HEADERS | 40 | #ifndef NO_WXPYTHON_EXTENSION_HEADERS |
266 | 41 | #ifdef KICAD_SCRIPTING_WXPYTHON | 41 | #ifdef KICAD_SCRIPTING_WXPYTHON |
268 | 42 | #include <wx/wxPython/wxPython.h> | 42 | #ifdef KICAD_SCRIPTING_WXPYTHON_PHOENIX |
269 | 43 | #include <wx/window.h> | ||
270 | 44 | #else | ||
271 | 45 | #include <wx/wxPython/wxPython.h> | ||
272 | 46 | #endif | ||
273 | 43 | #endif | 47 | #endif |
274 | 44 | #endif | 48 | #endif |
275 | 45 | 49 |
Windows build can be found here: https:/ /jenkins. simonrichter. eu/job/ windows- kicad-msys2- patch/171/