Dynamic linking GLFW with make - glfw

I am trying to compile a simple tutorial program utilising glfw with minimal opengl. My issue appears to be that the glfw library is stubbornly refusing to be dynamically linked. The relevant make command is:
"C:\Program Files\mingw-w64\mingw64\bin\g++" -Wall -m64 -D GLFW_DLL -l opengl32 -l glfw3 main.o -o triangle <br />
The main.o file is compiled from a c++ file, main.cpp by:
"C:\Program Files\mingw-w64\mingw64\bin\g++" -c -Wall -m64 -D GLFW_DLL main.cpp -o main.o
Every reference to the glfw functions made inside the code is causing an undefined reference to the relevant implementation functions (eg. __imp_glfwInit for glfwInit => undefined reference to '__imp_glfwInit')
Build system is mingw-w64 [windows] using make via the command line, with glfw 3.0.4. The glfw lib is 64 bit and the latest stable build avaliable. It consists of the files:
glfw3.dll
glfw3dll.a
libglfw3.a
Which are the 'WIN-64' 'lib-mingw'
After extensive searches (GLFW help pages useless[deal either with 2.7.2 which doesn't apply or doesn't have useful information in the case of 3.0.4], most of stackoverflow deals with static linking, ect) I have been unable to find a solution which works.
Is there something I am missing dealing with the linker that is not making me able to dynamically link?
Clarification on any errors I am making or a solution of some form that would still allow me to use the dynamic libraries would be greatly appreciated

It appears that the provided files do not work with mingw-w64, and are only compatible with 64bit mingw.
Thus the only option left is linking against the dll (with thanks to greatwolf: https://stackoverflow.com/a/17734362/2396393). The code to compile to objects thus became:
"C:\Program Files\mingw-w64\mingw64\bin\g++" -Wall -m64 -D GLFW_DLL main.o -o triangle ./lib/glfw3.dll -l opengl32
Where the dll glfw3 is located in the lib folder

Related

(C++) How do I use libraries when compiling for windows on linux?

I can already cross-compile some simple applications using x86_64-w64-mingw32-g++. However, I cannot find out how to find libraries for my project (in my case I need to use SDL2 and SDL2_image). I know how to install these libraries already (sudo apt install libsdl2-dev libsdl2-image-dev), but apt search does not show any libraries for x86_64-w640mingw32-g++.
Here are the links I've looked at:
https://arrayfire.com/cross-compile-to-windows-from-linux/
https://stackoverflow.com/questions/2033997/how-to-compile-for-windows-on-linux-with-gcc-g
Is there a way to use precompiled libraries, or do I need to add the source code in my project?
Update: I followed the instructions advised by Laurent Jospin, and can compile a "Hello World" program that works with Windows (I sent it to a friend to test). However, I cannot compile my program that uses SDL.
Terminal output:
$ /opt/mxe/usr/bin/x86_64-w64-mingw32.shared-g++ -O3 main.o Game.o TextureManager2D.o Map.o Entity.o Player.o -mwindows -lSDL2 -lSDL2_image -o ../../../endeavour-client.exe
/opt/mxe/usr/lib/gcc/x86_64-w64-mingw32.shared/5.5.0/../../../../x86_64-w64-mingw32.shared/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): In function `main':
/opt/mxe/tmp-gcc-x86_64-w64-mingw32.shared/gcc-5.5.0.build_.crt/../gcc-5.5.0.build_/mingw-w64-v8.0.0/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain'
collect2: error: ld returned 1 exit status
$
Changing -mwindows to -municode, -d UNICODE, -Wl,-subsystem,windows, or removing it all do not work.
What you are looking for is the M Cross Environnement: https://mxe.cc/
It is a set of makefiles able to download and cross compile a selection of popular libraries for windows on linux. By default it builds static libraries, such that you ends up with .a libraries that get merged into the final .exe, meaning you don't have to worry about shipping the dlls with your app. But if you prefer a modular structure, it can also builds some dlls.
The list of libraries they do provide is quite impressive. If a library is missing on the other hand you can still install it by copying the corresponding header files and dlls. In some specific situation you might have to cross-compile one of your dependency (I had to do that for an app using ruby scripting. The official windows build of ruby is somehow incompatible with certain libraries built with mingw. But this is rather exceptional).
The correct command is:
$ /opt/mxe/usr/bin/x86_64-w64-mingw32.shared-g++ -O3 main.o Game.o TextureManager2D.o Map.o Entity.o Player.o -mwindows -lmingw32 -lSDl2main -lSDL2 -lSDL2_image -o ../../../endeavour-client.exe
Edit: Note that having -lmingw32 -lSDL2main -lSDL2 -lSDL2_image in that exact order is vital.
I, being the absolute idiot that I am, forgot to include the -lmingw32 AND -lSDL2main flags in the command, which is why there is the issue with WinMain not being found. When using MinGW-w64 as the cross compiler, the -lmingw32 library has to be included. And of course, SDL requires the -lSDl2main flag when building for windows (but interestingly enough, not on Linux). Here are the links I used. (I had an uncommon insight in replacing -lSDLmain with -lSDL2main, as the links are pretty old.)
MinGW Starter Guide
Code::Blocks Forums
SO: Undefined Reference to WinMain

"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

Setup eclipse linker to compile and run GLFW applications - How to?

Based on this question I was able to make one default cmake compilation for GLFW libraries, compile my GLFW App and run; everything works and was made through the terminal since I'm using Ubuntu 14.04 64 bits.
I was using this line to compile:
g++ -std=c++11 -c main.cpp
And this to link:
g++ main.o -o main.exec -lGL -lGLU -lglfw3 -lX11 -lXxf86vm -lXrandr -lpthread -lXi
After use those commands I only needed to execute main.exec. However, I would like to setup eclipse to compile and run this GLFW application. Include files are already settled on the project but I'm having trouble with my linkers. I was trying to track my libraries (GL, GLU, glfw3....) manually to set the folders but I couldn't find all of them. Does anyone know how could I track the libraries to set them on my linker(Project - Properties - C/C++ Build - Settings - GCC C++ Linker) or could give me some guidelines to solve this situation, please?
Thanks in advance
After try and research for some hours, I found the solution which is pretty easy:
Instead of add paths to libraries, just add their names as it is in the command line. I still don't know from where the path reference for those libraries are coming (and would be great if someone could explain) but what is most important is that works. After build just run (CTRL + F11) like any other application.

Building code that uses EVP_* functions in Ubuntu

I am trying to build some code that uses the EVP_* functions in Ubuntu, however when I build, I get the dreaded "undefined reference" errors.
I am using Ubuntu 11.10.
The following line is how I compile:
g++ -lcrypto -lssl *.cpp -o IOService
[...]
crypto.cpp:(.text+0x8): undefined reference to `EVP_md5'
[...]
The cpp files include openssl/evp.h.
I have installed the libssl1.0.0-dbg package, but those libraries get installed in /usr/lib/debug/lib/i386-linux-gnu/ where my linker doesn't seem to find them. I tried softlinking and copying the .so files, to no avail (and I have the feeling this is not the way to go).
ld is a one-pass linker, meaning that you have to add libraries after the object files that use them: g++ *.cpp -o IOService -lcrypto (I think libssl is not needed if all you need is md5)

Configuring a library to be included with C++ test

I would like to utilize the UnitTest++ library in a testing file. However, I am having some difficulty getting the library to be included at compile time. So here is my current directory structure:
tests/
UnitTests++/
libUnitTest++.a
src/
UnitTests++.h
unit/
test.cpp
I have just used the UnitTest++ getting started guide to just get the library setup. Here is test.cpp:
// test.cpp
#include <UnitTest++.h>
TEST(FailSpectacularly)
{
CHECK(false);
}
int main()
{
return UnitTest::RunAllTests();
}
And I am currently trying to compile with:
gcc -lUnitTest++ -L../UnitTest++/ -I../UnitTest++/src/ test.cpp
I am currently getting a bunch output with ld: symbol(s) not found at the end. So how would I be able to get the UnitTest++ library properly included when this program is compiled? I am on a Mac and I'd also like for there to be an easy way for people on a Linux machine to run these same tests.
Whew, I hope this provides enough information, if not please let me know.
I was able to build it in the following manner
gcc -L../UnitTest++/ -I../UnitTest++/src/ test.cpp -lUnitTest++ -lstdc++
or
g++ -L../UnitTest++/ -I../UnitTest++/src/ test.cpp -lUnitTest++
that links to libstdc++ automatically.
GCC documentation says:
-llibrary
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified.
Thus, foo.o -lz bar.o' searches libraryz' after file foo.o but before bar.o. If bar.o refers to functions in `z', those functions may not be loaded.
I guess that's why the library symbols are not found when you first specify -lUnitTest++ and then test.cpp
Compile test.cpp to get test.o
and use
g++ test.o libUnitTest++.a -o ./exectest
to get the ./exectest executable
libUnitTest++.a is just an archive of all the object files of UnitTest++. You just need to link all the object files (your test object file + libUnitTest++.a)
Try editing the makefile that came with unittest++ and make it suitable for your case
The message ld: symbol(s) not found means you haven't compiled the library. So you need to go in the UnitTest++ folder, compile and install it.
I've never worked on a MAC, but in linux, libraries are usually compiled and installed with:
./configure
make
make install
In the UnitTest++ link you posted, you should simply:
make install
Then you will have the UnitTest++.so library in the libraries folder of your OS. Now the library can be linked with your program with the -lUnitTest++ command.
Usually you have to put -Lsomething before the -lsomething that requires it.