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
Related
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.
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.
I am a student currently working on a project to implement Intel Hyperscan for Virus Signature Scanning on Ubuntu 16.04.
On the system, I have gcc 5.4.0 and g++ 5.4.0.
Hyperscan uses CMake to "build" itself.
Having successfully build Hyperscan, I can't seem to be able to find a way to compile my own code for it. I also could not find any "proper" way of compiling code meant for Hyperscan online, hence I assumed g++ would be right. I have tried,
g++ -o -std=c++11 test test.cc $(pkg-config --cflags --libs libhs)
only for it to give the error: hs.h: No such file or directory
Hence I used,
g++ -o -std=c++11 test test.cc -I../hyperscan/src $(pkg-config --cflags --libs
libhs)
to get another error:
/usr/bin/ld: cannot find -lhs and collect2: error: ld returned 1 exit status
At this point, I am kind of lost and can't really progress with my project. Am I using g++ wrongly? Have I built Hyperscan incorrectly? Any tips or solutions would be greatly appreciated!
$(pkg-config --cflags --libs libhs) only works when library and related development files are installed on the system. Looks like you have source code of library, so first you need to build and install library itself, only then compile your test program.
Also, library may be available in standard repositories, then you maybe want to install it using something like "sudo apt install libhs-dev", however, if you have source code of particular version that you need to work with, or library is closed source and non-public, then the only way is to compile and install it manually. Refer to documentation, README, INSTALL files that may be supplied with library code and follow build and installation procedures described there.
Simple question- are these any way to not have to call libraries during the compiling? I mean, I would like to simply call g++ main.cpp without calling g++ main.cpp -lGL -lGLU -lGLEW -lSTL -lMyMother and so on... I know, makefiles or simple shell scripting, but I would like to make it elegant way - call these libraries inside cpp code - something like 'using GL;'.
Since you're using GCC, you could create/modify a specs file to add the flags you want.
If you don't like typing flags, you really should be using a makefile, though.
Technically you can dynamically load libraries by dlopen() and call functions from it (I am assuming you are on *nix). Though that would be not the same thing and I doubt will make your life easier. Other than that there is no portable way of specifying which library to use in source file.
On Linux you may use pkg-config and shell expansion. Use pkg-config --list-all to discover what packages are known to it (you might add a .pc file to add a new package). For instance, a GTK application mygtkapp.c could be compiled with
gcc -Wall -g $(pkg-config --cflags gtk+-x11-3.0) -c mygtkapp.c
then later linked with
gcc -g mygtkapp.o $(pkg-config --libs gtk+-x11-3.0) -o mygtkapp
Notice that order of arguments to gcc always matter. Of course use g++ to compile C++ applications with GCC.
Consider also using a Makefile like this one. Then just type make to build your software (and e.g. make clean to clean the build tree).
You might use weird tricks in your Makefile to e.g. parse with awk some comments in your C++ code to feed make but I think it is a bad idea.
Technically, you still pass -I and -D flags (at compile time) and -L and -l flags (at link time) to gcc or g++ but the pkg-config utility (or make ....) is generating these flags.
If you edit your source code with emacs you could add a comment at end of your C file to set some compilation command for emacs, see this.
PS. I don't recommend configuring your GCC spec files for such purposes.
I'm trying to compile this source code from the makefile in a VPS, but its not working. The VPS is a 64 Cent OS
Here's the full error
# make
gcc -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/amx/*.c
g++ -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/*.cpp
g++ -c -O3 -w -DLINUX -I../SDK/amx/ *.cpp
g++ -O2 -fshort-wchar -shared -o "TCP_V1.so" *.o
/usr/bin/ld: TCP-LINUX_V1.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
TCP-LINUX_V1.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [all] Error 1
Here's my makefile:
GPP=g++
GCC=gcc
OUTFILE="TCP_V1.so"
COMPILE_FLAGS=-c -O3 -w -DLINUX -I../SDK/amx/
all:
$(GCC) $(COMPILE_FLAGS) ../SDK/amx/*.c
$(GPP) $(COMPILE_FLAGS) ../SDK/*.cpp
$(GPP) $(COMPILE_FLAGS) *.cpp
$(GPP) -O2 -fshort-wchar -shared -o $(OUTFILE) *.o
Anyone know what's wrong?
Do what the compiler tells you to do, i.e. recompile with -fPIC. To learn what does this flag do and why you need it in this case, see Code Generation Options of the GCC manual.
In brief, the term position independent code (PIC) refers to the generated machine code which is memory address agnostic, i.e. does not make any assumptions about where it was loaded into RAM. Only position independent code is supposed to be included into shared objects (SO) as they should have an ability to dynamically change their location in RAM.
Finally, you can read about it on Wikipedia too.
In my case this error occurred because a make command was expecting to fetch shared libraries (*.so files) from a remote directory indicated by a LDFLAGS environment variable. In a mistake, only static libraries were available there (*.la or *.a files).
Hence, my problem did not reside with the program I was compiling but with the remote libraries it was trying to fetch.
So, I did not need to add any flag (say, -fPIC) to the compilation interrupted by the relocation error.
Rather, I recompiled the remote library so that the shared objects were available.
Basically, it's been a file-not-found error in disguise.
In my case I had to remove a misplaced --disable-shared switch in the configure invocation for the requisite program, since shared and static libraries were both built as default.
I noticed that most programs build both types of libraries at the same time, so mine is probably a corner case. In general, it may be the case that you rather have to enable shared libraries, depending on defaults.
To inspect your particular situation with compile switches and defaults, I would read out the summary that shows up with ./configure --help | less, typically in the section Optional Features. I often found that this reading is more reliable than installation guides that are not updated while dependency programs evolve.
Fixed it with -no-pie option in linker stage:
g++-8 -L"/home/pedro/workspace/project/lib" -no-pie ...
It is not always about the compilation flags, I have the same error on gentoo when using distcc.
The reason is that on distcc server is using a not-hardened profile and on client the profile is hardened. Check this discussion:
https://forums.gentoo.org/viewtopic-p-7463994.html
Simply cleaning the project solved it for me.
My project is a C++ application (not a shared library). I randomly got this error after a lot of successful builds.
I had the same problem. Try recompiling using -fPIC flag.
I'm getting the same solution as #camino's comment on https://stackoverflow.com/a/19365454/10593190 and XavierStuvw's reply.
I got it to work (for installing ffmpeg) by simply reinstalling the whole thing from the beginning with all instances of $ ./configure replaced by $ ./configure --enable-shared (first make sure to delete all the folders and files including the .so files from the previous attempt).
Apparently this works because https://stackoverflow.com/a/13812368/10593190.
We had the same problem. It turned out to be a mix-up in a Makefile. The error occurred when the linker was gcc, but the C++ compiler clang++. Changing the linker to clang++ fixed it.