-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Setting clCfg.helpSyntax = ""
doesn't prevent inclusion of the syntax into the binary
#207
Comments
Sorry for the delay - I was not notified of this issue creation by the system. I only check I am not sure I understand the NOHELP complaint. Do you want "CLIGEN-NOHELP" to not appear? or the option key to not appear? If you are willing to set As to the bigger question, I am very aware of the object code explosion and I am certainly open to adding define guards like |
Disregard "CLIGEN-NOHELP" related remark, it's nonsense.
Not sure what you mean. Setting Just curious, does anyone really use overriding syntax help text? How valuable is it, considering you can't really change the syntax very much (only separator characters, if I'm not mistaken). A static (and |
Oh...I see. That comes from Much of the advanced syntax described in the message is amendable/augmentable through your own custom argument convertors (overriding or augmenting |
Where's the line between a library and a library-building framework? :D Thanks for the workaround tip. |
It's just a library. Like most Nim libraries (and even C libraries if you count .o's in .a's), it can have replaceable components at the "whole file" level. There is some art to deciding what file boundaries should be, but I tried to do a granularity that might be useful to advanced use cases. Some other "file hooks", if you will, are |
Don't take my comments so seriously, I'm being too frivolous lately. Sorry for that. |
Ok. Mostly elaborating. For what it's worth, I don't do this myself, but it is also possible to override the contents of I think we can close this issue and defer the "diet mode" for cligen to such a time as when we actually know which features cause what amount of bloat. Until then, it's actually hard to answer those questions. The rSTdown parsing/color highlights/etc might also be a cause..or the config parsing that brings in that part of the stdlib or ...? (Yes, yes...I realize without an object file space profiler that investigating is almost as much work as implementing off switches...PRs along these off switch lines are welcome.) |
See e3ddf46 for one move along the direction desired here. |
I compiled 4 programs with import os, strutils; echo parseInt(paramStr(1)) import cligen/parseopt3
for kind, key, val in getopt(): echo kind, key, val and: proc foo() = discard
import cligen; dispatch foo and stripped with
The leap from The user-config parsing leap is about 45 kB (probably more for TOML), but now there is a switch for that which took but a 1-line patch. :) A minimal API still generates about 2.4x (64 kB) more than just Anyway, 113088-30992 = 82096 as overhead for a trimmed |
NOTE: Updated the above quite a bit. |
another 12-16kB. It could almost re-use the same `cgCfgNone` define, but it's at least theoretically possible for some importer to just want to `import cligen/humanUt` for the color/rendering stuff. So, insist on both the defines being hot to skip definitions, just in case. I believe this is all the low hanging fruit worth picking for #207
A little more color on 595e859. The following was my test set up (Linux, gcc-12.1.1_p20220625) (from
and commands like (& substrings): nim c --threads:off -d:danger -d:cgCfgNone -d:cgNoColor --cc:gcc --opt:size f I get sizes like:
which is a pretty good reduction for not much effort. To me this seems largely a marketing gimmick anyway and remaining overhead is only 2X an empty Nim file (which is 30992 bytes) and even trivial programs will be 50-75k. Programs that do anything useful will be more like 150k and the extra 60 of
The next biggest space taker is the somewhat important Our misspelling/suggestion system is a more factorizable feature, but it is tiny - like 1337 bytes..just kind of noise on the big Remaining space-takers are dispatcher/parser overhead for the simplest case; Hint - it's not empty: help, help-syntax are there as well as various behavioral things keyed off of Everything else would be about how space scales up with the complexity of the parameter list of the wrapped function which someone can study if they want. So, anyway - yeah, "In real life", people probably don't do In short, I think this covers the really easy big space reductions, but if someone else wants to try some things, be my guest. |
harder *post facto* than all during development. It was never an aim of mine writing cligen. Rather, an endless stream of feature requests took most effort and nimble's packaging story remains at best harder to use than it should be (and people doing one-off CLIs is a common test-drive of a prog.lang) - which implicitly means actual priorities were to be full-featured and one-stop shopping. Both of these are usually contrary to code size (even more so than the common "any code is contrary!"). Anyway, I am not against non-breaking size optimization, but it may be much more trouble than it is worth. There is data on 2..3 space optims already represented in this dir script/harness at: #207 This suite could usefully grow e.g.s for (at least) the many & diverse parameters case and the dispatchMulti minimal and large cases.
Thanks for the detailed analysis. |
Just one other data point, but if I use this clapper package that has no deps outside Go's stdlib to build this Go program: package main
import ("fmt"; "os"; "github.com/thatisuday/clapper")
func main() {
reg := clapper.NewRegistry() // create a new registry
if _, ok := os.LookupEnv("NO_ROOT"); !ok {
rootCommand, _ := reg.Register("") // root command
rootCommand.AddFlag("verb", "v", true, "") // --verb,-v;dflt: true
}
command, err := reg.Parse(os.Args[1:])
if err != nil {
fmt.Printf("error => %#v\n", err); return
}
fmt.Printf("sub-command => %#v\n", command.Name)
for argName, argValue := range command.Args {
fmt.Printf("argument(%s) => %#v\n", argName, argValue)
}
for flagName, flagValue := range command.Flags {
fmt.Printf("flag(%s) => %#v\n", flagName, flagValue)
}
} with the same version of gcc and I haven't tried the same experiment with the Rust package you mentioned, but I would not have a very optimistic Bayesian prior on it beating the cligen numbers. Now, of course, anyone looking through the above or the new |
Just as a follow-up to that last comment, according to your (EDIT: issue opening clap) link, only color and suggestions are activated by default and if I clone that repo and do I did not learn enough to disable color & suggestions, but I'd bet you don't go below 744 kB which is how big my Don't get me wrong - I do get the "pay for what you use" mentality, and support it generally - if not hard to provide - but most benchmarking needs to concern itself with "compared to what?". Compared to bare Nim, sure we could do a bit better - maybe 25..30 kB more of the 50..60 KB excess in the smallest space-taking mode, but we are already doing better than Go and much better than Rust. |
Sure enough - after following the instructions here - the same minimal features |
Setting
clCfg.helpSyntax = ""
doesn't prevent inclusion of the full original syntax string into the binary. Same goes (less surprisingly) for suppressing the help field with "CLIGEN-NOHELP".Tested on 1.5.23
This poses a bigger question, what's the status/plans on supporting modularity of available features?
See how this is presented for Rust's clap: https://docs.rs/clap/latest/clap/#feature-flags
If cligen had a bunch of options which would prevent the corresponding parts of the code to be compiled at all, this would definitely help with the image of a somewhat bloated library.
The text was updated successfully, but these errors were encountered: