Ian Romanick wrote: > > On Tue, Apr 23, 2002 at 12:49:20AM +0100, Keith Whitwell wrote: > > > Well, you're doing something you're not supposed to do & as a result > > glXGetProcAddress isn't working right. > > > > Do you really need to call your symbol glBegin? How about xyzBegin or > > similar? > > I have managed to solve this problem (see below), but first I'll give some > background. I had a rather large chunk of OpenGL code from a non-Linux > system that made some assumptions about what extensions would be available > in libGL.so. It checked to make sure that the extensions were enabled in > the driver before calling them, but it still assumed that the linker would > be able to resolve them at load time. Since a number of these extensions > don't exist in Mesa, the program would compile just fine, but it would not > link. > > I *really* did not want to have to make changes to the source code. It is > about 100,000 LOC, and changing the source with a bunch of ifdefs sounded > like way too much work. My initial attempt at working around this was to > write a script that would process glext.h and use the PFNGL* typedefs to > create a bunch of pointers-to-functions. It also generated a table of > structures that I would use with glXGetProcAddress to resolve the pointers. > > struct gl_extension > { > /* Name of the function that is needed. > */ > const char * name; > > /* Pointer to the pointer-to-function. > */ > void ** function; > }; > > A short stub routine would get called once at start up to fill in all of the > function pointers using glXGetProcAddress. Since all of the C files > included a header file that declared all of the extension functions as > pointer-to-function, the compiler would generate code to call it the right > way. If everything worked correctly, I would need to make no changes to the > 100,000 lines of application code. > > Everything did work correctly UNTIL it came time to resolve a function that > was exported by libGL.so. I believe the function that actually started the > whole mess was glTexImage3DEXT, but it could have just as easilly been any > of a number of functions. As near as I can tell, when ld.so loaded > libGL.so, it saw that glTexImage3DEXT was in address space already, so it > didn't bother to load it from the library. All references to > glTexImage3DEXT in the library were directed to the symbol in the > application. The end result being that glXGetProcAddress( "glTexImage3DEXT" ) > returned a pointer to the address where I was going to store it! > > I did find a very inelegant way to work around this (for those not > completely following, this is a work around to a work around *grin*). > Instead of having the script create a header file with the > pointers-to-functions having their actual OpenGL names, it prepends foo_ to > all of the names. glTexImage3DEXT becomes foo_glTexImage3DEXT. It then > generates a define to redirect the OpenGL name to the foo_ name. > > #define glTexImage3DEXT foo_glTexImage3DEXT > > Since this happens in the C preprocessor, ld.so never has any knowledge of > it. All it sees in the application is foo_glTexImage3DEXT, so it knows that > it still needs to resolve glTexImage3DEXT from libGL.so. > > I *KNOW* that I cannot be the first person who has ever had to try and solve > this problem. The OpenGL developer FAQ provides some hints, but really only > gives enough information to get from an unlinkable application to an > unrunable application. > > http://www.opengl.org/developers/faqs/technical/extensions.htm#0060 > > How have other people solved this? If there are some particularly good > sollutions out there, perhaps we could recommend that they be added to the > OpenGL developer FAQ. That sure would have saved me some trouble!
I fought this problem a while back when working on the Chromium project. The bottom line is that when libGL itself is built, one needs to use the option -Xlinker -Bsymbolic (for GCC anyway). This ensures that libGL's references to the GL functions are satisfied by the symbols in libGL, and not the symbols in the application. The 'ld' man page says: `-Bsymbolic' When creating a shared library, bind references to global symbols to the definition within the shared library, if any. Normally, it is possible for a pro gram linked against a shared library to override the definition within the shared library. This option is only meaningful on ELF platforms which support shared libraries. I'm using this flag now in Mesa when I build libGL.so but the fix should also be applied to the DRI trunk. I'll have to investigate how to add this to the Imakefile options. But to play it safe, you may want to continue using your work-arounds since few libGL's in the field have been built with this option. -Brian _______________________________________________ Dri-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/dri-devel