PDA

View Full Version : Linker and dependencies


ggambett
08-17-2005, 11:02 AM
I'm thinking of adding a hardware-accelerated renderer to my otherwise software 2D engine. This is a somewhat basic question but I want to be sure I get it right.

Some of the games will use OpenGL rendering, some won't. I want to have both Renderer classes in the same lib. My fear is that in a game that doesn't use the OpenGL driver, there will still be a dependency on OpenGL because of the presence of the class, even if there's no code to instantiate it.

Suppose I have SDLRenderer.obj and GLRenderer.obj in GameLib.lib. There is NO code in GameLib.lib that creates an instance of GLRenderer. I expect things to work like this :

cc MySoftwareRendererGame.cpp -l GameLib.lib -> works fine, the GL code isn't used so it isn't linked, the game doesn't need OpenGL.dll
cc MyGLRendererGame.cpp -l GameLib.lib -l OpenGL -> works fine, the game depends on OpenGL.dll as it should
cc MyGLRendererGame.cpp -l GameLib.lib -> undefined references to the OpenGL functions

Does my logic contain any bugs I'm not seeing?

Note : Yes, I know I could load the DLL manually and GetProcAddress() the OpenGL functions, but that's not what I'm trying to do here.

PeterM
08-17-2005, 11:14 AM
Visual C++ strips out unused dependencies, unfortunately I'm not sure how to get the same effect using GCC.It must be possible...

soniCron
08-17-2005, 12:37 PM
I could be totally off target here, but I was under the impression that missing the OpenGL DLL was something that simply didn't happen under any but the worst situations, because Windows comes with the ancient 1.1 reference driver. If that's the case, there'd be no problem compiling it into your code. I bet Cas would know if this is true or not! ;)

Bad Sector
08-17-2005, 01:07 PM
i also think the same as soniCron said.... never found any sane windows machine without opengl.dll

illume
08-17-2005, 07:58 PM
SDL has a multiplatform loader for dlls. It even has some good stuff for doing opengl xplatform.

You could keep your opengl code in a separate file, and not compile that in at all. You'll save a few KB too ;)

ggambett
08-17-2005, 08:25 PM
I'm using the SDL-OpenGL interface, in fact. Unfortunately, the last time I tried the SDL DLL loader, it didn't work in the Mac :(

I think the linker already does what I want to do. And you're right guys, opengl.dll is probably there anyway.

Sharkbait
08-17-2005, 11:42 PM
I have just implemented an OpenGL renderer to complement the SDL-powered equivalent in software. Come to think of it, I am simply linking in opengl32.lib, that in turn attempts to load in the DLL and probably crashes if it cannot find it, regardless of whether I use OpenGL or not! :eek:

Any ideas of how this issue should be tackled?

Phil Steinmeyer
08-18-2005, 06:19 AM
The general Win32 way of being truly dynamic about using DLLs (and not crashing if the DLL is not present), is to use the LoadLibrary function (in the Win32 API). I'm not sure if SDL has any wrapper functions for this, but it's not hard to use directly.

Nikster
08-18-2005, 06:46 AM
Worthless post removed.

Sharkbait
08-18-2005, 11:49 AM
I think I've found a solution for this, at least for the Win32 platform. As you may already be aware, linking opengl32.lib to take care of the function imports and actual library loading causes the executable to fail on startup before any opengl functions (and tests for hardware) are called.

A remedy for this is to use a linker option available in VC++ 6 and later versions called Delay Loading. The linker option has to be specified in the linker command line e.g. /DELAYLOAD:opengl32.dll in VC++ 6. In VS 2002+, a Delay Loaded DLLs field is available under Linker/Inputs.

This linker option essentially delays loading and importing of the opengl functions until they are called the first time.

Using SDL, the opengl dll will only be called on calling SDL_SetVideoMode(...), so this gives the coder an opportunity to test for hardware using SDL_VideoModeOk(...) before setting up the screen.

Here's my code for reference:

bool VideoManagerImpl::IsHardwareSupported(
int iWidth, int iHeight, bool bFullScreen)
{
int iFlags = SDL_HWSURFACE | SDL_OPENGL;
if (bFullScreen) iFlags |= SDL_FULLSCREEN;
return SDL_VideoModeOK(iWidth, iHeight, 32, iFlags);
}

I am not really sure if my approach is sound, but I did indeed verify through the debugger that Opengl32.dll is not loaded until the SetVideoMode call .

I don't know if there's an equivalent linker option in other platform compilers/linkers. For now at least, I seem to have a working solution for Win32.