Ethosa/nodesnim

Static Linking

wwderw opened this issue · 12 comments

I recently found this project. I like that it seems to follow along the lines of Godot as a Godot user. I got my own little hello world not really much, not at this point anyway. I am wanting to make sure that I can compile it correctly. I seem to be having a time with trying to compile with static linking.

I am running two rigs. One is KDE Neon and the other is Win 10. No cross platform tooling, straight native compilation. Running the same version of Nim on both, 1.4.8 and using nodesnim 0.4.

I am keeping all of the SDL and Freeglut .a files in a folder called lib in my project folder.

I am running the following command on both:
nim c --dynlibOverride:SDL2 --passL: "-L lib/" main.nim

I seem to be getting compilation errors related to undefined reference of SDL_SetCursor and SDL_CreateSystemCursor with several files within nodesnim. However, just compiling without dynlibOvveride and passL, everything runs fine on both OSs. Am I missing something with the linker flag for both of them? Or is statically linking not possible?

Appreciate the project and looking forward to working with it.

Thanks for the help.

freeglut has long been removed from dependencies.

and follow it: https://github.com/nim-lang/sdl2#static-linking-sdl2

It's works for me.

I think what happened is that when I did nimble install nodesnim, it pulled in 0.0.6 or something like that (I was having issues with setIcon(), which led me to look to make sure everything was current) and pulled from Master and got 0.4, but I still had freeglut from the original install and just kept it.

It looks like the page that you sent me to, the linking is what I need to do for windows (at least some of those seem to be for windows, I could be wrong, it always seems like I just know enough to cause damage). I should be able to give that a shot when I back on those rigs. Thanks!

it pulled in 0.0.6

For some reason nimble is pulling the wrong version. I have no idea what it might be.

Try it for KDE Neon https://github.com/nim-lang/sdl2#linux

I just found a bug that interferes with static compilation... 👀

I'll fix it now and update the nightly branch.

I just found a bug that interferes with static compilation... 👀

fix in fc268c2

Hmmm, I think this is a function of my knowing just enough to cause damage. I'm still at the same point with Linux. Just compiling works, but trying to link statically will compile, but it's the same size binary as before, so I doubt anything extra is getting in there. Windows passL that is mentioned on the nim-SDL bindings actually throws compiler errors. Some flags aren't recognized. I remove those and keep the rest and it compiles, but same as before, just the same size binary.

I tried just moving the SDL.dlls next to the compiled binary and that worked for those, but I was coming up with other .dlls that are missing that aren't apart of what I got from the various SDL libs (image, mixer, main etc).

What would be the basic --dynlibOveride and --passL for Linux and windows just for the main SDL library itself, just something that I could go from?

I was thinking that the full command would be something like:

nim c --dynlibOverride:libSDL2 --passL:"-lSDL2 -lSDL2main" main.nim

for --dynlibOverride, I also tried just SDL2 as well with the same results.

While that does compile, it doesn't add anything to the binary. To get this to work, should I actually be compiling SDL from source to allow linking in such a manner? I just was using the MS binaries from SDL and my package manager for Neon.

No, I have yet to compile the libs for either platform. I got the dev libraries for Linux via the package manager and I got the runtime only binaries from SDL website for Windows. I put the Windows dlls in the .nimble/bin location as well.

I did update yesterday to Nim 1.6.0 (I just noticed that a new version came out 2 days ago).

So I used this command:
nim c --dynlibOverride:SDL2 --passL:"-static -lSDL2 -lSDL2main" main.nim

I get a compiler error of:
warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

I thought that by using -static flag that would have pulled in what was being used from glibc as well? Is that wrong?

Since I got that compiler error, I don't know if that command would have worked otherwise.

I tried compiling with https://stackoverflow.com/questions/69158045/static-link-sdl2-on-linux
and also got this warning.
image

So, just for giggles, I tried to see if I could come up with a bash script to handle the dependencies in a folder called "lib" that would travel with the binary.

The script that I tried was:
#!/bin/sh

export DIRNAME="$(dirname "$(readlink -f "$0")")"
export SYSTEM_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"

export MAIN_ASSETS_DIR="$DIRNAME/assets/"

cd "$DIRNAME"

export LD_LIBRARY_PATH="$DIRNAME/lib:$LD_LIBRARY_PATH"
"$DIRNAME/bin/main" "$@"

But alas, it was not meant to be. The program still just kept on telling me that libSDL was not found etc.

Well, adding this to my usual command:
--gc:orc --deepCopy:on

That did result in a slightly bigger binary, but it still wasn't finding SDL on the second computer that doesn't have SDL on it, so that extra is either related to garbage collection or something else. I had always thought that that flag would have stripped away collection, but I'm one of those that knows enough to cause damage, so it might have the reverse.