How to setup GLFW with eclipse c++ and MinGW compiler? - c++

How do I include glfw.h and link the libraries libglfw.a and libglfadll.a in eclipse juno c++ with MinGW compiler. This is an attempt I made on setting it up:
This is the build command I tried to use:
g++ -o Practice.exe "src\\main.o" "-lC:\\Users\\Kaiden.ZEUS\\Files" & "Folders\\Programming\\C++\\Workspaces\\Practice\\Practice\\lib\\libglfw.a" "-lC:\\Users\\Kaiden.ZEUS\\Files" & "Folders\\Programming\\C++\\Workspaces\\Practice\\Practice\\lib\\libglfwdll.a"

Nothing of this is specific to OpenGL or GLEW, you're dealing with basic programmer craftsmanship skills here: How to configure a compiler linker toolchain to use additional libraries. This is essential knowledge, so please take the patience to properly learn it. The following is just a short list of notes what you should change. But you should really take up some learning material on the compilation and linking process to understand it.
You should place the libraries and headers into system wide directories, but not the standard directories of the compiler suite and configure those as additional search paths for the compiler and linker.
DO NOT put 3rd party library and header files into your project source tree, unless you take proper precautions that it won't interfere with likely installed systemwide instances of them.
Also you must choose between the static or the dynamically linked version of GLFW. If you use both you'll get symbol conflicts (this is something specific to GLFW).
In your build command line you're using the -loption with *directories*. This is wrong, search paths are specified using-L(capital L), while-l(lower l) just specifies library names without the path, prefix and suffix. Also you can replace backslashes` with forward slashes /, saving you some typing, i.e. the \\ escaping to produce a single backslashe to the command. In your case (I shortened the path)
g++ -o Practice.exe "src/main.o" "-LC:/Users/Kaiden.ZEUS/Files/ ... /lib" "-lglfw"
or
g++ -o Practice.exe "src/main.o" "-LC:/Users/Kaiden.ZEUS/Files/ ... /lib" "-lglfwdll"
However this compile command lacks specification of the include files. Say you've got the GLEW headers installed in C:/Users/Kaiden.ZEUS/Files/ ... /include/GL you'd add
"-IC:/Users/Kaiden.ZEUS/Files/ ... /include/GL"
to the command line.

Related

Set up GLFW for OpenGL for C++ without Visual Studio

I want to set up GLFW3 to work with C++ in a program called 4coder. I have a folder named libraries that holds all the stuff I need, I just don't know how to get C++ to include them using #include <GLFW/glfw3.h>. I literally started using C++ today and have no idea where to start.
You will need to add arguments when compiling the source code to specify the location of your headers and libraries. Exactly how this is done will depend on which compiler you are using but for example if you're using g++:
path-to-working directory>g++ name-of-file.cpp -Ipath-to-header-files -Lpath-to-library-files -lglfw3 -o name-of-executable
The key points here are the -I flag (which tells the compiler where to look for header files) and the -L flag (which tells the compiler where to look for libraries). -lglfw3 will then cause the compiler to look in the directory specified with the -L flag for the glfw3 library.
If you're using a different compiler, the syntax may be different but the general principle will apply - you just have to find the equivalent commands to -I and -L.

How to correctly set GSL path on mac

I have 'correctly' installed gsl on mac 10.13.2.
In my c++ program, I am calling like usual, for example:
#include <gsl/gsl_math.h>
However while running the code, it can not find the gsl.
fatal error: 'gsl/gsl_math.h' file not found
I was wondering how to correctly link gsl PATH and libraries.
I have tried,
setting PATH and LD_LIBRARY_PATH in .bash_profile
setting PKG_CONFIG_PATH to .../Gsl2.3/lib/pkgconfig
$which gsl-config returns
/Users/gkdgoutam/Softwares/HEP_Softwares/Install/Gsl2.3/bin/gsl-config
$pkg-config --libs gsl returns
-L/Users/gkdgoutam/Softwares/HEP_Softwares/Install/Gsl2.3/lib -lgsl -lgslcblas -lm
The only solution I can find is to run everytime with gsl linked.
Like:
g++ $(gsl-config --cflags) mycode.cc $(gsl-config --libs) && ./a.out
But I was wondering if the GSL PATH can be set globally so that I can simply run
g++ mycode.cc && ./a.out
This is how c++ code is compiled and built:
COMPILATION
A compilation unit will take each cpp file and work its way through included headers to locate forward declaration of implementations of symbol signatures of used functionality in your code. In your case this involves gsl/gsl.h. If the file cannot be found in the search directories, which you can expand by specifying C_INCLUDE_PATH and or CPLUS_INCLUDE_PATH. If you omit #include <gsl/gsl_math.h>, your code will not compile as there are signatures, which cannot be found for GSL functions, which you use.
LINKING
Once you have compiled all cpp/cc files you need to link the binary, which can be executed. The linking process consists of a search through all symbols in your .o/.obj... files and a matching of the same to what it can find in your object files and the libraries, which you have specified using for example -lgsl. If all goes well, every lookup finds an according binary implementation for your machine's hardware model (i.e. 64bit/32bit ..., Arm, Intel, ... etc). If some are not found you will find linkage errors.
What you are asking is, is there a way that C++ does not work as above? No!
If you leave out #include <gsl/gsl.h> or if said file is not found in your search paths, compilation will not work or. If you omit -lgsl, linking will fail. If you find it annoying to write all the above stuff in the command line, write a Makefile to reduce the building process to ideally a simple command: make.
Don't forget, that if you are linking against the shared library version of GSL, you might need specifying LD_LIBARAY_PATH on Linux and DYLD_LIBRARY_PATH on Macs as well.
TLDR: you cannot ask a c++ compiler / linker to work differently as designed.

Undefined reference when trying to use external library

I am trying to incorporate a C library into some Rcpp code.
I can use the C library in a C++ program easily. I 'make' the C library, which creates the .a and .dll files in the /lib folder. I can then use the package by including the header in the program and running something like this from command line:
cc myfile.cpp -o myfile -Ipath.to.header path.to.lib.a -lz
This essentially tells the compiler to take the .cpp program, include headers from -I, and to link to two libraries.
Getting this to work with Rcpp shouldn't be overly difficult if I understand makevars correctly (which I unfortunately don't seem to).
I add the library to a folder in my package, and in src I add a makevars and makevars.win that look like this:
PKG_CFLAGS=
# specify header location
PKG_CPPFLAGS=-Ipath.to.lib/include
# specify libs to link to
PKG_LIBS=path.to.lib/lib/file.a -lz
# make library
path.to.lib/lib/file.a:
cd path.to.lib;$(MAKE)
This correctly 'makes' the .a and .dll files for the library, however none of the Rcpp magic runs (i.e. in the build I never see the g++ system call that compiles the files in src), so "no Dll was created".
I am fairly certain this is a problem in my makevars target that makes the library. When I remove that portion from the makevars, and 'make' the library from the command line myself before building the package, I get the proper g++ calls with my -I and -l statements, but I get errors about undefined references.
I notice that the -l statements are only included in the final g++ call where the final .dll is made, but isn't included in the earlier g++ calls where the files with the library headers are compiled.
So I have two problems:
How do I fix my makevars so that it 'makes' the library, but doesn't stop Rcpp from compiling the files in src?
How do I deal with the undefined references? The library is clearly not header-only, so I am guessing it needs the -l statement in the earlier g++ calls, but that may not even be possible.
The best approach is to avoid complicated src/Makevars file altogether.
One easy-ish approach around this: use configure to build your static library, then once you actually build just refer to it in src/Makevars.
I use that scheme in Rblpapi (where we copy an externally supplied library in) and in nloptr where we download nlopt sources and build it 'when needed' (ie when no libnlopt is on the system).

Linking shared, static, and dynamic library

I built and installed the source code of spidermonkey, I want to link its library and its include folder with my C++ application, so I wrote this command on linux
g++ -I/home/SpiderMonkey/js-1.8.5/js/src/dist/include
-L/home/SpiderMonkey/js1.8.5/js/src/dist/lib -lmozjs185 helloworld.cpp -o
but it gives me undefined reference error, so what is the problem with this command:
the path which the src code was built in is home/SpiderMonkey/js1.8.5/src
and when I installed the src code, its libs and include folder exist now in usr/local/lib and usr/local/include/js respectively, so which path should I use in the command to compile my hellowrorld.cpp.
Also, I found 3 libraries with the same name but with different extension:
libname.so, libname.so.1.0, libname.so.1.0.0 and libname.a
which library should I use and what are the differences?
Put the libraries after your main.cpp on the compilation command. The linker determines which symbols to pull out of those libraries based on the objects it's already seen, left to right.
As for your addendum question:
libname.a is for static linking.
libname.so, libname.so.1.0 and libname.so.1.0.0 are all the same file, just with names that give you an increasing level of version information granularity.
Which to use is beyond the scope of this answer, but you can find plenty of information about that already existing on the web.

When look up symbol, the program doesn't search from the correct library

I'm adding two classes and libraries to a system, parent.so and child.so deriving from it.
The problem is when the program is loading child.so it cannot find parent's virtual function's definition from parent.so.
What happens,
nm -D child.so will gives something like (I just changed the names)
U _ZN12PARENT15virtualFunctionEv
The program will crash running
_handle = dlopen(filename, RTLD_NOW|RTLD_GLOBAL); //filename is child.so
it'll give an error with LD_DEBUG = libs
symbol lookup error: undefined symbol: _ZN12PARENT15virtualFunctionEv (fatal)
The thing I cannot explain is, I tried LD_DEBUG = symbols using GDB, when running dlopen, the log shows it tried to look up basically in all libaries in the system except parent.so, where the symbol is defined. But from libs log parent.so is already loaded and code is run, and it is at the same path of all other libraries.
......
27510: symbol=_ZN12PARENT15virtualFunctionEv; lookup in file=/lib/tls/libm.so.6
27510: symbol=_ZN12PARENT15virtualFunctionEv; lookup in file=/lib/tls/libc.so.6
27510: symbol=_ZN12PARENT15virtualFunctionEv; lookup in file=/lib/ld-linux.so.2
27510: child.so: error: symbol lookup error: undefined symbol: _ZN12PARENT15virtualFunctionEv(fatal)
How the program or system is managing which library to look for a symbol's definition?
I'm new to Linux, can anybody point me some directions to work on?
Thanks.
EDIT
The command used to generate parent.so file is
c++ -shared -o parent.so parent.o
Similar for child.so. Is any information missing for linking here? Looks like child is only including parent's header file.
EDIT2
After another test, calling
_handle = dlopen("parent.so", RTLD_NOW|RTLD_GLOBAL);
before the crashing line will solve the problem, which I think means originally parent.so was not loaded. But I'm still not very clear about the cause.
You need to tell the linker that your library libchild.so uses functionality in libparent.so. You do this when you are creating the child library:
g++ -shared -o libchild.so child_file1.o child_file2.o -Lparent_directory -lparent
Note that order is important. Specify the -lparent after all of your object files. You might also need to pass additional options to the linker via the -Wl option to g++.
That still might not be good enough. You might need to add the library that contains libparent.so to the LD_LIBRARY_PATH environment variable.
A couple of gotchas: If you aren't naming those libraries with a lib prefix you will confuse the linker big time. If you aren't compiling your source files with either -fPIC or -fpic you will not have relocatable objects.
Addendum
There's a big potential problem with libraries that depend on other libraries. Suppose you use version 1.5 of the parent package when your compile your child library source files. You manage to get past all of the library dependencies problems. You've specified that your libchild.so depends on libparent.so. Your stuff just works. That is until version 2.0 of the parent package comes out. Now your stuff breaks everywhere it's used, and you haven't changed one line of code.
The way to overcome this problem is to specify at the time you build your child library that the resultant shared library depends specifically on version 1.5 of libparent.so`.
To do this you will need to pass options from g++/gcc to the linker via the -Wl option. Use -Wl,<linker_option>,<linker_option>,... If those linker options need spaces you'll need to backslash-escape them in the command to g++. A couple of key options are -rpath and -soname. For example, -rpath=/path/to/lib,-soname=libparent.so.1.5.
Note very well: You need to use the -soname=libparent.so.1.5 option when you are building libparent.so. This is what lets the system denote that your libchild.so (version 1.0) depends on libparent.so (version 1.5). And you don't build libparent.so. You build libparent.so.1.5. What about libparent.so? That needs to exist to, but it should be a symbolic link to some numbered numbered version (preferably the most recent version) of libparent.so.
Now suppose non-backward compatible parent version 2.0 is compiled and built into a shiny new libparent.so.2.0 and libparent.so is symbolically linked to this shiny new version. An application that uses your clunky old libchild.so (version 1.0) will happily use the clunky old version of libparent.so instead of the shiny new one that breaks everything.
It looks like you're not telling the linker that child.so needs parent.so, use something like the following:
g++ -shared -o libparent.so parent.o
g++ -shared -o libchild.so -lparent child.o
When you build your main program, you have to tell the compiler that it links with those libraries; that way, when it starts, linux will load them for it.
Change their names to libparent.so and libchild.so.
Then compile with something like this:
g++ <your files and flags> -L<folder where the .so's are> -lparent -lchild
EDIT:
Maybe it would be a smaller change to try loading parent.so before child.so. Did you try that already?