BindBC / bindbc-sdl

Static & dynamic D bindings to SDL and the SDL_* libraries, compatible with BetterC, @nogc, and nothrow.
Boost Software License 1.0
88 stars 23 forks source link

Issue: "undefined identifier SDL_LinuxSetThreadPriorityAndPolicy" #34

Closed NullDott closed 2 years ago

NullDott commented 2 years ago

When compiling with ldc, compiler show this error.

../.dub/packages/bindbc-sdl-1.1.1/bindbc-sdl/source/bindbc/sdl/dynload.d(862,41): Error: undefined identifier `SDL_LinuxSetThreadPriorityAndPolicy`

But only when using SDL_2018 and SDL_2020 using fewer versions on dub.sdl makes executable unable to find SDL2.

Current SDL version installed: 2.0.20

mdparker commented 2 years ago

That's a compilation error, but I don't understand why it's happening. The symbol is defined in sdlsystem.d under a version(linux) block for both the static and the dynamic versions of the binding. Which platform are you compiling on?

But only when using SDL_2018 and SDL_2020 using fewer versions on dub.sdl makes executable unable to find SDL2.

That symbol was added to SDL in 2.0.18, so it isn't present in lower versions. However, if the loader isn't finding the library when compiling for a lower version, that's a problem. What is the exact error message you see in that case?

NullDott commented 2 years ago

I was doing this on Termux, trying to make a simple SDL program on my phone, just to test some things, but it ended up showing me that error and i assumed it was something from the bindings.

Apparently for what i saw, it's probably a Termux issue that fewer versions does not work, but i still don't know why that compilation error keeps happening if the symbol it's defined...

I will try to solve the problem in other way then, thanks for the response and sorry for bothering you.

mdparker commented 2 years ago

a simple SDL program on my phone

Probably what happens is your D compiler is defining version(linux) even for Android, but SDL excludes Linux-specific functions on Android.

I can work around that in the binding so that the Linux-specific stuff is excluded on Android. Give me a few days and I'll find some time for it.

That's also probably got something to do with the other problem about finding the library, too. I'll see what I can find out about it.

NullDott commented 2 years ago

Hi, it's me again!

I solved my issue, just copied the SDL_LinuxSetThreadPriorityAndPolicy symbol under a new else version(Android) {} block and it compiled totally fine, thanks for the advice Mike, now i can run my programs on Termux.

mdparker commented 2 years ago

Wow. Sorry, I forgot all about this. I'm going to reopen it, because I still can't understand why the error happened in the first place. I was rather far off about SDL excluding Linux-specific functions on Android. I must have been high. That would be a runtime error, not a compile-time error.

What I can't figure out is, if line 862 of dynload.d is being picked up by the compiler in a version(Linux) block, then why is the same not true for the declaration of the function pointer in sdlsystem.d at line 218? And why does SDL_LinuxSetPriority not also cause an error? And why did your change work?

I've ruled out the obvious potential causes and I'm left with utter confusion.

NullDott commented 2 years ago

Well, right now i can't test it anymore, Termux updates its packages almost as a rolling release distro, so i'm unable to do more tests until the bindings support SDL 2.24.0, i'll wait until then, and then i'm gonna try this again, to see if it still works, right now, the only question i have is...

Could this be a problem if i try to build for Android? I'm not really sure since i don't know about any bindbc-sdl project ported to android, and my android development knowledge is pretty lame.

mdparker commented 2 years ago

so i'm unable to do more tests until the bindings support SDL 2.24.0

You should be able to test now. The binding will load the SDL 2.24.0 shared library and only pull from it the symbols for whichever version you've configured, from 2.0.0 (the default) up to 2.22.0. The SDL API is extremely stable.

Could this be a problem if i try to build for Android?

I'm confused. I thought you were already building for Android.

NullDott commented 2 years ago

You should be able to test now. The binding will load the SDL 2.24.0 shared library and only pull from it the symbols for whichever version you've configured, from 2.0.0 (the default) up to 2.22.0. The SDL API is extremely stable.

Alright, i tested it, this is what i got:

Apparently this time the compiler can load the symbols properly but only if no version is specified in dub.json it confuses me because months ago when i tried the same, it didn't work, it's really weird.

I tried this after deleting the bindings from the .dub directory, and adding them again without any modifications. So, looks like it works now i guess?

I'm confused. I thought you were already building for Android.

I am building for Android, but i'm doing it on Termux, right on my phone, I was talking about building for Android on my Laptop with Debian, and see if this issue happens there too, but i haven't tried yet, that's why i was concerned.

At least now i can compile and run without much trouble, but the thing with the dub.json file doesn't make sense to me right now, anyway.

NullDott commented 2 years ago

Thanks again Mike, seriously, but i guess the issue can be closed for now. I'll be trying to test and build on my Laptop to see what happens, and come back here if someone goes wrong.

Thanks for the help!

mdparker commented 2 years ago

Apparently this time the compiler can load the symbols properly but only if no version is specified in dub.json it confuses me because months ago when i tried the same, it didn't work, it's really weird.

The compiler doesn't load symbols. That happens at runtime. The reason the error only happens when you specify a version is because there is no SDL_LinuxSetThreadPriorityAndPolicy anywhere in the binding for anything below SDL_2018.

The original error you posted was happening on line 862 of dynload.d. That's where the call to lad SDL_LinuxSetThreadPriorityAndPolicy is at. It's only there with SDL_2018 and higher, as specified by the static if on . What's happening is that when the compiler &SDL_LinuxSetThreadPriorityAndPolicy on line 823. But notice line 862 is also behind a version(linux).

The SDL_LinuxSetThreadPriorityAndPolicy is declared in sdlsystem.d. It's protected by the same conditional compilation constructs: a static if that causes it to only be declared when SDL_2018 or higher is set, and a version(linux).

But what your error is saying is that there is a mismatch. The compiler sees the function call in dynload.d, but it doesn't see the declaration in sdlsystem.d. And I was about to say that I don't understand why but writing it out like this and looking at the code again, I totally see what the problem is now. I should have a fix for it.

NullDott commented 2 years ago

Oh, great!

mdparker commented 2 years ago

Alright. I think tagged 1.2.2. Once the dub registry picks it up, that should fix it.

Also, I have a recommendation for you. Because the SDL API is stable, you don't need to configure the binding for the highest version supported. Figure out which version you absolutely need based on which functions you are using and define that version in you dub.json. That way, you're only compiling support for the version you need, so you won't have the symbols for the higher versions in the executable, and the loader will only attempt to load that version at runtime.

NullDott commented 2 years ago

Thanks, i will keep that in mind!