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

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.

Related

gcc: "cannot find -lasound" when compiling on Windows

I am compiling a C++ program on Windows. The program uses the SDL2 library. I run the following pkg-config command to obtain the correct flags to pass to the GCC compiler.
$ pkg-config sdl2 --cflags --libs
which gives output
-lpthread -lasound -IC:/sdl2/include/SDL2 -LC:/sdl2/lib -lSDL2
However when using these flags with GCC the program fails to compile, giving the error
cannot find -lasound
Is this a library I need to obtain in order to use SDL2, or am I making a mistake somewhere?
GCC not find this library. Find file libcomdlg32.a and find your -lasound file and copy -lasound file in folder, where's libcomdlg32.a file.

Undefined boost reference despite correct linking

I found a lot of similar problems, but I was not able to apply any given solution for me. A few months ago, I worked on a project using the boost library. I compiled simply in the command line, as described on the boost website.
g++ -I pathToBoost file.cpp -o file -lboost_system -lboost_filesystem
The two required linkings to boost_system and boost_filesystem were also done. This worked perfectly, but now suddenly an error occurs when i tried to compile it again.
/usr/bin/ld: /tmp/ccM2BzEo.o: in function `boost::system::generic_category()':
file.cpp:(.text._ZN5boost6system16generic_categoryEv[_ZN5boost6system16generic_categoryEv]+0x7):
undefined reference to `boost::system::detail::generic_category_instance'
Well, it seems to me that there is an error linking the boost_system library. Since the same thing worked before, is a problem with the compiler possible?
I used
Boost 1.68.0
g++ (GCC) 8.2.1
ManjaroLinux 18.0.3
I hope that somebody can help me here and that I was not just too stupid to see a solution in another thread.
Greetings!
The order of libraries in linker command line is important. boost_filesystem depends on boost_system, hence the fix:
-lboost_filesystem -lboost_system
Alternatively, you can surround the list of libraries with --start-group and --end-group to make the linker re-scan the libraries multiple times until it either fails or resolves all symbols, so that no specific ordering of libraries in the command line is necessary. However, it may take longer to link. E.g.:
g++ -I pathToBoost file.cpp -o file -Wl,--start-group -lboost_system -lboost_filesystem -Wl,--end-group
Since you specify -I pathToBoost you also need to specify -L<path-to-boost-libs> -Wl,-rpath=<path-to-boost-libs>. Otherwise it uses headers from one version of boost from pathToBoost, but links wrong libraries from your system boost.

g++ cannot link stdc++ statically (windows)

I've been doing a simple c++ program with use of curlpp library. I can build and compile everything just right and I can run it if having MinGW in my PATH. When I delete it and copy all curlpp dlls in the directory, it says (of course):
The program can't start because libgcc_s_dw2-1.dll is missing from your computer. Try reinstalling the program to fix this problem.
I believe that the problem is that std libraries are not linked statically, but I tried all possibilities and it seems as they are not linked. I type:
g++ -o myApp.exe main.cpp -std=gnu++11 -L(curl,curlpp,opensll) -I(all includes) -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic -lcurlpp -lcurl -Wl,--as-needed
with no errors, then I run it and I get error from above. Of course, if I have MinGW in my PATH, then everything works.
I tried to change the order of options in the command without any luck. Putting -static-libgcc -static-libstdc++ as advised elsewhere is not working.
Thanks in advance
Regards

How to choose between shared and static library?

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.)

Is it possible to build protobuf without pthread?

There is a need to use Protocol Buffers on the real-time OS where there is no pthread. I am able to link protobuf statically this way
g++ -g -Wall example.pb.cc example.cc -o example -static -lprotobuf -lpthread
However without pthread I get link errors. Is it possible to configure protobuf to work without pthread?
Not really. See this unresolved issue.
Someone has patched an older protobuf version to not depend on pthreads, see here - which you might take a look at if you really need it, and possibly forward port.
Also note that you're supposed to use pkg_config to get the proper compiler and linker flags when using protobuf, e.g.
pkg-config --cflags protobuf # compiler flags
pkg-config --libs protobuf # linker flags