failure to compile imgui, glfw, opengl on linux with gcc 11.2 - c++

I've recently started coding with c++ and the project that im currently on requires imgui. so i set up the .h and .cpp libraries in a folder called "include" in the same folder as the source code. I'm currently trying to run the cpp in https://github.com/ocornut/imgui/tree/master/examples/example_glfw_opengl3 and compile it with gcc using gcc imgui.cpp -lstdc++ -lglfw -lGL -limgui but i just get
/usr/bin/ld: cannot find -limgui
collect2: error: ld returned 1 exit status
yes i know there is a make file in the link but im using the file in another folder.

Assuming you downloaded imgui to a place called $IMGUI_DIR and the file that contains your main function is main.cpp, your compile commandline should look like the following: (the \ are just there to break up the command)
g++ main.cpp -o main \
$IMGUI_DIR/imgui*.cpp $IMGUI_DIR/backends/imgui_impl_glfw.cpp $IMGUI_DIR/backends/imgui_impl_opengl3.cpp \
-I $IMGUI_DIR -I $IMGUI_DIR/backends \
-lglfw -lGL
In order, you tell the compiler:
Where your code is and where to put the output
What Imgui code to include, namely the core library and the two backends you want to use
Where Imgui code should look for its headers
If all this sounds like a lot, know that you can simply build the example you linked and override IMGUI_DIR at compile time with make IMGUI_DIR=/path/to/imgui

Related

Compiling an external library on Linux

Good Day Everyone,
N.B - This problem has been solved - I have provided my own solution in the answer section however the solution provided by Jonathan is much shorter. Nevertheless, this was the following question I originally posted:
I am basically trying to compile a serial library (for UART communication) on Linux however I am not really sure how to correctly compile (I have mentioned what I have done so far below), any suggestions would be highly valuable. I am using the serialib library - which is composed of 2 main files (serialib.h and serialib.cpp) , you may directly view the source code of these files here (scroll all the way to the bottom and view the files in new tabs): http://serialib.free.fr/html/classserialib.html
I transferred these files (serialib.h and serialib.cpp) to my BeagleBone Black micro-controller which is running Debian (Wheezy) , g++/gcc (Debian 4.6.3-14) 4.6.3. I wrote my own program (uart.cpp is my file name) to access the functions provided by this library, this is what I wrote:
#include <iostream>
#include "serialib.h"
#ifdef __linux__
#define DEVICE_PORT "/dev/ttyO1"
#endif
int main()
{
serialib LS;
return 0;
}
So as you can see I am trying to access the 'seriallib' class. serialib.h, serialib.cpp and uart.cpp are all in the home directory. I also manually added the iostream library in serialib.cpp as I did not see it being declared in the original source code.
Now I am really unsure of how to compile such external libraries but so far I tried the following steps:
g++ -c -Wall -Werror -fPIC serialib.c to convert to PIC which gives the following error:
distcc[3142] (dcc_parse_hosts) Warning: /home/debian/.distcc/zeroconf/hosts contained no hosts; can't distribute work
distcc[3142] (dcc_zeroconf_add_hosts) CRITICAL! failed to parse host file.
distcc[3142] (dcc_build_somewhere) Warning: failed to distribute, running locally instead
g++ serialib.cpp -L /home/debian/serialib.h which gives the following error:
/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../arm-linux-gnueabihf/crt1.o: In function _start':
(.text+0x30): undefined reference tomain'
collect2: ld returned 1 exit status
distcc[3210] ERROR: compile serialib.cpp on localhost failed
As of now I am still finding out how to compile this and if I manage to work this out then I'll post my solution here too. Once again any suggestion will be highly valuable. Thank you all :) .
g++ -c -Wall -Werror -fPIC serialib.c to convert to PIC which gives the following error:
The "error" is not an error, it's a warning, telling you that your distcc setup is broken, but that it compiled locally.
That command doesn't "convert to PIC", it compiles the file serialib.c and produces a compiled object file, serialib.o
g++ serialib.cpp -L /home/debian/serialib.h
This is just nonsense. It tries to build a program from serialib.cpp and use the directory /home/debian/serialib.h (which isn't a directory!) to find libraries.
You don't need to "compile a library" you can just compile both the source files and link them together into a program. Either:
g++ -c serialib.cpp
g++ -c uart.cpp
g++ serialib.o uart.o -o uart
Or all in one command:
g++ serialib.cpp uart.cpp -o uart
You should read An Introduction to GCC to understand the commands, not just enter bogus commands without understanding them.
I have found a solution to this problem, hope this helps for all the future readers with similar problems. I have my own source code uart.cpp (Given in the question) which I want to compile, the external library is serialib that contains two main files (serialib.h and serialib.cpp), you will want to replace the following commands with respect to the files you have
Step 1: Compiling with position independent code
g++ -c -Wall -Werror -fpic serialib.cpp
Step 2: Creating a shared library
g++ -shared -o libserialib.so serialib.o , here the library is libserialib.so.
Step 3: Linking your source code with library
g++ -L /home/debian -lserialib uart.cpp -o uart
g++ -L /home/debian -Wall -o test uart.cpp -lserialib
You may save the library at a different path and you may have a different name of course. Suppose you have a library called libabc.so at the directory /home/user/myDir then the commands will be like:
g++ -L /home/user/myDir -labc your_code.cpp -o your_code
g++ -L /home/user/myDir -Wall -o test your_code.cpp -labc
test is out own program, lserialib is actually looking for libserialib.so and not serialib.o as gcc/g++ assumes all libraries start with lib and end with .so or .a and you can see the same goes for labc as it will look for libabc.so thus it is important to make sure your library name begins with lib and ends with .so or .a
Step 4: Making library available at run time
Here we provide the path where the library is actually stored, I saved it in the directory /home/debian which is why my command looks like:
export LD_LIBRARY_PATH=/home/debian:$LD_LIBRARY_PATH
if your library is saved at /path/to/file then the command will look like:
export LD_LIBRARY_PATH=/path/to/file:$LD_LIBRARY_PATH
This is to help the loader find the shared library and to view this path: echo $LD_LIBRARY_PATH and to unset this: unset LD_LIBRARY_PATH
To execute the program type either ./test or ./uart and in case of any modification to the main source code (uart.cpp in this case) , simply repeat step 3. I found the following link very useful: http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html . Thank you to all of you who took time to read this question and especially those who gave me suggestions. If anyone has more or better solutions, feel free to post them here to assist future readers :).

"multiple definition of `atexit'" when linking with DLL

I use MinGW32 more specifically TDM-GCC-32. I have very simple project I link to one custom library but this error pops out:
>g++ -D_WIN32 -D_MINGW -lgdi32 -lgdiplus -Linterception/x86 -linterception main.cpp -o interceptor.exe
interception/x86/libinterception.a(dgnes00125.o):(.text+0x0): multiple definitio
n of `atexit'
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../crt2.o:crt1.c:(.text+0x2c0):
first defined here
interception/x86/libinterception.a(dgnes00109.o):(.text+0x0): multiple definitio
n of `_onexit'
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../crt2.o:crt1.c:(.text+0x2d0):
first defined here
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../../mingw32/bin/ld.exe: C:/TD
M-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../crt2.o: bad reloc address 0x20 in
section `.eh_frame'
collect2.exe: error: ld returned 1 exit status
Commands I use to build the library:
gcc -DINTERCEPTION_EXPORT -D_WIN32 -D_MINGW -shared -o interception.dll interception.c
dlltool -z interception.def --export-all-symbol interception.dll
dlltool -d interception.def -l libinterception.a
I guess I have to use different options for compiling the library to avoid redefinitions..
The dlltool method I believe is currently deprecated. I can't fault you here though, as most of the available documentation still says to do it this way.
Gcc will link directly against .dll files, making .a files obsolete (at least for dealing with dll's - the only current reason to use a .a file is for static linking). You don't even have to specify the dll with the -l flag, although you have to specify the path of the dll if it's not in your current directory
C:\Users\burito>gcc main.o opengl32.dll -o main.exe
gcc: error: opengl32.dll: No such file or directory
C:\Users\burito>gcc main.o c:\Windows\system32\opengl32.dll -o main.exe
C:\Users\burito>
Ok, opengl32.dll is perhaps not a great example, but I hope I've given you the general idea.
I believe MSVC still needs its .lib files to use a .dll, for which there are several ways of making them if the library doesn't come with one.
In your specific case, the command that should work would be...
g++ -D_WIN32 -D_MINGW -lgdi32 -lgdiplus interception/x86/interception.dll main.cpp -o interceptor.exe
If for whatever reason you really do need to create a .a file from a .dll, the command that has worked for me is...
gendef interception.dll
dlltool -l interception.a -d interception.def -k -A
As the repository you linked does provide .dll files in its releases, you shouldn't have to build them yourself

Cannot find .dll using MinGW and MSYS

OS: Windows 7
I have the source, as well as all the library files I'm using in one directory, on my desktop. I'm running the shell by using msys.bat, which was created when I installed MinGW. I've tried to run the following (and many others):
g++ -I. -L. -o opengltest.exe opengltest.cpp -lglew32 -lglew32s -lglew32.dll
I recieve the following error:
c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/ld.exe: cannot find -lglew32.dll
collect2: ld returned 1 exit status
This also happens when I use the -L switch and the entire C:/Users/... path, but I get the same error. Again, glew32.dll is in the same directory that the .cpp is in, which is the same directory I'm working in within the shell. I've tried multiple solutions from multiple posts, and it still seems like I'm missing something. I thought using the -L. was a straightforward way to tell MinGW to look in the working directory, but apparently it doesn't work that way.
Do not link against both the dynamic and static linking version of glew in the same application. This makes no sense. Also do no link against glew32.dll, this makes equally little sense.
Most importantly, do not use the DLL version of glew with g++ at all - it will not work (see one of my previous answers to understand why). Instead, #define GLEW_STATIC (better if you use -DGLEW_STATIC as a compiler switch) and only link to glew32s.

Linking to ROOT files in xCode

I need to link to the .so files and headers found in /root/lib and /root/include in a project in xcode 3.2.6. ROOT is an analysis framework from CERN.
There is a utility root-config, that will return all the libraries necessary, I can compile on the command line using:
CFLAGS = `root-config --cflags`
GLIBS = `root-config --glibs`
test : main.cpp main.h
g++ $(CFLAGS) $(GLIBS) -g -Wall main.cpp -02 -o test
Program runs fine with no bugs. But, I want to use xcode for the whole project, but can't get it to either
A: use this utility
or
B: search the right paths to the .so files. I have included /root/lib and /root/include in the build variables header_search_paths and library_search_paths under the build settings. I then actually type in the files I need into the other_linker_flags like so:
-llibTree -llibHist -llibRIO -llibCint -llibCore
xcode returns the message:
ld: library not found for -llibTree
collect2: ld returned 1 exit status
Command /Developer/usr/bin/g++-4.2 failed with exit code 1
Does anybody know whats going on? Can xCode compile .so files? Is there some other issue here?
This has nothing to do with ROOT. To link against a library named libSomething.so in your library search path you can use a linker flag -lSomething. You want to link against e.g. libTree.so, so the correct flag to use would be -lTree, not -llibTree which would look for liblibTree.

How do I link libcurl to my c++ program in linux?

I need to use libcurl in a piece of software I am writing on my ubuntu machine. I am using Eclipse to write and compile all of the software. When I put the libcurl files in the same folder as the .cpp file, and include the curl.h file in the header, When I attempt to compile the program, It comes up with these errors:
Building target: sms
Invoking: GCC C++ Linker
g++ -o"sms" ./src/sms.o
./src/sms.o: In function `main':
/home/geekman/workspace/sms/Debug/../src/sms.cpp:38: undefined reference to `curl_easy_init'
/home/geekman/workspace/sms/Debug/../src/sms.cpp:42: undefined reference to `curl_easy_setopt'
/home/geekman/workspace/sms/Debug/../src/sms.cpp:44: undefined reference to `curl_easy_setopt'
/home/geekman/workspace/sms/Debug/../src/sms.cpp:46: undefined reference to `curl_easy_perform'
/home/geekman/workspace/sms/Debug/../src/sms.cpp:47: undefined reference to `curl_easy_cleanup'
collect2: ld returned 1 exit status
make: *** [sms] Error 1
I took the contents of the include folder from libcurl, and placed them in the same folder as the .cpp file. then in the header of the .cpp file, I typed:
#include <curl/curl.h>
I also tried:
#include "curl/curl.h"
Any ideas on the problem? Thanks.
Your header file inclusions are just fine; your problem is occurring at the linking step. In order to link against libcurl, you need to add the -lcurl command line option, assuming it's installed in a standard directory:
g++ -o sms ./src/sms.o -lcurl
If it's not installed in a standard directory, you also need to add the -L/path/to/libcurl, e.g. something like:
# Assuming that /home/geekman/workspace/libcurl is where libcurl.a is located
g++ -o sms ./src/sms.o -L/home/geekman/workspace/libcurl -lcurl
Also note that the -lcurl option has to appear after the list of object files you're linking, otherwise it won't link properly.
You can try to use curl-config --libs.
An alternate answer (the first one is excellent). Consider using the output returned by "pkg-config --libs libcurl" as an argument to your compiler.
For example,
CPPFLAGS=`pkg-config --libs libcurl`
g++ $CPPFLAGS myfile.o
Pkg-config is a standard way for open source libraries to communicate to you how to link against them / #include their files.
Anyone who is using ecplise CDT then you need to do following. First on terminal enter
curl-config --libs
On my machine, the result is
-L/usr/lib/i386-linux-gnu -lcurl
then do according to this screenshot and you will be able to compile. btw don't forget to add header files in your code
So you enter library folder path without -L and library name without -l because they will be automatically added by linker.
You have to link the library to your program. With gcc (and most other compilers) you can specify the libraries to link with -lname_wo_lib, e.g. -lcurl
Also see GNU GCC Manual - Options for Linking for a detailed explanation of the options Adam Rosenfield said. For standard search directories, see An Introduction to GCC - for the GNU Compilers gcc and g++ - Setting Search Paths.
In addition to the first answer, I had to link the curlpp library too. So to compile the main.cpp file which included the curlpp I had to do:
g++ main.cpp -lcurl -lcurlpp
Using only one of the two links would return different errors regarding different links. It is important to remind that this only worked because I had installed all the necessary libraries in the standard include folders