cabal icon indicating copy to clipboard operation
cabal copied to clipboard

Confusing -O1 in build profile

Open sjakobi opened this issue 6 years ago • 30 comments

$ 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.

sjakobi avatar Sep 01 '19 00:09 sjakobi

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.

23Skidoo avatar Sep 01 '19 00:09 23Skidoo

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?

sjakobi avatar Sep 01 '19 04:09 sjakobi

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.

phadej avatar Sep 01 '19 06:09 phadej

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…

sjakobi avatar Sep 01 '19 21:09 sjakobi

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

jberryman avatar Jan 22 '20 00:01 jberryman

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.

phadej avatar Jan 22 '20 17:01 phadej

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.

tomjaguarpaw avatar Sep 26 '21 10:09 tomjaguarpaw

I think it's the "global" optimization level, ie. the top-level optimization: in cabal.project.

fgaz avatar Sep 26 '21 10:09 fgaz

and what about include that useful info in the message, something like Top level build profile...

jneira avatar Sep 26 '21 10:09 jneira

@sjakobi @jberryman @tomjaguarpaw is @jneira's proposal enough to clarify the meaning of that message? If not, any suggestions?

fgaz avatar Sep 26 '21 12:09 fgaz

Well, it would certainly be better (and give something more substantial to Duck Duck Go for when confused).

tomjaguarpaw avatar Sep 26 '21 12:09 tomjaguarpaw

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.

sjakobi avatar Sep 27 '21 14:09 sjakobi

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?

jberryman avatar Sep 27 '21 15:09 jberryman

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.

tomjaguarpaw avatar Sep 27 '21 15:09 tomjaguarpaw

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 ☺️

jneira avatar Sep 27 '21 16:09 jneira

#4605

fgaz avatar Sep 27 '21 16:09 fgaz

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.

fgaz avatar Sep 27 '21 16:09 fgaz

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

jberryman avatar Sep 27 '21 17:09 jberryman

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"

gbaz avatar Feb 18 '22 05:02 gbaz

That's a totally valid fix.

Mikolaj avatar Feb 18 '22 06:02 Mikolaj

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.

ulysses4ever avatar Feb 18 '22 12:02 ulysses4ever

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 avatar Sep 05 '22 11:09 mouse07410

@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 avatar Sep 06 '22 06:09 fgaz

@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 avatar Sep 06 '22 13:09 mouse07410

@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

ulysses4ever avatar Sep 08 '22 02:09 ulysses4ever

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 avatar Sep 08 '22 13:09 mouse07410

@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!

ulysses4ever avatar Sep 08 '22 13:09 ulysses4ever

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.

ulysses4ever avatar Sep 08 '22 13:09 ulysses4ever

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 avatar Sep 09 '22 16:09 mouse07410

@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.

ulysses4ever avatar Sep 09 '22 17:09 ulysses4ever