zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.82k stars 6.6k forks source link

make menuconfig not supported on Windows #5847

Closed mbolivar closed 6 years ago

mbolivar commented 6 years ago

Since the kconfiglib switch, make/ninja menuconfig can't work on Windows, but this page implies it's possible run menuconfig on Windows:

http://docs.zephyrproject.org/application/application.html#overriding-default-configuration

A fix for this issue likely involves writing a Python3 GUI on top of kconfiglib that allows users to graphically edit their configuration.

carlescufi commented 6 years ago

Options for the GUI library to use:

mbolivar commented 6 years ago

A text user interface would indeed be a replacement for menuconfig, no disagreement there.

IMO a "real" GUI would be very nice to have as well. I normally use xconfig instead of menuconfig, as its UI is a lot better (example: I can search for an option, then enable it in one click from the results window).

carlescufi commented 6 years ago

@mbolivar you would be able to do that using asciimatics or python-prompt-toolkit as well I'm pretty sure. The advantage with text mode is much smaller dependencies and consistent layout

ulfalizer commented 6 years ago

Hello,

@mbolivar A jump-to feature like that is something I've been missing in menuconfig as well.

It should be pretty easy to implement in Kconfiglib, by looking up the symbol by name in kconf.syms and jumping to one of its menu nodes in kconf.syms["FOO"].nodes (a symbol can get multiple nodes from being defined in multiple locations, though you usually only see one).

If you wanted to get fancier, you could iterate through kconf.defined_syms instead and search prompt texts and help texts and things like that as well.

@carlescufi Those look pretty cool. At least ASCIIMATICS and prompt_toolkit seem to have mouse support, which is another thing I've been missing in menuconfig.

You've probably already seen it, but there's a menuconfig example/proof-of-concept at https://github.com/ulfalizer/Kconfiglib/blob/master/examples/menuconfig.py. What's missing for a basic usable menuconfig is menu tree navigation (right now it just dumps the entire tree) and less clunky input.

Ask if you have any questions.

mbolivar commented 6 years ago

@ulfalizer awesome, thanks for the pointers! I wish I had more time to work on this :\

carlescufi commented 6 years ago

Here's a "wish list" for this particular feature:

mbolivar commented 6 years ago

Options for the GUI library to use:

https://github.com/peterbrittain/asciimatics https://github.com/erikrose/blessings https://github.com/jonathanslenders/python-prompt-toolkit

I've done some initial review of these based on their documentation and installing them and playing around with their basic examples.

In all three cases, the libraries appear to be thoughtfully designed and carefully implemented.

Blessings provides basic terminal coloring and text styling, as well as positioning and fullscreen control. The feature set seems too restricted to implement the full wish-list, which includes features like text boxes and input fields, mouse support, etc., without a lot of trouble.

Asciimatics, by contrast, provides TUI support, including buttons, line drawings, and (terminal permitting) mouse input, out of the box.

Prompt toolkit has all of the above, as well as support for advanced features like text autocomplete, Emacs and Vi keybindings within the TUI, and more.

I would therefore rule out blessings and restrict the search to Asciimatics and Prompt toolkit.

Between the two, prompt toolkit seems to have a much better ecosystem, with many significant projects using it as a backend. I'm a longtime user of the IPython shell, for example, and I was interested to learn it uses prompt_toolkit. Some of the other features people have implemented on it (like the aws shell) were futuristic by CLI standards -- really impressive stuff.

Asciimatics is Apache 2.0, prompt toolkit is BSD 3 clause.

Given that, I think prompt toolkit is a clear winner, as something that can be used to start small but eventually produce really killer features.

mbolivar commented 6 years ago

Given that, I think prompt toolkit is a clear winner, as something that can be used to start small but eventually produce really killer features.

Ugh, though there's some pain coming down the pipe:

https://github.com/jonathanslenders/python-prompt-toolkit/issues/568

carlescufi commented 6 years ago

Ugh, though there's some pain coming down the pipe

Not sure this is a real problem, it looks like he'll push to pypi without changing the name, and even if he did change the name we could use the *2 version?

ulfalizer commented 6 years ago

Nice coincidence. I just bumped Kconfiglib's major version to 3 (though I doubt anyone will be affected by the small API behavior change -- just sticking to principles since I said I use semantic versioning). :P

Yeah, seems best to go with the *2 version. Thanks for the investigation!

mbolivar commented 6 years ago

Not sure this is a real problem, it looks like he'll push to pypi without changing the name, and even if he did change the name we could use the *2 version?

Lots of tools depend on the 1 version, I'm not sure how distro package management would cope with both installed in one system -- I guess 'import prompt_toolkit' would work with the version 1 from apt in your IPython install, but the *2 version in your pip --user install in the Zephyr environment?

More seriously, testing things in the early documentation pages beyond hello-world from the 2.0 branch broke fairly often. It seems like the docs are in some kind of intermediate state between the two versions, which could be a pain to develop against.

ulfalizer commented 6 years ago

Probably wouldn't be a huge pain to switch out prompt_toolkit out for something else at least, if it turns out to be a pain. Could do a basic usable version with just keyboard input and simple menu drawing first, and then see what to go with from there when adding more fancy features like mouse support. The basic version would probably be pretty easy to port over to other toolkits if needed.

ulfalizer commented 6 years ago

Would be cool if there was a UI toolkit that could generate both a text-based UI and a graphical UI as output, depending on settings. Doubt there's anything like that though.

ulfalizer commented 6 years ago

Here's some notes from playing around a bit with some of the toolkits (I might update them as I go):

ASCIIMATICS

The API and widget set seem nice and flexible, and mouse support is good.

Unfortunately, there's really noticeable startup delay and (worse) input delay in the UI examples I tried (samples/contactlist.py, samples/forms.py, samples/treeview.py).

Holding down a key in the contactlist.py example, I saw CPU usage go up to 90% on my Core i7-2600k. I think ASCIIMATICS might have been more of an animation library initially, with the UI stuff added later.

Here's two related issues I found:

Python Prompt Toolkit

Seems to be focused on text input, with some widgets tacked on.

Mouse support might only be available for text widgets and simple buttons:

There's also the upcoming 2.0 version switch that @mbolivar mentioned, which seems a bit messy.

Urwid

Haven't looked into it much, but it seems it might lack Windows support.

The standard curses module

Pretty low-level and do-it-yourself.

Would be snappy at least, and probably has the most complete mouse support. Drawing some simple Windows manually might not be that much work (I'm kinda leaning towards a "fullscreen" display, with just some buttons at the bottom and a title bar at the top, and maybe a dialog or two).

Unfortunately it doesn't work out of the box on Windows, though getting it ro run might be possible. Some related links:

Some other links:

Blessings

A thin wrapper around the standard curses module, with the same limitations. Also seems to use some ioctl() stuff for terminal resizing that might not work on Windows.

ulfalizer commented 6 years ago

Made a little progress on a version that uses the curses module. It's still in a WIP (hacky) state and missing essential features (no save/load, symbol information, search, mouse support, etc.)

The curses-specific parts are trivial, so it'd be easy to switch out curses for something else. I suspect that will be true when more features are added as well. Most of the complication is in menu navigation logic and the like.

skarmbild fran 2018-04-03 08-39-13

Some things I like about curses:

It would be nice if PDCurses turns out to be a viable option on Windows. Then we could use curses everywhere.

I added some Vi keybindings by the way, in addition to the "intuitive" keybindings:

Tell me if you have any other feature requests. :)

carlescufi commented 6 years ago

@mbolivar @SebastianBoe @nashif @ulfalizer

I have looked through the option of using PDCurses and the .whl file you point to, but here are the issues with it:

Therefore I would much rather use a pure Python alternative that gives us the certainty that we will be able to support it for many years into the future.

If there are limitations with the Python toolkit that we choose to use it's OK, we can improve that in the future slowly but surely. I'd much rather not have all the features (like mouse support) out of the box than take a dangerous bet of using an unsupported API on Windows that depends on a precompiled binary we don't have control of.

carlescufi commented 6 years ago

A few more comments on the options you list:

For me the best contender is still python-prompt-toolkit by far because of all the reasons listed so far.

ioannisg commented 6 years ago

@gbakke FYI

ulfalizer commented 6 years ago

Summing up some notes from IRC:

All the work I'm doing now would apply for any toolkit (i'm basically only using getch() + addstr() on the curses side), so I could get a usable version done in curses first and then switch over to something else if needed.

carlescufi commented 6 years ago

@ulfalizer thanks for the updates. If all you need is getch() and addstr() then I am pretty sure we can get a version of those relatively easily either using PPT or taking the necessary code from it.

ulfalizer commented 6 years ago

@carlescufi I suspect it might be messy to rip it out cleanly if they don't provide it in the interface. There's probably display optimization and stuff going on. I think that's needed to avoid flicker even in terminal emulators.

Pretty sure we'll work something out at least. :)

ulfalizer commented 6 years ago

Added scrolling, support for menuconfig FOO symbols, and some misc. minor things:

skarmbild fran 2018-04-04 13-09-52

Not winning any beauty contests yet.

One thing I've always found annoying about make menuconfig is that you can't search for a symbol and then jump directly to it, so I designed it to make that easy to implement:

The current position is remembered only as the currently selected node cur_node (plus a preferred_row variable, to keep the scroll from jumping around when you go in and out of menus). Everything else is derived from cur_node (e.g. the current menu). cur_node can then be set to wherever you want to jump to, even if it's in a completely different menu.

carlescufi commented 6 years ago

@ulfalizer looking good. A bit more coloring and this will be menuconfig. If you want I can give it a go on Windows, need the branch.

ulfalizer commented 6 years ago

@carlescufi It's in a bit of a half-broken state at the moment, but I'll send you a version to try out tomorrow at the latest. :)

ulfalizer commented 6 years ago

Got Windows installed and did some testing. Works fine until you resize the terminal.

Unfortunately, fixing that might be a bit painful. Some notes:

No KEY_RESIZE events are returned by getch() in the Python code, so the terminal resize isn't even detected. PDCurses itself supports KEY_RESIZE, but the wheel does not. Functions like curses.resizeterm() and curses.is_term_resized() end up not even existing.

It might be because setup.py from the wheel only has this:

define_macros = [("WINDOW_HAS_FLAGS", None)]`

Looking at _cursesmodules.c in the wheel source code (which is just a modified version of _cursesmodule.c from the CPython sources), it looks like HAVE_CURSES_IS_TERM_RESIZED and the like would need to be defined for those functions to become available. Maybe those macros are supposed to get defined by the extension building framework when building extensions though...

Perhaps rebuilding the wheel (python setup.py build) with some extra flags would fix it at least.

ulfalizer commented 6 years ago

I added a simple configuration dialog for string/int/hex values (no input verification yet) and save/load functionality, so it's in a basic usable state now.

Still ugly as sin, but that's for later.

skarmbild fran 2018-04-10 21-50-45

skarmbild fran 2018-04-10 21-52-36

Some missing/planned stuff:

Please tell me if there's any other features you want to see.

carlescufi commented 6 years ago

@ulfalizer This is excellent progress. the "Search and jump to" functionality is something I've always wanted in menuconfig so this will be most welcome. Regarding the beautification, I would settle with a simple color scheme reasonably similar to what's in menuconfig today, but maybe @mbolivar, @nashif or @SebastianBoe have opinions on the visual style that we should adopt here. In any case, nice work.

mbolivar commented 6 years ago

maybe @mbolivar, @nashif or @SebastianBoe have opinions on the visual style that we should adopt here.

I wish I had opinions :).

I don't use menu-driven applications from the terminal much (I prefer xconfig to menuconfig).

My only general idea would be that discoverability, for users who are accustomed to full-featured GUIs would be preferable to magic key sequences to get help or otherwise start to figure out how to use the application.

ulfalizer commented 6 years ago

Hello,

Status update is mostly that I wasted time on nitpicking alternative scrolling implementations and trickiness related to that. Scrolling is surprisingly tricky to get robust, with having to remember positions when jumping in and out of menus, nodes disappearing, windows being resized, scroll offsets, page up/down, the window being resized while a dialog is open, etc.

I'll try to get back to more essential stuff soon so I can get a first version out. Should really have left some of this till later, but you know how it is when you double down on stuff.

@mbolivar Any particular features in xconfig that you've missed in menuconfig?

ulfalizer commented 6 years ago

Got the scrolling and resizing worked out nicely. Pretty simple codewise now too. Always get a false start or two.

Progress update below.

Missing features:

I'm thinking of releasing an initial version without those. It's basically in a usable state now, with just the "10%" stuff left (plus whatever I forgot).

carlescufi commented 6 years ago

Hi Ulf, awesome update. I think it's time to post a DNM/RFC PR now so we can start discussing this. The PR should also include the following:

In a follow-up PR then we can target:

I think the for CMake side @SebastianBoe can probably contribute, so we are all in sync from the get go

ulfalizer commented 6 years ago

Status update:

Getting closer.

ulfalizer commented 6 years ago

Status update:

Screenshots below:

skarmbild fran 2018-04-18 13-23-26

skarmbild fran 2018-04-18 13-25-04

skarmbild fran 2018-04-18 13-25-26

skarmbild fran 2018-04-18 13-27-26

As seen in the last screenshot, long expressions can get ugly, which is a problem make menuconfig has as well. The expression could probably be split it up in some way to fix it, but it might not be a priority at the moment.

Major TODOS off the top of my head:

Tell me if you spot something you miss.

ulfalizer commented 6 years ago

There's now a do-not-merge pull request at https://github.com/zephyrproject-rtos/zephyr/pull/7140. Feedback appreciated!

ulfalizer commented 6 years ago

A proper pull request is now at https://github.com/zephyrproject-rtos/zephyr/pull/7174.

carlescufi commented 6 years ago

This has now landed in master

mbolivar commented 6 years ago

Nice work @ulfalizer!