|
Cross compiling DOS tool with Allegro 4.2 - multiple definitions during linking |
megatron-uk
Member #17,010
February 2019
|
Hi, I'm writing a cross-platform game browser tool, one of the platforms being DOS, and as such, am using Allegro 4.2 for the graphics handling on that platform (others being SDL for Linux, GEM/VDI for Atari ST, etc). When I'm linking my code using liballeg.a I get loads of multiple definition errors: 1/usr/i586-pc-msdosdjgpp/bin/i586-pc-msdosdjgpp-gcc -Wall -Wno-unused-function -DUSE_LOGGING -DLOGGING -g -o bin/menu_dos.exe src/menu.o src/logging.o src/input.o src/image.o src/qdbmp.o src/gfx.o src/bmp2text.o src/csvlib.o src/gamedata.o -L/usr/i586-pc-msdosdjgpp/i586-pc-msdosdjgpp/lib -lalleg
2
3src/gfx.o:gfx.c:(.text+0x0): multiple definition of `_default_ds'
4src/menu.o:menu.c:(.text+0x90): first defined here
5src/gfx.o:gfx.c:(.text+0x8): multiple definition of `bmp_write_line'
6src/menu.o:menu.c:(.text+0x98): first defined here
7src/gfx.o:gfx.c:(.text+0x18): multiple definition of `bmp_read_line'
8src/menu.o:menu.c:(.text+0xa8): first defined here
9src/gfx.o:gfx.c:(.text+0x28): multiple definition of `bmp_unwrite_line'
10src/menu.o:menu.c:(.text+0xb8): first defined here
11src/gfx.o:gfx.c:(.text+0x38): multiple definition of `is_windowed_mode'
12src/menu.o:menu.c:(.text+0xc8): first defined here
13src/gfx.o:gfx.c:(.text+0x44): multiple definition of `clear_to_color'
14src/menu.o:menu.c:(.text+0xd4): first defined here
15src/gfx.o:gfx.c:(.text+0x54): multiple definition of `bitmap_color_depth'
16src/menu.o:menu.c:(.text+0xe4): first defined here
17src/gfx.o:gfx.c:(.text+0x60): multiple definition of `bitmap_mask_color'
18src/menu.o:menu.c:(.text+0xf0): first defined here
19src/gfx.o:gfx.c:(.text+0x6c): multiple definition of `is_same_bitmap'
20src/menu.o:menu.c:(.text+0xfc): first defined here
21src/gfx.o:gfx.c:(.text+0xa8): multiple definition of `is_linear_bitmap'
22src/menu.o:menu.c:(.text+0x138): first defined here
23src/gfx.o:gfx.c:(.text+0xbc): multiple definition of `is_planar_bitmap'
24src/menu.o:menu.c:(.text+0x14c): first defined here
25src/gfx.o:gfx.c:(.text+0xcc): multiple definition of `is_memory_bitmap'
26src/menu.o:menu.c:(.text+0x15c): first defined here
27src/gfx.o:gfx.c:(.text+0xe0): multiple definition of `is_screen_bitmap'
28src/menu.o:menu.c:(.text+0x170): first defined here
29src/gfx.o:gfx.c:(.text+0x120): multiple definition of `is_video_bitmap'
30src/menu.o:menu.c:(.text+0x1b0): first defined here
31src/gfx.o:gfx.c:(.text+0x12c): multiple definition of `is_system_bitmap'
32src/menu.o:menu.c:(.text+0x1bc): first defined here
33src/gfx.o:gfx.c:(.text+0x13c): multiple definition of `is_sub_bitmap'
34src/menu.o:menu.c:(.text+0x1cc): first defined here
35src/gfx.o:gfx.c:(.text+0x14c): multiple definition of `acquire_bitmap'
36src/menu.o:menu.c:(.text+0x1dc): first defined here
37src/gfx.o:gfx.c:(.text+0x160): multiple definition of `release_bitmap'
38src/menu.o:menu.c:(.text+0x1f0): first defined here
39src/gfx.o:gfx.c:(.text+0x174): multiple definition of `acquire_screen'
40src/menu.o:menu.c:(.text+0x204): first defined here
41src/gfx.o:gfx.c:(.text+0x190): multiple definition of `release_screen'
42src/menu.o:menu.c:(.text+0x220): first defined here
43src/gfx.o:gfx.c:(.text+0x1ac): multiple definition of `is_inside_bitmap'
44src/menu.o:menu.c:(.text+0x23c): first defined here
45src/gfx.o:gfx.c:(.text+0x204): multiple definition of `get_clip_rect'
46src/menu.o:menu.c:(.text+0x294): first defined here
47src/gfx.o:gfx.c:(.text+0x234): multiple definition of `set_clip_state'
48src/menu.o:menu.c:(.text+0x2c4): first defined here
49src/gfx.o:gfx.c:(.text+0x240): multiple definition of `get_clip_state'
50src/menu.o:menu.c:(.text+0x2d0): first defined here
51src/bmp2text.o:bmp2text.c:(.text+0x0): multiple definition of `_default_ds'
52src/menu.o:menu.c:(.text+0x90): first defined here
53src/bmp2text.o:bmp2text.c:(.text+0x8): multiple definition of `bmp_write_line'
54src/menu.o:menu.c:(.text+0x98): first defined here
55src/bmp2text.o:bmp2text.c:(.text+0x18): multiple definition of `bmp_read_line'
56src/menu.o:menu.c:(.text+0xa8): first defined here
57src/bmp2text.o:bmp2text.c:(.text+0x28): multiple definition of `bmp_unwrite_line'
58src/menu.o:menu.c:(.text+0xb8): first defined here
59src/bmp2text.o:bmp2text.c:(.text+0x38): multiple definition of `is_windowed_mode'
60src/menu.o:menu.c:(.text+0xc8): first defined here
61src/bmp2text.o:bmp2text.c:(.text+0x44): multiple definition of `clear_to_color'
62src/menu.o:menu.c:(.text+0xd4): first defined here
63src/bmp2text.o:bmp2text.c:(.text+0x54): multiple definition of `bitmap_color_depth'
64src/menu.o:menu.c:(.text+0xe4): first defined here
65src/bmp2text.o:bmp2text.c:(.text+0x60): multiple definition of `bitmap_mask_color'
66src/menu.o:menu.c:(.text+0xf0): first defined here
67src/bmp2text.o:bmp2text.c:(.text+0x6c): multiple definition of `is_same_bitmap'
68src/menu.o:menu.c:(.text+0xfc): first defined here
69src/bmp2text.o:bmp2text.c:(.text+0xa8): multiple definition of `is_linear_bitmap'
70src/menu.o:menu.c:(.text+0x138): first defined here
71src/bmp2text.o:bmp2text.c:(.text+0xbc): multiple definition of `is_planar_bitmap'
72src/menu.o:menu.c:(.text+0x14c): first defined here
73src/bmp2text.o:bmp2text.c:(.text+0xcc): multiple definition of `is_memory_bitmap'
74src/menu.o:menu.c:(.text+0x15c): first defined here
75src/bmp2text.o:bmp2text.c:(.text+0xe0): multiple definition of `is_screen_bitmap'
76src/menu.o:menu.c:(.text+0x170): first defined here
77src/bmp2text.o:bmp2text.c:(.text+0x120): multiple definition of `is_video_bitmap'
78src/menu.o:menu.c:(.text+0x1b0): first defined here
79src/bmp2text.o:bmp2text.c:(.text+0x12c): multiple definition of `is_system_bitmap'
80src/menu.o:menu.c:(.text+0x1bc): first defined here
81src/bmp2text.o:bmp2text.c:(.text+0x13c): multiple definition of `is_sub_bitmap'
82src/menu.o:menu.c:(.text+0x1cc): first defined here
83src/bmp2text.o:bmp2text.c:(.text+0x14c): multiple definition of `acquire_bitmap'
84src/menu.o:menu.c:(.text+0x1dc): first defined here
85src/bmp2text.o:bmp2text.c:(.text+0x160): multiple definition of `release_bitmap'
86src/menu.o:menu.c:(.text+0x1f0): first defined here
87src/bmp2text.o:bmp2text.c:(.text+0x174): multiple definition of `acquire_screen'
88src/menu.o:menu.c:(.text+0x204): first defined here
89src/bmp2text.o:bmp2text.c:(.text+0x190): multiple definition of `release_screen'
90src/menu.o:menu.c:(.text+0x220): first defined here
91src/bmp2text.o:bmp2text.c:(.text+0x1ac): multiple definition of `is_inside_bitmap'
92src/menu.o:menu.c:(.text+0x23c): first defined here
93src/bmp2text.o:bmp2text.c:(.text+0x204): multiple definition of `get_clip_rect'
94src/menu.o:menu.c:(.text+0x294): first defined here
95src/bmp2text.o:bmp2text.c:(.text+0x234): multiple definition of `set_clip_state'
96src/menu.o:menu.c:(.text+0x2c4): first defined here
97src/bmp2text.o:bmp2text.c:(.text+0x240): multiple definition of `get_clip_state'
98src/menu.o:menu.c:(.text+0x2d0): first defined here
99collect2: error: ld returned 1 exit status
100Makefile.common:10: recipe for target 'menu_dos.exe' failed
101make: *** [menu_dos.exe] Error 1
I've got a couple of object files that do a #include <allegro/gfx.h> or #include <allegro/keyboard.h>, but why does this cause multiple definition errors? Anyone else still using Allegro with more modern compilers for DOS? I've tried both GCC 5.5.0 and 7.2.0 as per (https://github.com/andrewwutw/build-djgpp/releases), but there's no difference in behaviour. Allegro 4.2.2 is built for DOS from (https://github.com/msikma/allegro-4.2.2-xc). It's years and years since I did any dabbling with Allegro - is the intention to only include any allegro headers only once, and in one place? John
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Try defining ALLEGRO_STATICLINK before including allegro 4 or link to the dynamic library and see if it goes away. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
megatron-uk
Member #17,010
February 2019
|
Thanks for the suggestion, unfortunately it doesn't appear to make any difference; both passing -DALLEGRO_STATICLINK to GCC, and also setting it manually around the include blocks for allegro.h: #ifdef USE_ALLEGRO 1/usr/i586-pc-msdosdjgpp/bin/i586-pc-msdosdjgpp-gcc -Wall -Wno-unused-function -Wno-unused-variable -march=i386 -mtune=i386 -mfpmath=387 -O3 -I/usr/i586-pc-msdosdjgpp/i586-pc-msdosdjgpp/sys-include -DALLEGRO_STATICLINK -DUSE_ALLEGRO -DPOSIX -DDIR_SEP=\"\" -DGAMEDIR=\"C:\GAMES\" -DCSV_FILE=\"MENU.CSV\" -DALLEGRO_NO_COMPATIBILITY -DSTATICLINK=1 -DUSE_LOGGING -DLOGGING -c -o src/image.o src/image.c
2...
3[more objects compiling here]
4...
5/usr/i586-pc-msdosdjgpp/bin/i586-pc-msdosdjgpp-gcc -Wall -Wno-unused-function -Wno-unused-variable -march=i386 -mtune=i386 -mfpmath=387 -O3 -I/usr/i586-pc-msdosdjgpp/i586-pc-msdosdjgpp/sys-include -DALLEGRO_STATICLINK -DUSE_ALLEGRO -DPOSIX -DDIR_SEP=\"\" -DGAMEDIR=\"C:\GAMES\" -DCSV_FILE=\"MENU.CSV\" -DALLEGRO_NO_COMPATIBILITY -DSTATICLINK=1 -DUSE_LOGGING -DLOGGING -c -o src/gamedata.o src/gamedata.c
6src/gamedata.c: In function 'comparegames':
7src/gamedata.c:254:6: warning: implicit declaration of function 'toupper' [-Wimplicit-function-declaration]
8 c = toupper(game_a->name[0]);
9 ^
10
11Linking....
12/usr/i586-pc-msdosdjgpp/bin/i586-pc-msdosdjgpp-gcc -Wall -Wno-unused-function -DUSE_LOGGING -DLOGGING -g -o bin/menu_dos.exe src/menu.o src/logging.o src/input.o src/image.o src/qdbmp.o src/gfx.o src/bmp2text.o src/csvlib.o src/gamedata.o -L/usr/i586-pc-msdosdjgpp/i586-pc-msdosdjgpp/lib -lalleg
13src/input.o:input.c:(.text+0x0): multiple definition of `install_allegro'
14src/menu.o:menu.c:(.text+0x2d8): first defined here
15src/input.o:input.c:(.text+0x20): multiple definition of `set_window_title'
16src/menu.o:menu.c:(.text+0x2f8): first defined here
17src/input.o:input.c:(.text+0x34): multiple definition of `desktop_color_depth'
18src/menu.o:menu.c:(.text+0x30c): first defined here
19src/input.o:input.c:(.text+0x48): multiple definition of `get_desktop_resolution'
20...
21...
No joy. I think the problem stems from having code in those allegro 4 header files, both in the inline headers in allegro/inline/*, but also in things like allegro/system.h (e.g. install_allegro is a function rather than just a prototype). This makes me think I can't really use any part of Allegro unless it's in one, singular object file, am I right?
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
No, thankfully that's not how allegro works. This is besides the point but you need to include the header for toupper, otherwise that function links to nothing. #include <ctype.h> C will bite you like that. When compiling statically, you also need to link to the following libraries : -lkernel32 -static-libstdc++ But that won't get rid of the redefinition errors. First, STATICLINK=1 is a flag passed to make when building allegro. If you're linking to liballeg.a, that is the dynamic allegro library, the static one would be liballeg_s.a, which you would link to with -lalleg_s. Since you're not doing that, don't define ALLEGRO_STATICLINK either. The problem is something else. I'm trying to think what it is. You might want to spend some time reading docs\build\mingw32.txt for some steps of the build process. They apply to DOS as well. You can get a .chm doc for 4.2.2 here : Those are the latest docs for the 4.2.2 build process, which was abandoned in favor of cmake for Allegro 4.4 and also when DOS support was dropped. But you probably know that, so... EDIT My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
megatron-uk
Member #17,010
February 2019
|
Thanks for the tips, however, unless I'm completely mistaken when building the DOS target for liballegro the only option is a static library (unless I've missed something); DOS doesn't have a dynamic loader like Unix or Windows, so a .a file is the only thing you can create that makes any sense. Certainly the .a file I've got is a plain old ar archive, not a shared library. In terms of link options for my code, it's a pure DOS allegro library and my cross compiler (i586-pc-msdosdjgpp) targets pure DOS as well (via either 5.5.0 or 7.2.0 djgpp version of GCC), it's not wingw32 or anything like that, so there's no linking with Windows dll's, for now that's just libc.a and liballeg.a: 1/usr/i586-pc-msdosdjgpp/i586-pc-msdosdjgpp/lib $ ls -l
2total 7564
3-rw-r--r-- 1 megatron users 4516 Oct 18 2015 crt0.o
4-rw-r--r-- 1 megatron users 2720 May 11 2015 djgpp.djl
5-rw-r--r-- 1 megatron users 628 Aug 23 2017 dxe.ld
6-rw-r--r-- 1 megatron users 4558 Oct 18 2015 gcrt0.o
7drwxr-xr-x 2 megatron users 4096 Aug 23 2017 ldscripts
8-rw-r--r-- 1 megatron users 3230830 Sep 7 2007 liballd.a
9-rw-r--r-- 1 megatron users 1530832 Sep 7 2007 liballeg.a
10-rw-r--r-- 1 megatron users 1588764 Sep 7 2007 liballp.a
11-rw-r--r-- 1 megatron users 999320 Oct 18 2015 libc.a
12-rw-r--r-- 1 megatron users 45298 Oct 18 2015 libdbg.a
13-rw-r--r-- 1 megatron users 58804 Oct 18 2015 libemu.a
14-rw-r--r-- 1 megatron users 482 Oct 18 2015 libg.a
15-rw-r--r-- 1 megatron users 245346 Oct 18 2015 libm.a
16-rw-r--r-- 1 megatron users 482 Oct 18 2015 libpc.a
1megatron@thinky:/usr/i586-pc-msdosdjgpp/i586-pc-msdosdjgpp/lib $ file liballeg.a
2liballeg.a: current ar archive
3
4megatron@thinky:/usr/i586-pc-msdosdjgpp/i586-pc-msdosdjgpp/lib $ ar t liballeg.a | head -n 10
5allegro.o
6blit.o
7bmp.o
8clip3d.o
9clip3df.o
10colblend.o
11color.o
12config.o
13datafile.o
14dataregi.o
15...
16...
I must be missing something obvious here - I'm going to go right back to the version of GCC that Allegro was bundled with back in the days of DOS; I think it hung around v2.95 number for a very long time. Maybe something has broken with the modern binutils stuff? --- Edit: Your link to that old post was a good one - although changing the C dialect looked at first to be disastrous (adding -std=c89 basically caused everything else to error out - I have examples of the later dynamic malloc calls, c++ style commenting, etc. etc.), it helped greatly in tracking down the actual cause; the inline functions in the headers. One of the original commenters mentioned about a change in extern inline handling in c99, and sure enough, it's detailed here: https://gcc.gnu.org/onlinedocs/gcc/Inline.html The short version is that if compiling against Allegro 4.x on something more modern than GCC 2.x (which, if you're doing any DOS work these days, you'd be nuts for using so old a version of GCC), you need to pass the option -fgnu89-inline. Otherwise, it will never work due to the inline functions in the headers. I don't know how well this plays with other libraries, so your mileage may vary in that regard. Here's the output: ... /usr/i586-pc-msdosdjgpp/bin/i586-pc-msdosdjgpp-gcc -Wall -Wno-unused-function -Wno-unused-variable -march=i386 -mtune=i386 -mfpmath=387 -fgnu89-inline -O3 -I/usr/i586-pc-msdosdjgpp/i586-pc-msdosdjgpp/sys-include -DDOS -DALLEGRO_STATICLINK -DUSE_ALLEGRO -DDIR_SEP=\"\" -DGAMEDIR=\"C:\GAMES\" -DCSV_FILE=\"MENU.CSV\" -DALLEGRO_NO_COMPATIBILITY -DSTATICLINK=1 -DUSE_LOGGING -DLOGGING -c -o src/gamedata.o src/gamedata.c ... Linking.... /usr/i586-pc-msdosdjgpp/bin/i586-pc-msdosdjgpp-gcc -Wall -Wno-unused-function -DUSE_LOGGING -DLOGGING -g -o bin/menu_dos.exe src/menu.o src/logging.o src/input.o src/image.o src/qdbmp.o src/gfx.o src/bmp2text.o src/csvlib.o src/gamedata.o -L/usr/i586-pc-msdosdjgpp/i586-pc-msdosdjgpp/lib -lalleg $ ls -l bin/menu_dos.exe -rwxr-xr-x 1 megatron users 433952 Feb 18 20:13 menu_dos.exe $ file bin/menu_dos.exe bin/menu_dos.exe: MS-DOS executable, COFF for MS-DOS, DJGPP go32 DOS extender
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
I'm sorry, that was really more mingw advice, which I guess doesn't apply to DOS. I never really actually compiled anything for DOS, except for my very first programs with allegro. Glad you figured it out though. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|