Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Works in IDE not from command line

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Works in IDE not from command line
AceBlkwell
Member #13,038
July 2011
avatar

I'm using Allegro 4.4.2 in eclipse on Linux Slackware 14.2

The issue I'm having is in order to static link my program, I'm compiling / linking from the prompt as I can't get eclipse to do it. When I enter...

g++ -Wall -o Dragons allegro.cpp board.cpp keys.cpp main.cpp map.cpp rand.cpp sound.cpp target.cpp title.cpp `allegro-config --static --libs`

I get an error.
main.cpp:(.text+0x158): undefined reference to `gameplay(BITMAP**, bchar*, char (*) [15], char (*) [15], int, DATAFILE*)' collect2: error: ld returned 1 exit status

At first I thought it was my definition (or declaration, I get the two confused in terminology) before main. So I commented out the actual call to the function within main. It compiled and linked fine. Obviously the program didn't work right but the executable worked on it's own. Now I believe it's with the call. I'm guessing g++ isn't considering the definition and call as the same function. So I'm including both the definition and call, along with declaring of the variables that go with it. Maybe someone can see something I'm not. Again, keep in mind it compiles (dynamically) fine in eclipse and I was able to static link in Windows 10 from
DevCpp with no change to the code itself. Don't get bogged down with the actual working of the code below. I weeded out the stuff that had nothing to do with the function call or it's definition.

Thanks in advance to looking this over.

void gameplay(BITMAP *[],bchar [] ,char[][15], char[][15],int,DATAFILE *);

int main(int argc, char *argv[]) {
/************Setup / Configurations ***********/
bchar token[4]; // Array for board pieces
BITMAP *GameBitmaps[3]; //BITMAPs for Game graphics
DATAFILE *GameDat = NULL; // DAT file with all screen - Fonts - Sounds
char board[15][15]; // Playing Board
char walls[15][15]; // Allows walls to stay hidden until ran into
int sound_clip = 69; // Random Number Init

GameDat = load_datafile("Dragons.dat"); // Load Data file and create bitmaps
GameBitmaps[BUFFER]= create_bitmap(640,480);
GameBitmaps[BUF_HOLD]= create_bitmap(640,480);
GameBitmaps[2]= create_bitmap(640,480);

/*********** Start Program ****************/
while(resp != KEY_Q){
if (resp == KEY_P){ // Game Play Start
gameplay(GameBitmaps,token,board,walls,sound_clip,GameDat);
} // End Gameplay IF

} // While Quit loop

return EXIT_SUCCESS;

} // End of main();

END_OF_MAIN();

Edgar Reynaldo
Member #8,592
May 2007
avatar

I think that the only reason you would get an undefined reference is if you forgot to compile and link the file with the function definition in it, or if the function prototype declaration is wrong.

AceBlkwell
Member #13,038
July 2011
avatar

Thanks Edgar. The issue was I hadn't included the gameplay function file, play.cc, in the command line. Adding play.cpp to the command line, solved my compiling/linking issue. It didn't however make my program Static. I've tried it on a second machine without Allegro installed. It won't run. I get unable to execute bin error. I was afraid of this when the file was only 66K bites. In Windows the static program was between 15-20meg.

In any case, this issue was solved. I'll mark it accordingly

If anyone has any ideas on why my command line text wouldn't yield a static file, I'd love to hear it.

Thanks

Apparently you can't mark as SOLVED. Oh well.

bamccaig
Member #7,536
July 2006
avatar

You might get a hint if you check the output to the command:

allegro-config --static --libs

That'll tell you what it's actually trying to link to. I don't have much experience with static linking something with Allegro so nothing stands out to me as the culprit..

Append:

Try adding -static to the g++ options. allegro-config is outputting all of the dependency libraries, but I think by default you'll be dynamically linked to them. The GCC option should tell GCC to statically link wherever possible.

AceBlkwell
Member #13,038
July 2011
avatar

Bam, thanks. I’ll try tonight and update you. Meanwhile can you tell me how to get the output of the allegro-config?

bamccaig
Member #7,536
July 2006
avatar

AceBlkwell
Member #13,038
July 2011
avatar

Thx. Do you mean just the allegro config command? Or the actual program?

Edgar Reynaldo
Member #8,592
May 2007
avatar

AceBlkwell
Member #13,038
July 2011
avatar

I've added the -static command to the command line. It did give me an error. Looks like needed files are missing.

I tried just the allegro-config command alone but didn't see an option for output.

Here is the response I got from the entire command line entry. Are these normal files seen with allegro. I know lalleg is but not sure about the rest.

#SelectExpand
1bash-4.3# g++ -Wall -static -o Dragons allegro.cpp board.cpp keys.cpp main.cpp map.cpp rand.cpp sound.cpp target.cpp title.cpp play.cpp `allegro-config --static --libs` > test.txt 2rand.cpp: In function 'int random_no(int)': 3rand.cpp:18:21: warning: unused variable 'tv' [-Wunused-variable] 4 struct timeval tv; 5 ^ 6rand.cpp:19:16: warning: unused variable 'number' [-Wunused-variable] 7 unsigned int number,modnumber; 8 ^ 9title.cpp: In function 'void instruct(BITMAP**, DATAFILE*)': 10title.cpp:60:9: warning: unused variable 'test' [-Wunused-variable] 11 int test = 0; 12 ^ 13play.cpp: In function 'void gameplay(BITMAP**, bchar*, char (*)[15], char (*)[15], int, DATAFILE*)': 14play.cpp:57:41: warning: comparison of constant '-1' with boolean expression is always false [-Wbool-compare] 15 if(contact == 'S'&& Treasure_Captured == TRUE) 16 ^ 17/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lalleg 18/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lSM 19/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lICE 20/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lX11 21/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lXext 22/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lXext 23/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lXcursor 24/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lXcursor 25/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lXpm 26/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lXxf86vm 27/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lasound 28/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lXxf86dga 29/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lSM 30/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lICE 31/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lX11 32/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../x86_64-slackware-linux/bin/ld: cannot find -lXext 33collect2: error: ld returned 1 exit status

Thanks

bamccaig
Member #7,536
July 2006
avatar

If you execute the allegro-config command by itself it should output something automatically (that's its entire purpose in life). For example:

bambams@sephiroth:~$ allegro-config --libs --static
-L/usr/lib/x86_64-linux-gnu -lalleg -lm -lpthread -lrt -lSM -lICE -lX11 -lXext -lXext -lXcursor -lXcursor -lXpm -lXxf86vm -lasound -lXxf86dga -lSM -lICE -lX11 -lXext -ldl

Edgar Reynaldo
Member #8,592
May 2007
avatar

It looks like you're missing X11 development libraries, and you haven't set the proper include directory for allegro.

Look here for the list of packages you need to install :

https://wiki.allegro.cc/index.php?title=Build/X11

This

allegro_config --static --cflags

will give you the include directory for allegro where it was installed.

AceBlkwell
Member #13,038
July 2011
avatar

Thanks. The allegro-config set up with -cflags option gave me pretty much what you shown Bam.

Edgar I’ll get this downloaded, thanks. Did have a question though. If I run g++. for a console game before activating KDE, why would I need X11 libs. That would imply I can’t run outside of KDE or Gnome? Which isn’t that big of deal given most ppl use one or the other. Or is it the static aspect. The compiling and linking is getting all items needed to cover all contingencies?

Edgar Reynaldo
Member #8,592
May 2007
avatar

X11 is just the default linux driver - there is a linux console driver too

EDIT

You're going to need to call allegro-config twice in the same command line. Once with --cflags --static to get the include directories. These go before your source files. Then you need allegro config with --libs --static and -static in front of it.

g++ -Wall -O2 -o game.exe `allegro_config --static --cflags` *.cpp -static `allegro_config --static --libs`

bamccaig
Member #7,536
July 2006
avatar

Allegro creates windows so it needs X11 for that at the very least. I suspect that it also gets its input through X11, but I'm not certain. I'm not sure if a fullscreen program would work from a virtual console (i.e., without X11 environment variables defined), but I would think not. That said, the user shouldn't need any particular desktop environment installed or running. Raw X11 is probably sufficient for Allegro's needs (but then you won't be able to manage the session as easily). But as you said, most people that are going to be running your game are already going to expect that and have that.

AceBlkwell
Member #13,038
July 2011
avatar

Thanks for the info guys. Still running in to roadblocks.
I've downloaded the 64 versions of the files Edgar recommended. On a side note I hope that doesn't mean my program will only run on 64bit computers. But either way, I've been able to search and find most of the files in the //usr/lib64 directory. The files the linker says it can't find. I assumed a had a g++ default directory issue. So I've added the -L//usr/lib64 directory to the command line. I'm not sure I have the position in the string correct nor the syntax but I don't get an error, the linker just doesn't see the files. Any suggestions, or can you see an issue with my command line verbiage?

bash-4.3# g++ -Wall -O2 -L//usr/lib64 -o Dragons `allegro-config --static --cflags` allegro.cpp board.cpp keys.cpp main.cpp map.cpp rand.cpp sound.cpp target.cpp title.cpp play.cpp -static `allegro-config --static --libs`

LennyLen
Member #5,313
December 2004
avatar

On a side note I hope that doesn't mean my program will only run on 64bit computers.

It does.

AceBlkwell
Member #13,038
July 2011
avatar

Thanks Lenny. I figured as much. Once I get the command line correct, I'll download and install the 32 bit version. Though I don't imagine there are very many 32s left 8-).

I've also learn something. Should I be using pkg-config instead of allegro-config

wiki says to use pkg-config for v4.4:
https://wiki.allegro.cc/index.php?title=Compiling_Allegro_Programs#Allegro_4.4.x

bamccaig
Member #7,536
July 2006
avatar

Interesting catch. If you're using 4.4 then I think you should be using pkg-config. I think 4.4 was pretty much after 5.x came out and so most of us are used to <=4.2.. Give pkg-config a try and see if that gives you better results. You should be able to test it directly just as you did with allegro-config and compare the output. You can also substitute it into the g++ command to see if it works for you or not.

That said, I haven't figured out what platform you're on yet. I don't think that pkg-config is generally supported on Windows. I know that I've seen it installed by a Perl distribution, but I wouldn't expect it in a typical MinGW install (unless something has changed; perhaps MSYS2 does it though?). Just so we're all clear it would probably be helpful if you told us which version of which operating system you're running, and which version of toolchain and dev environment, etc.. Whatever you can tell us about your setup will help us give better advice.

AceBlkwell
Member #13,038
July 2011
avatar

Thanks Bam. I've already swapped pkg for allegro but just name only. It gave me errors. I think there is some prep work that goes in to using it. IE listing needed files or config file or something

BTW I had listed my op at the start but not details of IDE.

- Using Slackware 14.2 (64) and when I run in dynamic mode and actually program I used eclipse neon. G++ 5.3.0. I can get program to run from eclipse and can line compile from G++ if not static. Program will run fine. Just can't port binaries with out Allegro installation.

- Windows 10 (and 7) using DevCpp portable. Not sure of the version of MinGW. I can program, run dynamic and with Edgar's help and a LONG list of needed library files I can static compile from the IDE. the program can port to other machines without needing Allegro installation.

Thanks again

Edgar Reynaldo
Member #8,592
May 2007
avatar

pkg-config is downloaded and installed separately through your package manager. The allegro.pc files are installed by cmake. You need those to tell pkg-config what to output when you call it.

bamccaig
Member #7,536
July 2006
avatar

Also, pkg-config has its default list of directories to search for these *.pc files so depending on your Allegro install you might need to expand them with environment (or command line options). For example, if you install by source then I think Allegro usually wants to install to /usr/local by default, but on some platforms pkg-config might not look in /usr/local/lib/pkgconfig by default. You can export a PKG_CONFIG_PATH environment variable to specify the paths you want it to search. If you do install pkg-config and it can't find Allegro, you can try to locate the *.pc files by doing something like `find / -name '*.pc' 2>/dev/null | less`. This uses the find(1) command to locate all file names in the file system ending in ".pc", ignoring errors, and then pipes it to less so you can read it if there's more than a page full of answers.

AceBlkwell
Member #13,038
July 2011
avatar

Thanks Edgar and Bam

Looks like I have pkg-config installed. 0.29.1. Must be a slackware thing. Per the man page, I have all the *.pc files in one of the four default locations //usr/lib/pkgconfig. I don't see any *allegro*.pc files of any kind. However I do have an allegro.pc file in //usr/lib64/pkgconfig directory.

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib64
includedir=${prefix}/include
version=4.4.2
suffix=

Name: allegro
Description: Allegro game programming library
Version: ${version}
Libs: -L${libdir} -lalleg${suffix}
Libs.private: -lm -lpthread -lrt -lSM -lICE -lX11 -lXext -lXext -lXcursor -lXcursor -lXpm -lXxf86vm -ldl
Cflags: -I${includedir}

As I stated before, the man page doesn't show the /lib64 directory as being a default search area. Should I change that within pkg-config program some how, or just copy the allegro.pc to the location pkg-config does look. I'm concerns the *.pc file is relatie to the files in it's surroundings.
BTW does pkg-config have different versions 32 and 64. Meaning is there something like pkg-config (32) and pkg-config64 (64)?

bamccaig
Member #7,536
July 2006
avatar

I don't think pkg-config would have different versions for 32-bit and 64-bit builds. You could try just adding that path you found to see what output it gets you:

$ export PKG_CONFIG_PATH=/usr/lib64
$ pkg-config --cflags allegro
$ pkg-config --libs allegro
$ unset PKG_CONFIG_PATH # if you don't like the results

AceBlkwell
Member #13,038
July 2011
avatar

Thanks Bam.

This moved the needle some. I still get the same error but now with only one line per. As you can see in my previous posts, I was getting 2-3 lines for Xext and 2 lines for ICE. That sort of thing. Now it’s just a single line for each file. Still the same files as before just less of them. I’ll keep at it. Maybe I can add /usr/lib(32) as well to the path command.

Do you know, does the linker look one time for needed libs or does it look multiple times depending on how many cpp files you are working with?

Thanks again.

bamccaig
Member #7,536
July 2006
avatar

Do you know, does the linker look one time for needed libs or does it look multiple times depending on how many cpp files you are working with?

Linking should occur once I think when producing a shared object AKA SO (Linux), dynamic link library AKA DLL (Windows), or executable. The linking phase has to reoccur at execution if your executable was linked with dynamic libraries (SOs or DLLs) because the referenced code hasn't been copied into your executable and needs to be reloaded from the library.

Instead, when your program is being started up by the program loader it reads information about which dynamic libraries are needed and links them in too (and it is also possible for your program to attempt to load a dynamic library at any point in its execution too I think, but you wouldn't be doing that here). If the errors are occurring when you compile (i.e., g++) then the linker can't find the libraries at linking time. If you get the errors when you try to execute the program instead then the problem is your environment doesn't reference the necessary paths at runtime.

You can expand the paths that are checked automatically with the LD_LIBRARY_PATH environment variable. That'll only help if linking works, but execution fails.

I'm not sure if the errors you're currently getting are still in the OP or what. I recommend when posting about errors is that you always copy/paste the full output because it'll help to make things clear. Also, as you make progress, it's helpful to post the latest command and output because you might be assuming nothing has changed (since your mind will be bored staring at the same thing so long), and another set of eyes might catch something you didn't. It also helps to keep us on the same page so we don't have to make wrong assumptions.

If the errors are still that -lalleg or -lX11 cannot be found, you can try searching your system for the relevant files. -lalleg is referring to either liballeg.a or liballeg.so in Linux. Similarly, -lX11 should be referring to libX11.a or libX11.so. There may optionally be a version number appended after the file extension, such as libX11.so.6 or libX11.so.6.3.0, but usually the versionless files are symlinks to the full version. You can try using find to locate the files you're trying to link to and verify that pkg-config (or allegro-config, whatever you're trying to use) references those paths.

 1   2 


Go to: