Confusing -O1 in build profile
$ cabal build
Resolving dependencies...
Build profile: -w ghc-8.8.1 -O1
In order, the following will be built (use -v for more details):
- bsb-http-chunked-0.0.0.4 (lib) (first run)
What does the -O1 in the Build profile: line mean? The ghc-options for my library component include -O2, and the verbose log shows that ghc is invoked with -O2 too.
It means that the local packages in the project are configured with -O1. However, as you correctly notice, this can be overridden on per-component basis in ghc-options.
Ah, thanks! In my case there weren't any other local packages that could be configured with -O1.
I first noticed it while benchmarking where it caused me much doubt about the validity of the numbers I was seeing.
What's the motivation for outputting this default(?) setting, especially when it doesn't apply / is overridden?
The motivation is that we consider ghc-options: -O2 (any -O flag) to be at the very least questionable practice.
In cabal.project you can have
optimization: 2
for all local, or per package (also non-local)
The core idea is that optimizations could be configured for all packages in an uniform way, without investigating if there’s some dev, devel or fast flag.
Also as a bonus, changing optimization level (also possible from command line), won’t cause full recompilation (or worse: mixed-level compilation) as build products are kept separate.
On 1 Sep 2019, at 7.58, Simon Jakobi [email protected] wrote:
Ah, thanks! In my case there weren't any other local packages that could be configured with -O1.
I first noticed it while benchmarking where it caused me much doubt about the validity of the numbers I was seeing.
What's the motivation for outputting this default(?) setting, especially when it doesn't apply / is overridden?
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.
The motivation is that we consider
ghc-options: -O2(any -O flag) to be at the very least questionable practice.
Interesting! Was there some kind of discussion that I could read?
Configuring the optimization level like this seems useful. Reporting -O1, when the actual optimization level applied is different, still seems confusing to me. Maybe cabal should also report the overrides then…
I guess I'm not following the back and forth here.
It means that the local packages in the project are configured with -O1.
I have a project where I have a cabal.project.local that looks like:
package our-project
optimization: 0
documentation: false
and a .cabal file like:
name: our-project
library
...
executable our-project
...
- When I do a
new-buildI seeBuild profile: -w ghc-8.6.5 -O1 - If I move
optimization: 0to the top-level I see ``Build profile: -w ghc-8.6.5 -O0` - In both cases it looks like the library and executable in my project are built without optimizations (as intended)
So I'm not sure what "Build profile" is supposed to mean, and not sure if what it's reporting is correct, and not sure if I'm using my cabal.project.local file correctly
Related to #5353
The problem is the same unresolved one as with profiling. Prof and non-prof libraries can depend on each others, opt and non-opt libraries can depend on each other. The prof discussion needs input from @dcoutts as iirc he had some ideas.
On 22. Jan 2020, at 2.34, Brandon Simmons [email protected] wrote:
I guess I'm not following the back and forth here.
It means that the local packages in the project are configured with -O1.
I have a project where I have a cabal.project.local that looks like:
package our-project optimization: 0 documentation: false and a .cabal file like:
name: our-project library ... executable our-project ... When I do a new-build I see Build profile: -w ghc-8.6.5 -O1 If I move optimization: 0 to the top-level I see ``Build profile: -w ghc-8.6.5 -O0` In both cases it looks like the library and executable in my project are built without optimizations (as intended) So I'm not sure what "Build profile" is supposed to mean, and not sure if what it's reporting is correct, and not sure if I'm using my cabal.project.local file correctly
Related to #5353
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
What does the -O1 in the Build profile: line mean? The ghc-options for my library component include -O2, and the verbose log shows that ghc is invoked with -O2 too.
FYI I have also just experienced puzzlement at this.
I think it's the "global" optimization level, ie. the top-level optimization: in cabal.project.
and what about include that useful info in the message, something like Top level build profile...
@sjakobi @jberryman @tomjaguarpaw is @jneira's proposal enough to clarify the meaning of that message? If not, any suggestions?
Well, it would certainly be better (and give something more substantial to Duck Duck Go for when confused).
is @jneira's proposal enough to clarify the meaning of that message? If not, any suggestions?
I don't have a better proposal. However I just noticed that the term "build profile" doesn't appear to be documented. My suggestion would be to fix that, or alternatively to use a different term if that one is better established and documented.
It sounds like in the message "Build profile: -w ghc-8.6.5 -O1" the "-O1" will often be meaningless, one of many global defaults which might be overridden in sections of the cabal.projec(.local) or .cabal files.
I guess I'd suggest deleting the message unless someone can explain how it might be helpful info for users?
I agree. It would be much more helpful to see the actual options that each package is being built with, but failing that seeing nothing at all is probably more helpful than seeing something that is misleading.
Well the ghc version is useful imo and the optimization level should reflect the top level config, taking in account the global config and several cabal.project.* I guess it would be useful ask who added it via blame ☺️
#4605
There is a reason why that specific info is shown though. "build profiles" have separate caches, so switching between --disable-optimization and --enable-optimization should cause no recompilation. Same for -w. See #3343 for more info. We should check if this is mentioned in the docs.
I just reminded myself that top-level things in cabal.project apply to all local packages, while a package * stanza will affect library dependencies as well. So I think I could be using optimization: 0 at the top level and would have gotten a sensible message (and also better caching behavior) IIUC
I'm kind of stumped on a good short-term solution. Maybe a message saying whether we are using an existing cached build profile directory would be just as useful?
Long term I wonder if what we want is:
- build profile is the hash of all local package settings (after baking in top-level local package settings)
- some good UX for clearing out older build profile artifacts
I think a very easy "fix" would be to say instead of "Build profile" the slightly more verbose "Build profile (subject to package-level overrides"
That's a totally valid fix.
While this is probably an improvement, it's not ideal unless there's a diagnostic message later on that some of the mentioned parameters were, in fact, overridden. Also, GHC version is impossible to override, so it's not completely true either.
Cabal-3.8.1.0.
Could you explain why Cabal reports -O1 even when ~/.cabal/config has ghc-options: -O2 and optimization: 2? Nothing in the local project settings explicitly configures optimization level, leaving it to the global default.
Leaving alone whether -O2 is (or is not) a good idea.
P.S. Thankfully, Cabal reports the GHC version correctly.
@mouse07410 what optimization level do you actually get when building the project? Is the message incorrect or is optimization from ~/.cabal/config not picked up at all? If it's the latter, could you open a new ticket about that?
@fgaz hard to say, because Cabal logging does not work either (see https://github.com/haskell/cabal/issues/8456). ;-)
But, based on the captured console output, -O2 does get passed to the GHC invocation. Presumably, from ghc-options: -O2, rather than from optimization: 2...?
It is unclear from the docs, whether I need just one of these (and if so - which one), or both: optimization: 2 and ghc-options: -O2. And it's unclear even if optimization: 2 is valid - but Cabal-3.8.1.0 did not complain about this value, so it must be acceptable...?
@mouse07410 did you read the doc? It suggests that optimization is meant to be more abstract setting. E.g. it can apply to (imaginary) Haskell compilers other than GHC, as well as, to GCC.
https://cabal.readthedocs.io/en/3.8/cabal-project.html#cfg-field-optimization
The doc says that it "builds with optimization" and passes -O2 to the C compiler.
Did it mean that GHC will also use -O2, or do I need to utilize ghc-options: -O2 in addition?
P.S. Docs IMHO do lack in the areas of clarity and comprehensiveness.
@mouse07410 you don't need ghc-options if you use optimization. For the docs: fully agree, and a contribution improving thereof would be very welcome!
That is not to say that the Build profile business is good — it is not. My guess would be that it prints the message before it reads the config (where you have optimization: 2). Arguably, this could be a separate ticket, because it most certainly will require something more clever than simply changing the (still very confusing!) message.
My guess would be that it prints the message before it reads the config (where you have
optimization: 2). . . it most certainly will require something more clever than simply changing the (still very confusing!) message
Admitting my lack of expertise here - why should it be any more complicated than printing the message after reading the config (when Cabal learns what GHC compiler is requested, and what options to pass to it)...?
@mouse07410 Very simply, because finding and changing a string is easier than moving the string, if you don’t know where to move exactly. Cabal’s code base is significant (after tests) it’s ~500 .hs files with ~100K SLOC (w/o spaces or comments).
And that’s assuming that my guess is right, which it may not be.