llvm-link with external libraries - llvm

I'm now playing with LLVM and it's JIT. I'm pretty interested in the JIT and then I wrote a small GTK+ hello world:
#include <gtk/gtk.h>
int main ()
{
gtk_init(NULL, NULL);
GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (win, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
GtkWidget *lbl = gtk_label_new ("hello world");
gtk_container_add (GTK_CONTAINER (win), lbl);
gtk_widget_show_all (win);
gtk_main();
return 0;
}
I compiled it into Bitcode this way:
clang -emit-llvm -S a.c `pkg-config --cflags gtk+-3.0`
llvm-link a.s -o a.o
But when I run it
> lli a.o
LLVM ERROR: Program used external function 'gtk_init' which could not be resolved!
I tried to find out how to add an external library when linking, but I found nothing. Is there a way to let it run?

llvm-link is a not a "usual" linker. It's used to merge several IR files. So, in your case a.o is just a binary LLVM IR and everything worked because llvm-link automagically parsed textual LLVM IR.
You cannot "link in" the native libraries. Though, you can load them into lli process (e.g. via LD_PRELOAD) and symbols are supposed to be resolved.

Related

SDL mingw static lib linking errors

I'm trying to compile a simple SDL program using Mingw w64. Here is my code:
test.c
#include "SDL2/SDL.h"
#include <stdio.h>
int main( int argc, char* args[] )
{
SDL_Window *window;
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("SDL2 Window", 100, 100, 640, 480, 0);
if(window==NULL)
{
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
SDL_Delay(3000);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
and here is the command I'm using to compile the program:
g++ -o text.exe test.c -I./include -L./lib -lmingw32 -lSDL2main -lSDL2
but when I compile the program, I get hundreds of linking errors that look like this:
./lib/libSDL2.a(SDL_wasapi_win32.o): In function `WASAPI_PlatformInit':
/Users/valve/release/SDL/SDL2-2.0.22-source/foo-x64/../src/audio/wasapi/SDL_wasapi_win32.c:255: undefined reference to `__imp_CoCreateInstance'
I downloaded the library from the second link down in the windows development libraries section on the official SDL website, and took the libraries from the following directory:
SDL2-2.0.22\x86_64-w64-mingw32\lib
The contents of ./lib are:
libSDL2main.a
libSDL.a
What is the problem and how can I fix it?
You have two options, depending on your intent:
If you want to link SDL2 dynamically (this should be your default course of action), you need to add libSDL2.dll.a to your library directory. Then libSDL2.a will be ignored and can be removed. It should just work, no other changes are needed.
If you want to statically link SDL2, you need more linker flags. The exact flags are listed in sdl2.pc in the Libs.private section.
As of SDL 2.0.22, those are: -Wl,--dynamicbase -Wl,--nxcompat -Wl,--high-entropy-va -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid.
Those should be added to the right of -lmingw32 -lSDL2main -lSDL2.
You also might want to add -static to statically link everything, including the standard library. (What's the point of statically linking SDL2, when your program still needs the DLLs of the standard library to work?) It also makes the linker prefer libSDL2.a to libSDL2.dll.a if both are available, meaning you don't need to worry what's in your library directory.

Compiling Allegro 5 Program through command line on a Mac

I followed to steps to build and install Allegro 5 from their wiki (found here: https://wiki.allegro.cc/index.php?title=Main_Page) and seemingly succeeded with no problems.
allegro was installed to the following (as the wiki suggests) /usr/local/include and usr/local/lib and I have confirmed allegro is there.
I then wrote the following code in vim:
#include <stdio.h>
#include <allegro5/allegro.h>
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display = NULL;
if(!al_init())
{
fprintf(stderr, "failed to initialize allegro!\n");
return -1;
}
display = al_create_display(640, 480);
if(!display)
{
fprintf(stderr, "failed to create display!\n");
return -1;
}
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
al_rest(10.0);
al_destroy_display(display);
return 0;
}
I am new to using Unix and have only ever compiled c++ programs with g++ that were simple hello world files with no libraries needed.
Therefore after searching around on the internet I tried the following commands:
g++ hello.cpp -o hello `pkg-config --libs allegro-5`
resulting in the following:
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
(maybe you meant: __al_mangled_main)
ld: symbols not found for architecture x86_64
clang: error: linker command failed with exit code 1
BTW, I used homebrew to install dependencies instead of macports
brew install pkg-config
brew install zlib
etc...
It seems like a linking problem.
What am I doing wrong?
try install allegro with homebrew and use gcc -o main main.c -lallegro -lallegro_main
because the allegro_main is a compatibility library that allows the main function to work on all compilers. Required only from OS X.

SDL library in linux

I'm trying to compile this code:
#include "SDL/SDL.h"
int main(void) {
SDL_Surface *Hello = NULL;
SDL_Surface *Screen = NULL;
SDL_Init( SDL_INIT_EVERYTHING );
return 0;
}
But it happens that the compiler says that:
undefined reference to SDL_Init
I dont know why this is happening. I'm using Debian Mint and Code::Blocks. Could you Help me?
It looks like you haven't got -lSDL on your link line.
sdl-config returns the compile and link flags for your installation of SDL.
Assuming the program is sdl.cpp
g++ -o sdl `sdl-config --cflags` sdl.cpp `sdl-config --libs`
Should give you the correct flags.
Go to project and then build options and select your project name.
Now go to the linker setting and type the following lines in the Other Linker options textbox:
-lSDLmain
-lSDL
SDL also requires command line arguments in the main function so you should change
int main(void)
to
int main(int argc, char **argv)
Now compile your project and it should work.

Compiling C++ code with allegro 5 and g++

What flags do I need to add to g++ in order to compile code using allegro 5? I tried
g++ allegro5test.cpp -o allegro5test `allegro-config --libs`
but that is not working. I'm using ubuntu 11.04. I installed allegro 5 using the instructions at http://wiki.allegro.cc/index.php?title=Install_Allegro5_From_SVN/Linux/Debian
I tried:
g++ allegro5test.cpp -o allegro5test `allegro-config --cflags --libs`
And it also gives a bunch of undefined errors, like: undefined reference to `al_install_system'
allegro-config --cflags --libs outputs:
-I/usr/local/include
-L/usr/local/lib -lalleg
So you successfully installed allegro5 on your system from the SVN. One thing you should know is that this build doesn't come with allegro-config. If you have it on your system it means you have previously installed allegro4.
allegro5 brings many changes, including different initialization procedures, library and function names.
Here's a hello world application for new version:
#include <stdio.h>
#include <allegro5/allegro.h>
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display = NULL;
if(!al_init()) {
fprintf(stderr, "failed to initialize allegro!\n");
return -1;
}
display = al_create_display(640, 480);
if(!display) {
fprintf(stderr, "failed to create display!\n");
return -1;
}
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
al_rest(10.0);
al_destroy_display(display);
return 0;
}
Notice how the command to compile this application refers to another include directory and library names, which are different from the previous version of allegro:
g++ hello.cpp -o hello -I/usr/include/allegro5 -L/usr/lib -lallegro
Allegro 5 uses pkg-config.
pkg-config --libs allegro-5.0 allegro_image-5.0
And so on for each library you are using.

Compiling C++ using -pthreads for Openwrt Linux-Get segmentation fault

I´m pretty new to programming in C++ and I´m using pthreads. I´m cross compiling my code for OpenWRT but for some reason I get segmentation fault when I run the program on my board but it runs fine on my PC. I suspect that the error occurs in the linking stage of the compilation because I tried a small C program and that worked fine. Also if I change the name of the file to .cpp and compile it with g++ it also works.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void *run(void *dummyPtr) {
printf("I am a thread...\n");
return NULL;
}
int main(int argc, char **argv) {
printf("Main start...\n");
pthread_t connector;
pthread_create(&connector, NULL, run, NULL);
printf("Main end...\n");
return 0;
}
The output from the eclipse compiler:
**** Build of configuration Release for project ThreadTest ****
make all
Building file: ../src/ThreadTest.cpp
Invoking: GCC C++ Compiler
mipsel-linux-g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/ThreadTest.d" -MT"src/ThreadTest.d" -o"src/ThreadTest.o" "../src/ThreadTest.cpp" -lpthread
mipsel-linux-g++: -lpthread: linker input file unused because linking not done
Finished building: ../src/ThreadTest.cpp
Building target: ThreadTest
Invoking: GCC C++ Linker
mipsel-linux-g++ -o"ThreadTest" ./src/ThreadTest.o -lpthread -static
Finished building target: ThreadTest
Edit: Removed the old code and put in a new simpler example. This code runs if I compile it as a C program but no if I compile it as a c++ program. I´m runnig the 2.6.26.3 kernel on the board.
This could easily be due to a low memory condition. You should try to enable some form of page file and free up any other memory.
Also, why -static? if your using a dynamic -lpthread, wouldn't linking the shared library be preferable?
Also, it could be due to your C++ lib being mis-matched, make sure your uclibc++ is the correct version, you may also want to install ldd if you have not already. Depends on your firmware.
It's not sufficient to simple link against pthread with -lpthread. You need gcc -pthread (as an option its own right) or gcc -D_REENTRANT -lpthread (define a symbol named _REENTRANT). I don't know if this necessary affects anything.
I don't know if you found an answer yet or if this was the problem, but there is a race condition in the code you showed. It is possible that main will return and your program will try to exit before your "run" thread has finished running. You can never assume that it will run in any particular order or with any particular timing. You should add a call to pthread_join(connector, NULL); before returning from main.
Before returning from the main and thus exiting the program, you should be doing a
pthread_join(connector, NULL);
which avoids exiting your application before the thread has terminated.
A correct declaration of main() is
int main(int argc, char **argv)
Edited to correct this answer:
This is because your compile -c line for your .c include -lpthread: linker input file unused
I found this answer about compiling c++ programs on openwrt:
http://manoftoday.wordpress.com/2007/10/11/writing-and-compiling-a-simple-program-for-openwrt/
I think you'll also want to read this to get gdb working:
http://forum.openwrt.org/viewtopic.php?pid=29712