Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Static Linking

This thread is locked; no one can reply to it. rss feed Print
Static Linking
Tonto_
Member #10,690
February 2009

I am trying to use static linking in my project and at run-time, strange things seem to happen, like access violations where in regular linking mode they work fine! :o

I can't really understand why this happens but I have in my code just the preprocessor options to do static linking or not and when I do static linking, it makes my data file and bitmap loading functions fail for some reason!

I get access violations trying to load the bitmaps

In debug mode, static link it fails in _stub_bank_switch
In release mode, static link, it fails in bmp_write_line (/* bank switch function */)
But my program works fine doing the dynamic linking!

Is there something that I might be overlooking or might be blind to

Timorg
Member #2,028
March 2002

allegro/docs/build/mingw32.txt said:

When using a statically linked library, you must define the preprocessor
symbol ALLEGRO_STATICLINK before including any of the Allegro headers and
link your program against Allegro and the main Win32/DirectX libraries
in that order (see the variable LIBRARIES in makefile.mgw). The names of
the statically linked Allegro libraries are post-fixed with '_s' so that
you will link with either liballeg_s.a, liballd_s.a or liballp_s.a.

The symbol ALLEGRO_STATICLINK is important for linux, I don't know the required arguments to allegro-config off the top of my head.

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

Tonto_
Member #10,690
February 2009

I did everything as the quoted text says but I don't know what you mean by this: "I don't know the required arguments to allegro-config off the top of my head."

LennyLen
Member #5,313
December 2004
avatar

Quote:

but I don't know what you mean by this: "I don't know the required arguments to allegro-config off the top of my head."

If you're compiling for Windows then you don't need to worry about it.

Tonto_
Member #10,690
February 2009

Minimal example demonstrates my troubles. It crashes on load_bitmap with an access violation in a bitmap line reading routine. I am running 4.2.2 with Microsoft Visual Studio 2008 on Windows XP

1#define ALLEGRO_USE_CONSOLE
2#define ALLEGRO_STATICLINK
3 
4#if defined(ALLEGRO_STATICLINK)
5 #if defined(DEBUG) || defined(_DEBUG)
6 #pragma comment(lib, "alld_s")
7 #else
8 #pragma comment(lib, "alleg_s")
9 #endif
10#else
11 #if defined(DEBUG) || defined(_DEBUG)
12 #pragma comment(lib, "alld")
13 #else
14 #pragma comment(lib, "alleg")
15 #endif
16#endif
17 
18#include <stdio.h>
19#include <allegro.h>
20 
21 
22int main(int argc, char ** argv)
23{
24 allegro_init();
25 
26 
27 BITMAP *b = load_bitmap("bitmap.bmp", 0);
28 DATAFILE *d = load_datafile("test.dat");
29 
30 if(!d || !b)
31 printf("Failed: %s\n", allegro_error);
32 
33 else
34 {
35 printf("Succeeded\n");
36 unload_datafile(d);
37 }
38 
39 return 0;
40}

The program crashes with an access violation in the runtime when I do the load_bitmap line. Also on load_datafile, load_font or anything, and I just don't know why. It errors here:

uintptr_t _stub_bank_switch(BITMAP *bmp, int y)
{
   return (uintptr_t)bmp->line[y];
}

Milan Mimica
Member #3,877
September 2003
avatar

Smells like the the old non-ASM bug on Windows. And yes, it's fixed in 4.3.10+ branch. Can you recompile your program with a ALLEGRO_NO_ASM preprocessor flag?

Tonto_
Member #10,690
February 2009

That preprocessor define works. I don;'t exactly even understand the problem but that fixes the linkage with alleg_s. I also wanted to try using alleg_s_crt.lib because vista always complains about like the SxS and the runtime libraries

I tried compiling it with alleg_s_crt first in the list for my linker options in vc++ 2008 but it failed with

11>Linking...
21>Allegro Test 2.obj : error LNK2001: unresolved external symbol __imp__printf
31>Allegro Test 2.obj : error LNK2001: unresolved external symbol __imp__rand
41>Allegro Test 2.obj : error LNK2001: unresolved external symbol __imp__getchar
51>Misc.obj : error LNK2001: unresolved external symbol __imp___errno
61>Misc.obj : error LNK2001: unresolved external symbol _atexit
71>Misc.obj : error LNK2001: unresolved external symbol __imp__srand
81>Misc.obj : error LNK2001: unresolved external symbol __imp___time64
91>LINK : error LNK2001: unresolved external symbol _mainCRTStartup
101>alleg_s_crt.lib(allegro.obj) : error LNK2001: unresolved external symbol @__security_check_cookie@4
111>alleg_s_crt.lib(allegro.obj) : error LNK2001: unresolved external symbol _abort
121>alleg_s_crt.lib(allegro.obj) : error LNK2001: unresolved external symbol _sprintf
131>alleg_s_crt.lib(allegro.obj) : error LNK2001: unresolved external symbol _vsprintf
141>alleg_s_crt.lib(allegro.obj) : error LNK2001: unresolved external symbol _free
151>alleg_s_crt.lib(allegro.obj) : error LNK2001: unresolved external symbol _strlen
16...

Maybe I just need to fiddle with it somemore somehow

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Did you follow the directions in allegro\docs\build\msvc.txt :

Quote:

When using a statically linked library, you must define the preprocessor
symbol ALLEGRO_STATICLINK before including any of the Allegro headers and
link your program against Allegro and the main Win32/DirectX libraries
in that order (see the variable LIBRARIES in makefile.vc). You have also
to make sure that your program is linked against the right C run-time
library, ie. the multi-threaded DLL version of MSVCRT (or the debug
version if you are using the debug library). You can change this option
at Project - Settings - C/C++ - Category: Code Generation - Use run-time
library.

If that doesn't work, you can post your project file for MSVC, and others can verify if your settings are correct. (Not me though, because I don't have MSVC).

What about setting the appropriate link libraries in your project options instead of using #pragma to do it? There is another set of libraries that you have to link against when linking statically to allegro :

-lkernel32 -luser32 -lgdi32 -lcomdlg32 -lole32 -ldinput -lddraw -ldxguid -lwinmm -ldsound

Link to those after linking to allegro.

Tonto_
Member #10,690
February 2009

The settings I tried to use to make it work with allegro_s_crt:

/MT - Multi-threaded run time library as is the allegro_s_crt, different from /MD, used for the msvcrt dll
/NODEFAULTLIB - Ignore the default msvcrt

Additional dependencies: alleg_s_crt.lib dinput.lib ddraw.lib dxguid.lib winmm.lib dsound.lib

Project file here: http://zxcvbn.googlecode.com/svn/trunk/pixelvalentine/Allegro%20Test%202/Allegro%20Test%202.vcproj

Should I be trying to do this at all? I was just annoyed that when I try to share my app the users get SxS errors and have to get the vcredist.

Edit: Also it occured to me, that I am using C++ -- not any C++ libraries but it is compiling as C++, will this mess up the linker symbols and make this whole thing not work?

Milan Mimica
Member #3,877
September 2003
avatar

I find it a good idea to have as much possible linked statically, even the CRT. And no, no need to compile your code as C++ if you use only C, but it will release you from many restrictions that C89 (the newest C that MSVC supports) imposes.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Quote:

Edit: Also it occured to me, that I am using C++ -- not any C++ libraries but it is compiling as C++, will this mess up the linker symbols and make this whole thing not work?

If you're compiling C code to be linked with C++ code, then you should wrap the C function declarations in extern "C" {/*....*/} to have those functions use C linkage. However if you're just compiling it as C++ instead then you shouldn't have any problems aside from making any necessary conversions to C++.

Quote:

Additional dependencies: alleg_s_crt.lib dinput.lib ddraw.lib dxguid.lib winmm.lib dsound.lib

You're missing several libraries from the list in my last post - allegro needs to be linked to those, and that's why there are undefined reference errors. Specifically, you missed these between linking to allegro and the rest of the libraries :

-lkernel32 -luser32 -lgdi32 -lcomdlg32 -lole32

So it seems you need to add kernel32.lib, user32.lib, gdi32.lib, comdlg32.lib, and ole32.lib to your additional dependencies.

Tonto_
Member #10,690
February 2009

I did a dumpbin on allegro_s_crt.lib and I couldn't find any normal crt functions, but a couple did say like al_srand or al_blah. Does this mean I use the al_* function calls to use the static allegro crt? This is what the dumpbin looks like if anyone is curious:

http://zxcvbn.t35.com/out.txt

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Quote:

Does this mean I use the al_* function calls to use the static allegro crt?

No, just use the normal functions allegro provides access to. You don't need to use a different set of functions to link to the same library.

Did you add the other dependencies for static linking?

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

Does this mean I use the al_* function calls to use the static allegro crt?

Allegro doesn't provide access to any C runtime symbols. Just its own API.

In addition, static linking means you need to link to allegro's dependencies manually since you can't link things directly to a static lib.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Go to: