How to choose between shared and static library? - c++

I'm trying to run the standard example from the SFML Library in Linux. I have download the Rep. from Github, build and install it with CMake. I have build 2 Libraries for static/shared debug, and 2 Libraries for static/shared Release.
The problem now, I don't know much about compiling in the Terminal. I use the commands I found on the SFML Website:
g++ -c test.cpp
g++ test.o -o sfml-app -lsfml-graphics -lsfml-window -lsfml-system
that works. I can run my SFML Application by ./sfml-app and double-click. But other people who (who have not installed SFML) using Linux cant. And I think it's because the compiler does not use the static libraries. Of course - how he could? It's not written in the command. But I also don't know how to write it.
The name of the static-release libraries is for example
libsfml-graphics-s.a
libsfml-window-s.a
libsfml-system-s.a
what must I write in g++, that he is using this libs when he link the stuff?

To link your program against the static versions of the libraries, you would do the following:
g++ test.o -o sfml-app libsfml-graphics-s.a libsfml-window-s.a libsfml-system-s.a
(Assuming, of course, that these files are in your local directory.)

Related

How to properly link a static library in C++ with gcc [duplicate]

I am trying to link GLFW to my C program.
The docs seem to suggest #include<GLFW/glfw3.h> however I have installed 2.7.2 (from my distro's repository) and don't have that header file:
find / -name *glfw* 2> /dev/null
/usr/lib/libglfw.so.2.6
/usr/lib/libglfw.a
/usr/lib/libglfw.so
/usr/lib/pkgconfig/libglfw.pc
/usr/lib/libglfw.so.2
/usr/include/GL/glfw.h
/usr/share/doc/libglfw-dev
/usr/share/doc/libglfw2
/var/cache/apt/archives/libglfw2_2.7.2-1_i386.deb
/var/cache/apt/archives/libglfw-dev_2.7.2-1_i386.deb
/var/lib/dpkg/info/libglfw2.list
/var/lib/dpkg/info/libglfw2.postinst
/var/lib/dpkg/info/libglfw-dev.md5sums
/var/lib/dpkg/info/libglfw2.postrm
/var/lib/dpkg/info/libglfw2.md5sums
/var/lib/dpkg/info/libglfw2.shlibs
/var/lib/dpkg/info/libglfw-dev.list
I tried #include<GL/glfw.h> but I still get undefined reference to 'glfwLoadTexture2D'
How do I link to GLFW and use glfwLoadTexture2D()?
An #include does nothing for the linker; it just brings in declarations, not the actual functions.
The documentation indicates that GLFW uses pkg-config (not surprising; #elmindreda knows her stuff), so your compilation line should be something like:
$ cc `pkg-config --cflags glfw3` -o foo foo.c `pkg-config --static --libs glfw3`
Also note that since the library uses pkg-config, you're not supposed to "care" about details such as where the header and library files are located on your particular installation. Just ask using the --cflags and --libs modes, and you will get the proper locations returned, as the example above indicates.
You are mixing up compilation and linking. If you were missing headers, you would probably have errors a lot sooner than the linking stage.
"Undefined reference" results from symbols not being found by the linker. The most likely cause is you not telling gcc that it should link to the GLFW libraries:
gcc myfile.c -lglfw
When I am on Linux, I compile opengl/glfw projects like this:
gcc main.c -lGL -lglfw
When I am on windows, I compile them by writing:
gcc main.c libglfw3.a -lopengl32 -lgdi32
and I put libglfw3.a file in the same directory where main.c is. I have read people say that they couldn't link properly before writing
-lopengl32 -lgdi32 -luser32 -lkernel32 -lws2_32.
Another thing which may be worth mentioning is that I couldn't link glfw libraries when I downloaded 32bit glfw binaries. When I downloaded 64bit glfw binaries everything worked fine. I have a 64 bit machine and a x86_64-w64-mingw32. I have read comments from people with the opposite experience, where they weren't able to link glfw libraries when they downloaded 64bit binaries, but they were able to link them after downloading 32bit binaries. My advice would be to try both.

How to compile to SDL2 application to Windows from Linux?

So recently I downloaded the Linux Subsystem on Windows 10, with Ubuntu.
I can compile an SDL2 app to Linux with the g++ command but whenever I try doing it with i686-w64-mingw32-g++ this command, I get an error saying main.cpp:5:9: fatal error: SDL2/SDL.h: No such file or directory.
The command I'm using is i686-w64-mingw32-g++ main.cpp -w -lSDL2 -o main.exe.
https://imgur.com/a/uqcGCoJ
Anyone knows how to fix this? :(
[EDIT]
So now I've tried specifying the directory of the necesary files with this command: g++ main.cpp -I/usr/include/SDL -L/usr/lib/x86_64-linux-gnu -w -Wall -Wextra -std=c++17 -lSDL2 -o main
which worked but when I use it with mingw it doesn't i686-w64-mingw32-g++ main.cpp -I/usr/include/SDL -L/usr/lib/x86_64-linux-gnu -w -Wall -Wextra -std=c++17 -lSDL2 -o main
https://imgur.com/a/sF6CpcP
You need to include the path to SDL's include directory on the command line. However, you need to include the path to the downloaded SDL for mingw32, not /usr/include/SDL2. The difference is the headers in /usr/include/SDL2 are for Linux and libs in /usr/lib are also for Linux, but you need to link to the Windows libraries.
What I usually do is download the development libraries for Mingw32 and put them directly into my project directory. Then all you need to do is add -ISDL2-2.0.8/i686-w64-mingw32/include -LSDL2-2.0.8/i686-w64-mingw32/lib to your command line and it will be able to find the headers and libraries it needs. Finally, make sure you copy SDL2-2.0.8/i686-w64-mingw32/bin/SDL2.dll to your executable directory in the Makefile.
Also, remember to link SDLmain as well. It handles creating a WinMain for you and all that, and then calls your main function.

Create static library with no (OpenSSL) dependencies

I am having a piece of code (test.cpp) which depends on OpenSSL. I would like to create a static library with my piece of code, but it should really include already all dependencies. So that in the end I really only need to link against libtest.a file (also on other distros).
I have tried this
g++-7 -c -std=c++17 -static -L/usr/local/lib -lssl -lcrypto test.cpp -o test.o
ar crf libtest.a test.o
g++-5 main.cpp -std=c++11 libtest.a
but it still gives undefined references to OpenSSL stuff.
Don't judge me, my knowledge about compiling is equal 0, usually I let Qt handle this.
I would appreciate it if somebody could sketch how to accomplish it.
A .a file is a collection of .o files and no more. There is no possibility of linking.
Perhaps you could make a .so file (shared library) which does allow things to be statically linked to it.
Note: If you statically link OpenSSL and the person using your library also uses OpenSSL then it means their binary will be bloated by having two copies of it (linkers are not smart enough to optimize this), so it may be a good idea to also publish a version of your library that doesn't statically link OpenSSL.

Running a SFML C++ program with minGW on Windows 10

So I'm trying to run an example SFML program on my Windows laptop. If relevant, the source code is on this page.
So first I make the .o file using this command -
g++ -c a.cpp -ISFML/SFML/include
Where a.cpp is the main file, and my SFML package is located in SFML/SFML.
Then I compile using this command -
g++ a.o -o a -LSFML/SFML/lib -lsfml-graphics -lsfml-window -lsfml-system
When I first ran the program I got the errors about not being able to find certain dlls, sfml-graphics-2 etc. So I found them and put them next to the exe. But now when I run, I get this weird error:
The procedure entry point
_ZNSt7__cxx1112basic_stringSt11char_traitsIcESalcEE7reserveEj could not be located in the dynamic link library.
What is going on here?
As the SFML download page states, You could be using the wrong version of the compiler, other library versions of SFML that you have not removed from your working directory that could mismatch between code and linker. Worst case, if your compiler is not listed there, you have to compile SFML yourself:
Get CMake. Get the source code for 2.4.2 by going to the bottom of the SFML download page. Follow this guide on SFML's GitHub repo. Alternatively, you could use the guide on SFML's page but it is for an older version. It might answer some questions that the first guide misses.
Ones CMake have generated the makefiles, you're on your way to build SFML.
Good luck!
I've had this problem for so long so I just wanted to help someone out who had the same problem. I have a windows 10 FYI and MinGW-w64 8.1.0 (if it doesnt work try a 32 bit mingw instead)
for a debug mode (debug is when your still working on the game and would like command prompt to open whenever you run it)
(make sure your in the right directory first by doing "cd")
g++ -c (file_name).cpp -o (file_name).o -I(path_to)SFML-64-bit/include -g -m64 -Wall &&
g++ (file_name).o -o (game_name).exe -L(path_to)SFML-64-bit/lib -lsfml-graphics -lsfml-window -lsfml-system
The code above when placed in command will compile everything for you if its all in the same directory so make sure you keep an eye out for that
and now for release mode (if you dont want command prompt to show up)
g++ -c (file_name).cpp -o (file_name).o -I(path_to)SFML-64-bit/include -O3 -m64 &&
g++ (file_name).o -o (game_name).exe -L(path_to)SFML-64-bit/lib -lsfml-graphics lsfml-window -lsfml-system -mwindows
Noticed all I added was the -mwindows and the -O3 aswell as removing -g and -Wall which are not necessary since we wont be using command prompt
Make sure to go to SFML/bin and take all the .dlls and put it into the same directory has your .exe sorry xd
Hope this helped.

-L option not working for mingw gcc

I am trying to get mingw gcc to work.
I need it to link with libopengl32.a.
Said file exists in C:/mingw/lib.
I used g++ as follows:
g++ -L"C:/mingw/lib" main.o -o test.exe -llibopengl32.a
It has no trouble finding the includes, it just complains that it can't find the library.
It seems unable to find any other library as well.
Also: I installed all the mingw components manually by downloading them from sourceforge, since using the automatic installer produced a broken installation on my system.
The -l flag automatically adds the lib prefix and the .a extension- you want:
g++ -LC:/mingw/lib main.o -o test.exe -lopengl32
Note you don't need the quotes around the path either. You could also just specify the whole library name & path:
g++ main.o -o test.exe C:/mingw/lib/libopengl32.a
As regards your installation problems, use either http://tdragon.net/recentgcc/ or http://nuwen.net/mingw.html - using the MinGW site itself is a recipe for pain.
You need to use -lopengl32 without "lib" and ".a"