Skip to content
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

-d:release -d:danger don't work as expected in user configs #14272

Closed
ghost opened this issue May 8, 2020 · 14 comments
Closed

-d:release -d:danger don't work as expected in user configs #14272

ghost opened this issue May 8, 2020 · 14 comments
Labels

Comments

@ghost
Copy link

ghost commented May 8, 2020

The problem is that currently the Nim compiler evaluates user configs last, so if a user puts -d:release or -d:danger in their
own config file, it won't have any effect on the actual compiler switches because the user config file will be evaluated last.

This can be quite unexpected for newbies since there are no warnings/hints about this behaviour at all. If you put these in your config file it'll compile just fine, defined(release) will return true, but the switches like --opt:speed won't get activated.

$ nim -v
Nim Compiler Version 1.3.1 [Linux: amd64]
Compiled at 2020-05-07
Copyright (c) 2006-2020 by Andreas Rumpf

git hash: 5fa7d374c4cb777372cf5b967575f228bda23c2b
active boot switches: -d:release
@ghost ghost changed the title Nim doesn't properly evaluate --define:danger when put in a config file -d:danger doesn't define -d:release when put in a config file May 8, 2020
@Skrylar
Copy link
Contributor

Skrylar commented May 8, 2020

shell script to reproduce (run this in an empty directory)

set -x

if [ ! -f main.nim ]; then
    cat << DONK > main.nim
echo "yardanico made me do it"
DONK
fi

if [ -f nim.cfg ]; then
    mv nim.cfg nim.cfg.off
fi

if [ ! -f nim.cfg.off ]; then
    cat << DONK > nim.cfg.off
-d:danger
DONK
fi

nim c -o:test-inline -d:danger main.nim
mv nim.cfg.off nim.cfg
nim c -o:test-cfg main.nim
du -sh test-cfg test-inline

@ghost ghost changed the title -d:danger doesn't define -d:release when put in a config file when defined(release) is false with -d:danger in a config file May 8, 2020
@ghost ghost changed the title when defined(release) is false with -d:danger in a config file symbols defined in nim.cfg file aren't visible ? May 8, 2020
@ghost ghost changed the title symbols defined in nim.cfg file aren't visible ? symbols defined in nim.cfg file aren't visible in user code? May 8, 2020
@ghost
Copy link
Author

ghost commented May 8, 2020

I discovered this when trying to minimise binary size:

echo "Hello world"
# nim.cfg
--os:any
--gc:arc
--panics:on
--define:posix
--define:release
--define:danger
--define:noSignalHandler
--cc:clang
--passC:"-flto"
--passL:"-flto"
# with no config
$ nim c --os:any --gc:arc --panics:on -d:posix -d:release -d:danger -d:noSignalHandler --cc:clang --passC:"-flto" --passL:"-flto" hello.nim 
$ wc hello
    3   113 18688 hello
# after adding config
$ nim c hello.nim
   79   863 69536 hello

@Clyybber
Copy link
Contributor

Clyybber commented May 10, 2020

This is caused by the fact that https://github.com/nim-lang/Nim/blob/devel/config/nim.cfg is now read before the project .cfg file.
This also causes -d:release or -d:danger not working at all in .cfg (aside from defining danger and release :p)

@ghost
Copy link
Author

ghost commented May 10, 2020

Even simpler way to reproduce:

# a.nim
proc a = 
  raise newException(ValueError, "test")
a()

Compile with nim c -r a.nim and you get the stack trace.
Now compile with nim c -d:release -r a.nim and you don't get the full stack trace as expected.
Now create a file nim.cfg and this inside:

-d:release

Now do nim c -r a.nim and the stack trace is still there which means that the -d:release is not really getting applied.

P.S: If you do it in config.nims, it still doesn't get applied.

@Clyybber
Copy link
Contributor

Also this is not a regression :p

@ghost
Copy link
Author

ghost commented May 10, 2020

Seems to be documented in https://nim-lang.org/docs/nims.html only but it's just a note
Note: In general, the define switches can also be set in NimScripts using switch or --, as shown in above examples. Only the release define (-d:release) cannot be set in NimScripts.
And it doesn't say that this wouldn't work in nim.cfg (and I haven't found the documentation which says that for nim.cfg)

@ghost
Copy link
Author

ghost commented May 10, 2020

So I guess there are two approaches - make this actually work or document it in an obvious place and optionally add a warning so when Nim sees -d:danger or -d:release in user config files it shows a warning

@ghost ghost changed the title symbols defined in nim.cfg file aren't visible in user code? -d:release -d:danger don't work as expected in user configs May 10, 2020
@alaviss
Copy link
Collaborator

alaviss commented May 10, 2020

I see a few ways to implement this:

  • Make --define special: The compiler should re-read all configurations that has been read before upon encountering a define or any flag that defines a symbol.

  • Make release and danger special: Add something like options.release = "--stacktrace:off --opt:speed", then -d:release and/or -d:danger can just add those flags in before any other flags.

  • Turn conditionals in nim.cfg into configuration blocks: Instead of "if this then parse", turn a block of:

    @if symbol
      flagA:on
    @endif
    

    into a configuration unit, ie: options.symbol = "flagA:on", then after processing all configurations, if symbol is defined, add the flags before any other flags. This is basically syntactic sugar for the previous proposal.

If we were to implement something like this, I'd personally prefer the first proposal, as it's easier to implement/understand IMO, though it might cause trouble with configurations that can have side effects (ie. nimscript's staticExec)

@Skrylar
Copy link
Contributor

Skrylar commented May 10, 2020 via email

@Araq
Copy link
Member

Araq commented May 11, 2020

Make release and danger special: Add something like options.release = "--stacktrace:off --opt:speed", then -d:release and/or -d:danger can just add those flags in before any other flags.

That's the solution I had in mind.

@ghost
Copy link
Author

ghost commented May 11, 2020

Yeah, I think that making release and danger special would make the most sense

@genotrance
Copy link
Contributor

Making release and danger special is not sufficient. Anything in nim.cfg that has an @if block is affected. A big example is cross-compilation typically invoked by --os which can tweak how all OS specific settings cascade, mingw being a specific case, and arch specific stuff like arm64. Lastly lto and strip.

Also, the user could have a global user cfg with other defines and if blocks which won't be able to reevaluate on a per-project basis.

@timotheecour
Copy link
Member

timotheecour commented Oct 21, 2020

this would be fixed via #15614 (comment), see RFC nim-lang/RFCs#278

EDIT: see #15742

@ghost
Copy link
Author

ghost commented May 23, 2021

Fixed by #18051

@ghost ghost closed this as completed May 23, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants