Crossplatform Engine in a DLL/SO?

Started by
12 comments, last by Puzzler183 19 years, 4 months ago
Well, it's come the time to decide. I know I should put my engine in a DLL; however, I'm not entirely sure how the shared object systems work on Mac and Linux beyond loading them. If I can't get it to build into a DLL with one setting and then a quick change will let me build a shared object, I won't do it since I want this to be crossplatform. So my question is, what have your experiences been with making something dynamically linkable accross platforms? And does anyone know of a good refernce for making shared objects on Mac/Linux other than what Google returns?
Advertisement
Are you using Visual Studio for your Windows development? If so, then you are not going to be able to just do a "quick change", but rather will have to set up two entirely separate build environments. You can also install cygwin on Windows and use gcc as your development environment, but you will lose the debugging capabilities of VS (though you do get gdb).

Personally, I'd still go the route of VS on Windows and gcc for your Unix ports. It's not really that big of a deal.

However, if this is your first game engine, then I'd scrap crossplatform all together and just focus on getting a good engine for a single platform. Learn the lessons, and then write a new engine that is multiplatform.

Best of luck!

Jeff
Jeff Thompson
A Portable DLL/SO Solution is an article that answers most of your questions. Alternatively, read the man pages for dlopen, dlsym, etc., which are the equivalents of Windows's LoadLibrary functions. To answer your fundamental question, it's not that hard. :-) A few differences in the compilation method, obviously, especially between VC and gcc, but the concepts are all the same. I recommend you go for it.

-bodisiw
-bodisiw
I know I'll have to set up two build environments for the two; the goal is to have as little code changing as possible. I used Dev-C++ and GCC because I like it a lot more than VS (and I have the most recent VS, legally, so please don't say to try the latest one). For the general record, I'm not exactly a newbie; I've just never bothered to put my stuff in a DLL before.

I know about how to load and that under linux; I've just never made a shared object. That article looks like something good though so I'll give it a read.

EDIT: The article had exactly what I needed. Thank you.
I'd love to know why you feel that a DLL/SO is so much better than a static library?

The binary will not be compatible between platforms anyway. There is no point in making it as a dynamic library, it will just serve to cause confusion.

Creating a static library places no overheads on development - there isn't anything you can't do with a static library. So just use one of those instead.

Mark
I was actually hoping to make both; I suppose though I at least need a library. I'm not exactly sure how to compile just a library, however, since I'm not experienced with DLL's or libraries beyond loading and using them.

Hmmm... So say I just made a library with that build option. I would still need the header files I have for all the class definitions and that; would the library be able to handle having methods in it? And do I need any special export options for a library?
Quote:Original post by markr
I'd love to know why you feel that a DLL/SO is so much better than a static library?

The binary will not be compatible between platforms anyway. There is no point in making it as a dynamic library, it will just serve to cause confusion.

Creating a static library places no overheads on development - there isn't anything you can't do with a static library. So just use one of those instead.

Mark


Ok, here is why a shared library is so much better than a static library:

1. Compiling dependancies. With a static library, any change to your library code requires a complete recompile of the executable. I'll assume that you understand the enormous consequences of this action.

2. Following from 1), swapping sub-systems and memory requirements. When you can at run-time load in only the libraries you need (aka, D3D library vs Ogl library), you are saving resources.

I'm not sure how using a shared library causes any sort of confusion whatsoever, and deducing from point #1, using a static library causes INCREDIBLE development overhead. With static libraries, you can't have a team working on the renderer with another team working on the sound system, with another team working on the gameplay. It's all about Modularity, only making systems interact where they are absolutely needed.

Anyway, to help the thread-starter, and others who might not know, it's very easy to set up a build system to create a platform specific library. Yes, .dll's built on Windows are not compatable on a Linux system, but it's easy to build the required libraries when needed. As a developer who uses Linux, I'm a huge fan of the command-line. Look into tools like Automake and SCons for easily creating the respectable libraries for the platform you're compiling on.

As for actually creating a library, with VS it's pretty easy, and there are plenty of tutorials about how to export classes and functions (search for __declspec, which is Windows specific. Linux and Mac don't need a special keyword).

And just as an example, in my game engine I will be statically linking the core library to the executable (as there really is no cleaner way to do this) and having all my subsystems (renderer, sound system, etc) in their own shared libraries, pulling them in run-time as needed.
Quote:Original post by JamesKilton
Ok, here is why a shared library is so much better than a static library:

1. Compiling dependancies. With a static library, any change to your library code requires a complete recompile of the executable. I'll assume that you understand the enormous consequences of this action.


I'm not following what the enormous consequences are?

Any change to the static library code will require a recompile of any code that depends on the changes made to the library, and the relinking of the executable.

If the library code is a dynamic library, all code that depends on the changes will still need to be recompiled.

So the gain is no linking step and only if there are absolutely no depencies on the changed code.

I'm happy to hear that I'm missing something.

Quote:
2. Following from 1), swapping sub-systems and memory requirements. When you can at run-time load in only the libraries you need (aka, D3D library vs Ogl library), you are saving resources.


This is true. You also gain in being able to distribute new subsystems, or patches for only the subsystem to your endusers. Of course, you now have to manage all of the versions of the various DLL's and the main executable to make sure you have the user properly patched all around. Not a big deal, but it is a harder problem than simply patching one executable.

Basically, version 1.20 loses meaning as you now have version 1.20 main executable, version 2.0 D3D renderer, etc.. This can cause huge problems for support.

Quote:
I'm not sure how using a shared library causes any sort of confusion whatsoever, and deducing from point #1, using a static library causes INCREDIBLE development overhead. With static libraries, you can't have a team working on the renderer with another team working on the sound system, with another team working on the gameplay.


I'm not sure how this follows at all. You can still have separate systems under a static library system. Being static or shared in no way forces a development style on you. There really isn't anything that prevents you from having multiple teams and people working on various aspects of the engine.


Quote:
It's all about Modularity, only making systems interact where they are absolutely needed.


On this we agree 100%. Messing this up is a huge portion of the troubles development teams encounter. I also do feel that using shared libraries nudges people in this direction, but it certainly isn't necessary in order to get people to write good interfaces to the various subsystems.

Quote:
And just as an example, in my game engine I will be statically linking the core library to the executable (as there really is no cleaner way to do this) and having all my subsystems (renderer, sound system, etc) in their own shared libraries, pulling them in run-time as needed.


Best of luck with your engine, I hope it turns out great!

Jeff
Jeff Thompson
Quote:Original post by jwthomp
I'm not following what the enormous consequences are?

Any change to the static library code will require a recompile of any code that depends on the changes made to the library, and the relinking of the executable.

If the library code is a dynamic library, all code that depends on the changes will still need to be recompiled.

So the gain is no linking step and only if there are absolutely no depencies on the changed code.

I'm happy to hear that I'm missing something.



The point of a shared/dynamic library is that you don't have to ever touch other code using that library UNLESS you're either a crappy programmer or the design was so bad that you had to change your API. That's the point of a library, a public API which doesn't change while the internals are hidden and not connected to anything outside. While this works with a static library as well, again, such interconnectedness is a Bad Thing(tm). Do you understand that?

Quote:
This is true. You also gain in being able to distribute new subsystems, or patches for only the subsystem to your endusers. Of course, you now have to manage all of the versions of the various DLL's and the main executable to make sure you have the user properly patched all around. Not a big deal, but it is a harder problem than simply patching one executable.

Basically, version 1.20 loses meaning as you now have version 1.20 main executable, version 2.0 D3D renderer, etc.. This can cause huge problems for support.


What's wrong with a single system version number? This feels like getting too bogged down in the details. Keeping of versions of everything, I feel, isn't necessary.

Quote:
I'm not sure how this follows at all. You can still have separate systems under a static library system. Being static or shared in no way forces a development style on you. There really isn't anything that prevents you from having multiple teams and people working on various aspects of the engine.


I think I had my mind wrapped around something else. You're right, it's just that I'm against the need to relink any executable.


Quote:
And just as an example, in my game engine I will be statically linking the core library to the executable (as there really is no cleaner way to do this) and having all my subsystems (renderer, sound system, etc) in their own shared libraries, pulling them in run-time as needed.


Best of luck with your engine, I hope it turns out great!

Jeff

Thanks.
I don't think people are getting the point. I know that a DLL can only be used on windows and that you use shared objects on Linux. The thing I'm trying to figure out is:

1) Should I make one instead of just compiling with the engine code?
2) Which to make (or both)?
3) Which to use for my purposes?
4) How are classes exported under both Windows and Linux?

This topic is closed to new replies.

Advertisement