7 ms·
Show HN: Add a command-line interface to any C++ program
- HMH 5y agoI haven't really touched C++ for a few years and it seems due to its lack of a nice package manager single header libraries are getting more and more poplar. Does this mean I should expect compilation time to significantly increase during development as headers need to be recompiled every time?
- pjmlp 5y agoIn the meantime two big contenders raised up, vcpkg alongside NuGET from Microsoft (also does Mac and Linux), and conan. Personally I dislike conan, because package managers should be written in the language of the community they serve, but that is me. Thankfully, both support binary libraries. Then there are modules, which on Visual C++'s case are going along quite well. Anyone that bothers using header only libraries only has themselves to blame for waiting for builds, they are a plague from users that pretend C and C++ are scripting languages.
- ngneer 5y agoConan has been very useful to me
- twqas 5y agoUnfortunately Microsoft is addicted to telemetry, so vcpkg has that. I did not bother checking for NuGET. Header-only libraries can give substantial speedups (25% in extreme cases).
- pjmlp 5y agoYou can disable it. I really would like to see benchmarks versus proper use of binary libraries.
- inetknght 5y ago> You can disable it. I shouldn't have to think about it; I shouldn't have to explicitly opt-out to have privacy. Telemetry should always be opt-in, and not opted-in by default.
- ranger_danger 5y agoThe problem is, as a developer trying to fix issues, telemetry can be extremely helpful... but if it's solely opt-in, then virtually nobody will actually use it, and then what's the point.
- kjs3 5y agoSo your developer issues should trump my user issues?
- TillE 5y agoIt tells you to just recompile with -disableMetrics if you want, it's really not a huge deal. It's not like Windows.
- kjs3 5y agoSo as a user, I have to recompile in deference to making things easier for the developer. Definitely not like Windows...for all their sins, they don't pull entitled BS like that on users.
- jstimpfle 5y ago"Header only" might be a bad name, in my perception what it really means is "you can drop the code files into your project; we won't annoy you with our own over-engineered build system". Slow-compiling APIs can be made in any form, whether "header only" or not. C++ template APIs cannot be compiled separately and can cause long compile times for all transitively dependent translation units. For example, stb_image.h is a single file that is 1 copy+paste from github away. It compiles quite quickly, and often you will need it alongside only a single .c file in your project, but anyway it's extremely easy to compile it separately. All you have to do is cut+paste the implementation part to a separate .c file.
- pjmlp 5y agoTemplates can be instanted for common types and consumed via binary libraries. Also modules support templates just fine. Indeed, header only libs are just doing PHP like programming.
- moonchrome 5y agoCopy pasting shit in your repo means you are responsible for maintaining that code and need to keep track of upstream manually. Especially in c++ where memory bugs are prevalent, this sounds like a terrible idea.
- mrich 5y agoIn the case here most of the code is templates and macros, so a cpp wouldn't save much.
- ranger_danger 5y agoJust include that header in a separate C/C++ file that has no other purpose, then you won't have to recompile it every time you change something elsewhere.
- corysama 5y agoYeah. "header only" had really caught on because it is a catchy term that is simple to understand. But, what I really, really wish caught on would be "single cpp file" with the expectation that you are capable of adding a single, self-contained source file to whatever build system you happen to be using.
- electroly 5y agoThat's often what "header only" libraries really are -- you create your own .cpp file, define a particular preprocessor symbol, and then include the header which will then produce the implementation in that translation unit. Without the symbol defined you only get the interface, suitable for including in other translation units.
- nuerow 5y agoObligatory reference to Boost's Program_options , which is as close to a standard way to handle command line options in C++ there is. https://www.boost.org/doc/libs/1_77_0/doc/html/program_options.html https://www.boost.org/doc/libs/1_77_0/doc/html/program_optio...
- nly 5y agoAs mentioned this isn't wholly relevent because TFA is about adding a REPL. Nonetheless I prefer to use cxxopts[0] over BPO if I can justify the extra submodule [0] https://github.com/jarro2783/cxxopts https://github.com/jarro2783/cxxopts
- azalemeth 5y agoWhat about gnu Genopt? I have really enjoyed using it, although it's perhaps pure C rather than C++.
- jcul 5y agoI haven't used Genopt, it looks cool. At first I thought you meant getopt, which it looks like Genopt is built on. However I think Genopt is concerned with command line arguments. This is about an interactive command line interface, like a REPL. So you type command and it calls functions interactivly. This kind of thing can be a lot of work to do right, so I think this header looks great. I'm looking forward to trying it out.
- ryandrake 5y agoYea, I was a little confused by the "command line" claim, too. Like, where is it parsing argv and argc, and does it support long style and short style options? Title should say "Add a REPL interface to any C++ program"
- eps 5y agoClean and simple API, clever implementation. Very nicely done. Saying as someone who worked on a cli framework for network devices in the past and quite enjoyed it. It was in C though, so it wasn't as terse.
- chrisaycock 5y agoI wrote this to add a REPL-like interface to existing programs. It can call normal functions with automatic parsing and type safety. class Arithmetic : public CommandInterface { int add(int x, int y) { return x + y; } void register_commands() override { register_command(&Arithmetic::add, "add", "Add two numbers"); } }; Simply evaluate a string to invoke the function. Arithmetic arithmetic; arithmetic.eval("add 3 4"); // returns "7" The user can place the eval() call behind any interface that has a string for its input and output. I personally use it behind a TCP socket on my trading application; I can query my strategy's state and change its parameters on the fly. If funky C++ interests you, the prop firm I work for is looking to hire engineers. Feel free to contact me directly: chris -AT- chrisaycock -DOT- com
- dmalecaut 5y agoProp firms sure like their esoteric C++!
- sfgweilr4f 5y ago"prop"?
- dmalecaut 5y agoProprietary trading firm
- choeger 5y agoNice work. Thanks for releasing it as free software. If I understand the design correctly, one can provide a custom argument parser by specializing lexical_cast?
- chrisaycock 5y agoYes, in theory. I've never tried to specialize lexical_cast since it's a Boost library and likely has its own assumptions. But I imagine it's possible if you want to handle things like arrays or user-defined types.
- anon-user-101 5y agoTo be fair to chrisaycock, this library it to actually add a runtime REPL rather than a command line interface. So the link to boost progam options is irrelevant.
- jb1991 5y agoWhy is the example flushing the output buffer twice with endl? This is naive, and a simple new line is probably intended for at least one of those flushes.
- jkrubin 5y agoI think it’s pretty cool regardless. Don’t be a weenie.
- eps 5y agoThe only comment that you think is worthy making after looking at OP's project is about adding a blank line in front of a prompt, in an example? Show some rudimentary respect towards the work of others by not nitpicking on trivialities.
- deleted 5y ago[deleted]
- deleted 5y ago[deleted]
- svalorzen 5y agoNice work! I maintain a library, cpp-readline [1], with a very similar API. The main difference is that relegates the REPL part to GNU readline. You do have the additional dependency, but on the other hand it automatically adds history and other nice-to-have features. [1]: https://github.com/Svalorzen/cpp-readline https://github.com/Svalorzen/cpp-readline
- ulnarkressty 5y agoHow does this compare to boost::spirit? I tried some years ago to make something similar but gave up due to the huge compile times for even simple grammar parsing.
- chrisaycock 5y agoSpirit is a parser combinator. That's if you want to design a whole language from scratch. My library is for single-name commands that can take simple parameters. You can't define your own language here.
- butwhywhyoh 5y agoThis isn't a command-line interface, this is a REPL. Very confusing title.
- cozzyd 5y agoNote that you can use cling/ROOT an actual C++ repl.