Dear All,
I'm a Nim newbie, so forgive any possible naivete...I've put together a package for probability distributions/random numbers, and one of my examples runs with 'nim c sir' but cannot find the shared library when I use 'nim c -d:release sir':
https://github.com/sdwfrost/distributions/blob/master/examples/sir.nim
The library itself is in my LD_LIBRARY_PATH.
This is only a guess, but I wonder if dead code elimination is (for some reason) removing the hooks to your library. Try compiling with
nim c -d:release --deadCodeElim:off sir
instead. Does that help?
Dear @mbaulch,
Yes, that fixed it. It's not obvious (at least to me) why this would happen, when another, very similar, example doesn't have this problem:
https://github.com/sdwfrost/distributions/blob/master/examples/gibbs.nim
Just glancing over gibbs.nim and sir.nim, I can't see why this would happen. It's most likely a compiler bug. Would you mind filing an issue? I'll have a look at the compiler later (today, hopefully) and see if I can figure out what's going on, as it may affect other libraries too.
Thanks.
sir.nim fails for me in release mode. I have Ubuntu 16.04 with Nim devel updated right now and GCC 5.4.0. The example compiles just fine (nim c -d:release sir.nim), but trying to run it (./sir) results in could not load: libRmath-nim.so. The same happens with nim c -r -d:release sir.nim, but does not happen when I don't pass the flag -d:release.
How are you linking the library? What I have done is
This works fine in debug mode, but fails in release
Originally compiled my own libRmath-nim.so but tried using the nimble-pkg provided copy instead (via LD_LIBRARY_PATH). Still same result. My C compilers are slightly older. Clang 3.6, GCC 4.8.4. I'd be surprised if that made a difference. I'm assuming, @andrea, that gibbs succeeds for you with -d:release (while sir fails): as per @sdwfrost`s experience?
Even if I can't replicate the issue, there are a few other things I can try.
Hi @mbaulch @andrea
I've only encountered this problem in Linux; I just tried a fresh Nim-devel install (Ubuntu, gcc 4.6.3), and get the same issue. I don't have any problems with OSX (gcc-5 from homebrew or the packaged gcc). The test file (in tests/) also fails with -d:release, except when dead code elimination is turned off.
Best Simon
Thanks again to everyone for your patience. Having devoted some time to this, I've reached a conclusion.
An easy (and totally bizarre) way to fix sir.nim (for example) is to add a line (or more) that calls a proc from math. For example, suppose we add the following line to the end of sir.nim:
let x = round(1.234)
The problem disappears. Replacing round by splitDecimal also works. Anyhow, consider the difference in the C output generated by sir.nim vs. sir.nim with the above line. In nimcache/distributions_sir.c, the lines
N_NIMCALL(NF, round_115661_1009420244)(NF x0, NI places0);
/* ... */
NF x_127833_67199229;
/* ... */
x_127833_67199229 = round_115661_1009420244(1.2340000000000000e+00, ((NI) 0));
are added, while in nimcache/stdlib_math.c, the lines
#include <math.h>
N_NIMCALL(NF, round_115661_1009420244)(NF x0, NI places0) {
NF result0;
NF LOC6;
result0 = (NF)0;
{
if (!(places0 == ((NI) 0))) goto LA3;
result0 = round(x0);
}
goto LA1;
LA3: ;
{
NF mult0;
mult0 = pow(1.0000000000000000e+01, ((NF) (places0)));
LOC6 = (NF)0;
LOC6 = round(((NF)(x0) * (NF)(mult0)));
result0 = ((NF)(LOC6) / (NF)(mult0));
}
LA1: ;
return result0;
}
are added. Apart from these differences, the generated C output is identical. As sir executes, round_115661_1009420244 is called, but cannot (for any reason I can see) affect any other part of the execution. I can only conclude that there is a a bug in the linker infrastructure behind GCC.
I can't see another sensible explanation for this behavior. Can anyone else?
This situation is annoying, for sure, but I don't see any sensible way for the Nim compiler to help. My recommendation is to file a bug report with the GCC team, or use Clang.