www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - BindBC Updates: new loader function, SDL_net, streamlined SDL_*

reply Mike Parker <aldacron gmail.com> writes:
I've recently implemented some improvements centered on 
bindbc-sdl.

== New Loader Function

I've added a function to bindbc-loader (on Windows only) to allow 
adding a single path to the default DLL search path. This is to 
solve the problem that some of the SDL satellite libraries would 
fail to load when placed in a directory outside of the search 
path, such as a ./libs subdirectory.

The problem is that SDL loads its dependencies dynamically. So 
when a bindbc user would load a lib with a custom path, e.g., 
`loadSDLImage("libs\\SDL2_image.dll")`, the system loader would 
find that DLL just fine, but then when it in turn attempted to 
load a dependency like libpng, the system loader would search the 
DLL search path and *not* the libs subdirectory, thereby causing 
a failure.

Now you can do this:

```
version(Windows) setCustomLoaderSearchPath("libs");

if(loadSDL() < sdlSupport) { /* handle error */ }
if(loadSDL_Image() < sdlImageSupport) { /* handle error */ }

// Give SDL_image a chance to load libpng and libjpeg (it loads 
them lazily
// when the corresponding flags are passed to IMG_Init.
auto flags = IMG_INIT_PNG | IMG_INIT_JPEG;
if(IMG_Init(flags) != flags) { /* handle error */ }

// Now reset the default loader search path
version(Windows) setCustomLoaderSearchPath(null);
```

It's up to the caller to ensure the path is valid. For example, 
if the executable is run from a different directory, then "libs" 
will not be relative to the current working directory. 
`SDL_GetBasePath` can help there:

https://wiki.libsdl.org/SDL_GetBasePath?highlight=%28%5CbCategoryFilesystem%5Cb%29%7C%28CategoryEnum%29%7C%28CategoryStruct%29

I'm unaware of any issues with other libraries BindBC binds to, 
but if they do arise, this will solve those, too.

== SDL_net

I didn't initially port SDL_net over because I didn't think 
anyone was using it. I was waiting for someone to request it. 
Someone did. It's a small API, so it took a matter of minutes to 
complete.

== Streamlined SDL_* version identifiers

Previously, the SDL satellite library bindings could be enabled 
with e.g., `BindSDL_Image`, `BindSDL_TTF`, etc. That would enable 
the lowest supported version of the library. To enable a more 
recent version, an additional identifier was required 
(`SDL_Image_205`, `SDL_TTF_2014`). That's just dumb. Now, only 
one identifier is required, e.g., `SDL_Image_205` will do the 
trick by itself now. `SDL_Image` is equivalent to the 
`SDL_Image_200`. The old approach is still supported, though, so 
current build configs should continue to work without change.

See the loader documentation for details on the new function:

https://github.com/BindBC/bindbc-loader

There's also a bit about it in the bindbc-sdl documentation, 
along with the details about the approach to version identifiers.

https://github.com/BindBC/bindbc-sdl/blob/master/README.md

I've got some bigger packages to port over from Derelict yet (the 
OpenCL binding, for example). I've also had a request to include 
support for SDL's thread/mutex API so folks using DasBetterC can 
have access to it. That's all in the pipeline. Going forward, I 
plan to devote a handful of hours one day a week to bindbc until 
I've implemented everything on my task list, so it will get done 
sooner rather than later.
May 13 2020
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Wednesday, 13 May 2020 at 14:39:13 UTC, Mike Parker wrote:

 It's up to the caller to ensure the path is valid. For example, 
 if the executable is run from a different directory, then 
 "libs" will not be relative to the current working directory. 
 `SDL_GetBasePath` can help there:

 https://wiki.libsdl.org/SDL_GetBasePath?highlight=%28%5CbCategoryFilesystem%5Cb%29%7C%28CategoryEnum%29%7C%28CategoryStruct%29
Well, duh. I put the cart before the horse on that one. SDL2.dll is going to be in the same subdirectory since all the others depend on it and will fail to load if it isn't there (they don't load it dynamically, of course). Working with args[0] or, since this is a Windows-only thing, calling the Win32 API directly (GetModuleFileName, IIRC) will get you there.
May 13 2020
prev sibling next sibling parent reply Claude <claudemr live.fr> writes:
On Wednesday, 13 May 2020 at 14:39:13 UTC, Mike Parker wrote:
 I've recently implemented some improvements centered on 
 bindbc-sdl.
As a user of BindBC (and former Derelict), I really enjoy using those binding libraries. It's some great work, thanks.
May 14 2020
parent Mike Parker <aldacron gmail.com> writes:
On Thursday, 14 May 2020 at 09:55:15 UTC, Claude wrote:

 As a user of BindBC (and former Derelict), I really enjoy using 
 those binding libraries. It's some great work, thanks.
Thanks!
May 16 2020
prev sibling next sibling parent reply Andre Pany <andre s-e-a-p.de> writes:
On Wednesday, 13 May 2020 at 14:39:13 UTC, Mike Parker wrote:
 I've recently implemented some improvements centered on 
 bindbc-sdl.

 [...]
A little bit off topic. I wondered whether it is possible to combine dpp and bindbc. Maybe a separate Tool which creates a bindbc packages based on dpp output or even integrates into dpp? Did you already considered s.th. like that? Kind regards Andre
May 16 2020
parent Mike Parker <aldacron gmail.com> writes:
On Saturday, 16 May 2020 at 09:00:25 UTC, Andre Pany wrote:

 A little bit off topic. I wondered whether it is possible to 
 combine dpp and bindbc. Maybe a separate Tool which creates a 
 bindbc packages based on dpp output or even integrates into dpp?

 Did you already considered s.th. like that?
Hasn't even crossed my mind. My first thought is that I don't see it as a good fit. Although all of my bindings follow a similar pattern, there are details specific to some of the libraries that led me to break the pattern. This arises mostly in the way different libraries handle their release versioning. Given dpp's use case, I don't see it as a generator of bindings that cover multiple library versions.
May 16 2020
prev sibling parent reply Daniel C <dcrep rep.com> writes:
Can this library be used in a 64-bit build?  I only see the one 
lib, and was curious if the function definitions make any 
assumptions about argument size or stack configuration etc.
May 21 2020
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 22/05/2020 12:21 PM, Daniel C wrote:
 Can this library be used in a 64-bit build?  I only see the one lib, and 
 was curious if the function definitions make any assumptions about 
 argument size or stack configuration etc.
There are no binary files provided in the bindbc-sdl repository. https://github.com/BindBC/bindbc-sdl It is a binding, it should match 1:1 definition wise to the C definition.
May 21 2020
parent reply Daniel C <dcrep rep.com> writes:
 There are no binary files provided in the bindbc-sdl repository.

 https://github.com/BindBC/bindbc-sdl

 It is a binding, it should match 1:1 definition wise to the C 
 definition.
There is a library file included in the dub repository download: https://code.dlang.org/packages/bindbc-sdl Also, when setting it to static compile, it complains during linking there are missing functions, even though I've already added the appropriate SDL library files. Oddly, when I use dub to compile the library file for bindbc-sdl, when I include that library file during linking it causes an error that it's not a valid library file... even though it was created with dub + dmd? Some odd things going on. I'm on Windows 7 x64 btw Thanks
May 22 2020
parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 22 May 2020 at 22:20:55 UTC, Daniel C wrote:

 There is a library file included in the dub repository 
 download: https://code.dlang.org/packages/bindbc-sdl
What download are you referring to? I don't have any library files in the git repository, and I don't know of any downloads from the duo repository.
 Also, when setting it to static compile, it complains during 
 linking there are missing functions, even though I've already 
 added the appropriate SDL library files.
What are the missing symbols?
 Oddly, when I use dub to compile the library file for 
 bindbc-sdl, when I include that library file during linking it 
 causes an error that it's not a valid library file... even 
 though it was created with dub + dmd?  Some odd things going 
 on.  I'm on Windows 7 x64 btw
Are you building it separately from your app? Or is it a dependency in your app's dub configuration? Please provide the commands you are using and the errors you are seeing. Then I can have an idea of what's going on.
May 22 2020
parent reply Daniel C <dcrep rep.com> writes:
On Saturday, 23 May 2020 at 01:23:38 UTC, Mike Parker wrote:
 What download are you referring to? I don't have any library 
 files in the git repository, and I don't know of any downloads 
 from the duo repository.
Huh.. I'm not sure, it must have gotten there when I dub'd something lol. Sorry
 Also, when setting it to static compile, it complains during 
 linking there are missing functions, even though I've already 
 added the appropriate SDL library files.
What are the missing symbols?
This is what I'm getting: Error 42: Symbol Undefined __D6bindbc3sdl4bind9sdlevents9SDL_Event6__initZ
 Are you building it separately from your app? Or is it a 
 dependency in your app's dub configuration?
I did build it using dub from the downloaded folder, but I suppose that was pointless as the .lib file that's generated isn't even recognized. I'm building my app without dub. I've now put all the source files into the same folder as my project and I'm still seeing the same undefined symbol issue.
 Please provide the commands you are using and the errors you 
 are seeing. Then I can have an idea of what's going on.
dmd.exe sdl_bindbc_test.d -g -m32 -w -debug -version=BindSDL_Static -version=SDL_2012 -version=SDL_Image_205 SDL2.lib SDL2_image.lib Honestly it could be something I'm missing. I saw the "-betterC" option in the documentation, but I assumed that my entire app would need to use -betterC so I avoided it. Apologies if it's something dumb I'm overlooking.
May 22 2020
next sibling parent reply Daniel C <dcrep rep.com> writes:
On Saturday, 23 May 2020 at 03:25:12 UTC, Daniel C wrote:
 I'm building my app without dub.  I've now put all the source 
 files into the same folder as my project and I'm still seeing 
 the same undefined symbol issue.
I should say, I put the bindbc library into a subfolder. So it's like this: project/bindbc/sdl/bind The SDL lib files are in the same folder with the source, primarily because the LIB environment variable was being ignored by the compiler/linker.
May 22 2020
parent reply Mike Parker <aldacron gmail.com> writes:
On Saturday, 23 May 2020 at 03:29:44 UTC, Daniel C wrote:
 On Saturday, 23 May 2020 at 03:25:12 UTC, Daniel C wrote:
 I'm building my app without dub.  I've now put all the source 
 files into the same folder as my project and I'm still seeing 
 the same undefined symbol issue.
I should say, I put the bindbc library into a subfolder. So it's like this: project/bindbc/sdl/bind The SDL lib files are in the same folder with the source, primarily because the LIB environment variable was being ignored by the compiler/linker.
I suggest you create project/lib and drop the SDL libraries there along with the bindbc-sdl library and pass the path to the linker. Since you should be using the MS linker (see below), it expects the /LIBPATH option (https://docs.microsoft.com/en-us/cpp/build/reference/libpath-additional-li path?view=vs-2019), which you can add to your dmd commandline as `-L/LIBPATH:lib`. Of course, that's assuming you've got the Microsoft Build Tools installed either independently or as part of a Visual Studio installation. If not, you'll be using the LLVM linker that ships with DMD. I believe in that case it should be `-L-Llib`. If you really want 32-bit and to statically link with the SDL import libraries, I strongly recommend you use the -m32mscoff dmd options (and the corresponding -ax86_mscoff dub option). The SDL libraries are distributed as COFF, not OMF, so using OPTLINK would require converting the lib files to OMF first.
May 22 2020
parent reply Daniel C <dcrep rep.com> writes:
On Saturday, 23 May 2020 at 04:07:35 UTC, Mike Parker wrote:
 I suggest you create project/lib and drop the SDL libraries 
 there along with the bindbc-sdl library and pass the path to 
 the linker. Since you should be using the MS linker (see 
 below), it expects the /LIBPATH option 
 (https://docs.microsoft.com/en-us/cpp/build/reference/libpath-additional-li
path?view=vs-2019), which you can add to your dmd commandline as
`-L/LIBPATH:lib`. Of course, that's assuming you've got the Microsoft Build
Tools installed either independently or as part of a Visual Studio
installation. If not, you'll be using the LLVM linker that ships with DMD. I
believe in that case it should be `-L-Llib`.

 If you really want 32-bit and to statically link with the SDL 
 import libraries, I strongly recommend you use the -m32mscoff 
 dmd options (and the corresponding -ax86_mscoff dub option). 
 The SDL libraries are distributed as COFF, not OMF, so using 
 OPTLINK would require converting the lib files to OMF first.
Thanks. I did have SDL in a project/lib folder and was trying to set LIB and then use -L and other options, but I suppose I borked that up as well. Thanks again for the tips! I'll be mucking around with it again later.
May 23 2020
parent reply Daniel C <dcrep rep.com> writes:
On Saturday, 23 May 2020 at 19:59:51 UTC, Daniel C wrote:
 I'll be mucking around with it again later.
Well, I'm having limited success. I got 32-bit compile/run using basic -m32, and -m64 compiles but crashes lol. Trying out 32-bit -m32mscoff with Microsoft Build Tools (2019) resulted in this mess: phobos32mscoff.lib(runtime_c8b_76e.obj) : error LNK2001: unresolved external sym bol _printf phobos32mscoff.lib(parseoptions_d98_7cf.obj) : error LNK2001: unresolved externa l symbol _printf phobos32mscoff.lib(gc_244f_122.obj) : error LNK2001: unresolved external symbol _printf phobos32mscoff.lib(msvc_32mscoff.obj) : error LNK2001: unresolved external symbo l __vsnprintf phobos32mscoff.lib(parseoptions_d93_21b.obj) : error LNK2001: unresolved externa l symbol _sscanf Frustrating! I don't even know where to go for help with that stuff. Through experimentation, I was able to compile with older Visual C++ 2010 tools, but I'd rather not be using 10 year old tech. Maybe this wasn't the time for me to come back lol
May 23 2020
parent reply Mike Parker <aldacron gmail.com> writes:
On Sunday, 24 May 2020 at 04:16:10 UTC, Daniel C wrote:
 On Saturday, 23 May 2020 at 19:59:51 UTC, Daniel C wrote:
 I'll be mucking around with it again later.
Well, I'm having limited success. I got 32-bit compile/run using basic -m32, and -m64 compiles but crashes lol. Trying out 32-bit -m32mscoff with Microsoft Build Tools (2019) resulted in this mess: phobos32mscoff.lib(runtime_c8b_76e.obj) : error LNK2001: unresolved external sym bol _printf phobos32mscoff.lib(parseoptions_d98_7cf.obj) : error LNK2001: unresolved externa l symbol _printf phobos32mscoff.lib(gc_244f_122.obj) : error LNK2001: unresolved external symbol _printf phobos32mscoff.lib(msvc_32mscoff.obj) : error LNK2001: unresolved external symbo l __vsnprintf phobos32mscoff.lib(parseoptions_d93_21b.obj) : error LNK2001: unresolved externa l symbol _sscanf Frustrating! I don't even know where to go for help with that stuff. Through experimentation, I was able to compile with older Visual C++ 2010 tools, but I'd rather not be using 10 year old tech.
There should be no need to revert to VS 2010. These errors indicate that something in your build process or setup is borked. Have you tried building your app with dub and using bindbc-sdl as a dependency rather than doing it separately DMD? This way, you can ensure that everything is being compiled with the same options and the linker is getting the correct libraries.
 Maybe this wasn't the time for me to come back lol
I would say it's generally much easier to build D projects these days than it ever has been. We just need to figure out where you're going wrong.
May 23 2020
parent reply Daniel C <dcrep rep.com> writes:
On Sunday, 24 May 2020 at 05:15:19 UTC, Mike Parker wrote:
 On Sunday, 24 May 2020 at 04:16:10 UTC, Daniel C wrote:
 On Saturday, 23 May 2020 at 19:59:51 UTC, Daniel C wrote:
There should be no need to revert to VS 2010. These errors indicate that something in your build process or setup is borked. Have you tried building your app with dub and using bindbc-sdl as a dependency rather than doing it separately DMD? This way, you can ensure that everything is being compiled with the same options and the linker is getting the correct libraries.
I figured it out by going through the changelog for the compiler. From "Change Log: 2.069.0" https://dlang.org/changelog/2.069.0.html#link-against-vs2015 "If you don't use dmd for linking, make sure to add legacy_stdio_definitions.lib to your command line when linking against the VS2015 runtime." Adding legacy_stdio_definitions.lib fixed that last problem. The 64-bit build is working as well.. I had mistakenly put the wrong DLL alongside it *facepalm*. It's using the default linker for 64-bit though, so I'll need to try with the Visual Studio linker. Now that I've figured out the rest, I think it should be trivial though. Obviously the legacy_stdio_definitions.lib file needs to be documented somewhere on this site other than on a changelog. I will probably use dub for projects in the future, but I wanted a quick compilation option for building single-file programs without the extra setup and structure dub entails. Anyway, thanks for your help Mike! Without it I may have given up on D for another year or so ;-)
May 23 2020
parent Mike Parker <aldacron gmail.com> writes:
On Sunday, 24 May 2020 at 06:39:27 UTC, Daniel C wrote:


 "If you don't use dmd for linking, make sure to add 
 legacy_stdio_definitions.lib to your command line when linking 
 against the VS2015 runtime."
Good find. If I was ever aware of that, I had forgotten about it.
 Anyway, thanks for your help Mike! Without it I may have given 
 up on D for another year or so ;-)
Glad I could help!
May 24 2020
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Saturday, 23 May 2020 at 03:25:12 UTC, Daniel C wrote:
 On Saturday, 23 May 2020 at 01:23:38 UTC, Mike Parker wrote:
 What download are you referring to? I don't have any library 
 files in the git repository, and I don't know of any downloads 
 from the duo repository.
Huh.. I'm not sure, it must have gotten there when I dub'd something lol. Sorry
It gets there when you build it :-)
 Also, when setting it to static compile, it complains during 
 linking there are missing functions, even though I've already 
 added the appropriate SDL library files.
What are the missing symbols?
This is what I'm getting: Error 42: Symbol Undefined __D6bindbc3sdl4bind9sdlevents9SDL_Event6__initZ
This isn't a symbol from the SDL library. It's a D symbol from the binding.
 Are you building it separately from your app? Or is it a 
 dependency in your app's dub configuration?
I did build it using dub from the downloaded folder, but I suppose that was pointless as the .lib file that's generated isn't even recognized. I'm building my app without dub. I've now put all the source files into the same folder as my project and I'm still seeing the same undefined symbol issue.
 Please provide the commands you are using and the errors you 
 are seeing. Then I can have an idea of what's going on.
dmd.exe sdl_bindbc_test.d -g -m32 -w -debug -version=BindSDL_Static -version=SDL_2012 -version=SDL_Image_205 SDL2.lib SDL2_image.lib
You didn't link with the bindbc-sdl library. But a couple of points about that -m32 option: 1. On Windows, DMD always builds with -m32 by default, so you don't need to specify it. 2. It means you're using the default OPTLINK linker which requires object files in the OMF format. 3. The COFF format is more common in the Windows ecosystem, which the -m32mscoff and -m64 options will cause to be generated 4. Unlike DMD, dub will use the system architecture on Windows for the default build, meaning on 64-bit Windows it will automatically pass -m64 to DMD.
 Honestly it could be something I'm missing.  I saw the 
 "-betterC" option in the documentation, but I assumed that my 
 entire app would need to use -betterC so I avoided it.
No. You can link to betterC libraries with a normal D app.
 Apologies if it's something dumb I'm overlooking.
Essentially, the bindbc-sdl library you built is invalid because dub built it with -m64 (unless you explicitly passed -ax86 on the dub command line) and you built your app with -m32, giving you both an architecture mismatch and an object file format mismatch. Then your dmd command is missing the bindbc-sdl library, hence the linker error.
May 22 2020
parent Daniel C <dcrep rep.com> writes:
On Saturday, 23 May 2020 at 03:55:33 UTC, Mike Parker wrote:
 On Saturday, 23 May 2020 at 03:25:12 UTC, Daniel C wrote:
 This is what I'm getting:
  Error 42: Symbol Undefined 
 __D6bindbc3sdl4bind9sdlevents9SDL_Event6__initZ
This isn't a symbol from the SDL library. It's a D symbol from the binding.
I figured as much, that's why I tried to link against the bindbc-sdl library at first (which then gave me the invalid library file error). I removed it from the line I posted to get that message to reappear.
 You didn't link with the bindbc-sdl library. But a couple of 
 points about that -m32 option:

 1. On Windows, DMD always builds with -m32 by default, so you 
 don't need to specify it.
 2. It means you're using the default OPTLINK linker which 
 requires object files in the OMF format.
 3. The COFF format is more common in the Windows ecosystem, 
 which the -m32mscoff and -m64 options will cause to be generated
 4. Unlike DMD, dub will use the system architecture on Windows 
 for the default build, meaning on 64-bit Windows it will 
 automatically pass -m64 to DMD.
Ugh, I remember running into build issues when I gave D a shot a few years ago. There's a lot of options and specifics that aren't very well documented, or at the very least confusing. In the case of Dub, it felt to me like some black box that wasn't clear as to what it was doing (even having tried to read the documentation a few times). I felt more in control and aware of what was going on with dmd but lol, again I was missing something.
 No. You can link to betterC libraries with a normal D app.
Oh, that's good news. I'll pass that option next time.. or actually - I'm not sure what will change in the generated library?
 Essentially, the bindbc-sdl library you built is invalid 
 because dub built it with -m64 (unless you explicitly passed 
 -ax86 on the dub command line) and you built your app with 
 -m32, giving you both an architecture mismatch and an object 
 file format mismatch.

 Then your dmd command is missing the bindbc-sdl library, hence 
 the linker error.
Ah. Dub did do something mischievous after all ;-) And thanks, yeah I'll add the bindbc-sdl library back in after I get my command lines straight. More experimentation ahead. Thanks so much for your help!
May 23 2020