Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

attach a GUI to a command line tool

I'm working on an interactive command-line tool. The tool shows a prompt, and the user can enter commands and parameters which are being processed. After a command was executed, thhere is a new prompt and the user can proceed entering commands. It is very similar to gdb debugger, when used in cli mode. The tool is mostly written in C++, with some wrappers for using C librarys.

I'd like to attach a GUI (QT would be my first choice here) to my tool, however, I'm not sure how to do this. If you search the internet, many Unix developers prefer to strictly separate back- and frontend. So, I'm thinking about making the GUI a separate executable, which just uses the functionality of my command line tool.

What's the best way to achieve this? Should I use interproces communication with pipes or sockets? gdb, for example, uses TCP/IP, allowing to even run the GUI not on the same machine as the server! (However, this feature is not necessary).

If using some kind of IPC, how should the communication work? Should I use an ASCII interface (The Art Of Unix Programming prefers this)? This would have the advantage that my GUI just needs to parse the output of my command line tool. I don't have to change my tool very much, because it does not make much difference if the tool writes to a socket/pipe or just to cout. If so, should I define a protocol for IPC or just parse the input/output?

Another way would be to integrate the GUI to my tool directly, resulting in just one executable. Insight debugger does it this way. Insight not just "uses" gdb, it has its own gdb in its programm code. This way I won't have to write a parser, my GUI code can just call functions from my "base code".

Or should I make my command line tool a library, which I can link with a cli- or a GUI frontend?

What would be the best way to solve my problem? What are the avantages/disadvantes of the solutions above? What do you prefer?

like image 442
lugge86 Avatar asked May 12 '14 09:05

lugge86


1 Answers

As you noted in the question, there are several ways you can architect two pieces of software. There are three questions you want to ask yourself:

  1. what's the relationship between the two code segments.
  2. how likely is each code segment going to change in the future.
  3. how is your code going to be deployed

If one code segment is strictly a layer of abstraction on top of the other layer (the CLI code in your case), the core CLI functionality is relatively mature and stable, whereas you find it likely the the GUI will likely change often, this might suggest that you make the CLI code a library, and have the GUI code include the library and "call down" to the CLI code. If, on the other hand, the GUI code ties a bunch of pieces of software together, whereas the CLI code is a smaller, more isolated module and will likely change at a higher frequency rate (think dvd inside a dvd player) you might consider making your GUI a framework that imports different 'engines', or CLI modules. If you expect the two code segments to have a side-by-side relationship, for example the GUI might make HTTP requests to download images while the CLI code might do some CPU intensive number crunching in the background, then you might want to explore having both the CLI and GUI running as separate threads and communicating with other. [Depending on how closely coupled the two code segments are you can explore separate threads (no coupling), occasional message passing (message-queues) to using threads and fine-grained locks (very tightly coupled).]

separate processes (with the optional socket interface to run on different machines) are very useful when breaking down large software deployments into smaller, modular units. As long as your code can still fit in your head, and is less than roughly ~10,000 lines of code the added code complexity and latency isn't justified.

From your description it sounds as though the CLI code is mature, and the GUI is going to be simply a shell which interacts with the CLI. I also understand that you intended to ship your code as an executable. Therefore I think your use cases falls in line with making your CLI code a library, and writing a CLI shell and GUI shell that interface with it.

like image 134
gilsho Avatar answered Sep 28 '22 07:09

gilsho