I was trying to compile some multithreading code on different gcc versions on travis-ci. The versions that were used for the build were: g++ 4.8 and g++ 4.9. The code would refuse to compile without -lpthread on both versions. On adding the -lpthread flag however, they would compile, but when run, the g++ 4.8 code just crashed, while g++ 4.9 seemed to have build the right compilation. Now, when I changed the flag to -pthread on both compilers, both built correctly. I understand, -lpthread links with the C-style thread library, while -pthread causes the compiler to link the correct library, which 'might' not be the C-style thread library. Am I correct? Here's the link to the two build-logs: gcc 4.8 and gcc 4.9.
Related
I am currently trying to use Oracle Linux 6 OS on a SPARC S7 server to run the NPB benchmarks (with OpenMP multithreading support). The OS comes preloaded with gcc 4.4.7, which is missing the Niagara 7 optimizations. I downloaded devtoolset-3 from the Oracle Yum Repository, which has gcc 4.9.2 installed in /opt/rh/devtoolset-3/root/usr/bin. However, when I compile the NPB benchmark using the newer gcc, it automatically links to libraries associated with the older gcc 4.4.7 (located in /usr/lib). This caused my program to segfault during execution. I believe that it is because libgomp 4.4.7 is incompatible with libgomp 4.9.2. I have tried several ways of linking to the libraries in the gcc 4.9.2 folder (which is /opt/rh/devtoolset-3/root/usr/lib/gcc); none of the methods work:
-Xlinker -rpath=lib_location
-Wl -Bstatic
-L lib_location
The closest I got was when using -Wl -Bstatic ~/libgomp.a or -static -L ~/libgomp.a. It fails to find libraries such as libm that reside in the default gcc lib folder (usr/lib).
The actual command used to link is:
/opt/rh/devtoolset-3/root/usr/bin/gcc -O3 -fopenmp -mcmodel=medmid -static -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2 -o ../bin/bt.W.x bt.o initialize.o exact_solution.o exact_rhs.o set_constants.o adi.o rhs.o x_solve.o y_solve.o solve_subs.o z_solve.o add.o error.o verify.o ../common/print_results.o ../common/c_timers.o ../common/wtime.o -lm -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2/lib/
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lm
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lrt
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lpthread
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lc
Is there a way I can link just the libgomp library from gcc 4.9.2 while linking the remaining libraries from gcc 4.4.7?
The devtoolset compilers are all using the system libgcc, libstdc++, version 4.4.7, and can therefore not compile e.g. c++11.
I guess the gcc53-c++-5.3.0-1.el6.x86_64.rpm will do. Comes with the internal */gcc53/lib64{libgcc_s.so**, libgomp.so**, libstdc++} (version 5.3.0) ... Provides /usr/bin/{ gcc53, g++53 }
The package was created a year ago ... well tested, as extra compiler. Download link : https://drive.google.com/file/d/0B7S255p3kFXNbTBneHgwSzBodFE/view?usp=sharing
If you're going to do the -Wl,-Bstatic thing, make sure to follow it immediately by -Wl,-Bdynamic to reset to normal after your added library argument. By default, not all system libraries have static versions installed, which is why you get e.g. cannot find -lc.
So you can try this as a modification of your workaround:
-Wl,-Bstatic ~/libgomp.a -Wl,-Bdynamic
Not pretty, and this question deserves a much better answer (this is still pretty much a hack), but it should get the job done for now.
I built and installed llvm/clang-3.7 from source on my Ubuntu Linux system (I'm building from source because my development environment at work does not have apt-get available). The gcc version is 4.8.2. I followed the clang build instructions at http://clang.llvm.org/get_started.html, and everything worked fine (mkdir build; cd build; cmake -G "Unix Makefiles" ../llvm; make; make install). However, I'm now finding that a program to test Block_copy fails to compile. The program is auto-generated by autoconf when I try to build gnustep-base. The part that fails is:
int
main ()
{
return _Block_copy ();
;
return 0;
}
My compile command is:
clang -o conftest -m64 -march=opteron -mno-3dnow -ggdb -O2 -Wall -I/home/build/GNUstep/Local/Library/Headers -I/home/build/GNUstep/Local/Library/Headers -I/home/build/GNUstep/System/Library/Headers -fgnu-runtime -x objective-c -m64 -L/home/build/GNUstep/Local/Library/Libraries -L/home/build/GNUstep/Local/Library/Libraries -L/home/build/GNUstep/System/Library/Libraries conftest.c -lrt -ldl -lpthread -rdynamic -m64 -fgnu-runtime -L/home/build/GNUstep/Library/Libraries -L/home/build/GNUstep/Local/Library/Libraries -L/home/build/GNUstep/System/Library/Libraries -lobjc -lm
Do I need to build clang with a special option to enable blocks, or should I be linking with another library?
Do I need to build clang with a special option to enable blocks
No. But you may need -fblocks option using the clang binary.
-fblocks
Enable the "Blocks" language feature.
should I be linking with another library?
AFAIK, Yes.
_Block_copy is a part of BlocksRuntime.
BlocksRuntime Block.h
BlocksRuntime runtime.c
Have you compiled compiler-rt? It includes BlocksRuntime. The document explains how to build compiler-rt.
my program compiled and worked fine with:
g++ main.cpp exm1.cpp exm2.cpp -o main.o
i want to compile this app and run anywhere
how can i?
i try this code
g++ -g -Wall -I/MyApp/lib -static-libgcc -static-libstdc++ -static main.cpp exm1.cpp exm2.cpp -o main.o
but not work
in lib folder has 2 files:
exm1.h
exm2.h
main.cpp included:
#include <fstream>
#include <iostream>
#include <string>
#include <streambuf>
#include <stdlib.h>
#include "lib/exm1.h"
#include "lib/exm2.h"
my linux is kali, and i want run this app on CentOS 6
please help me,thanks
As C. bear said, use the -m32 flag so the program is able to run on 64- and 32- bit systems. In doing this, You'll also have to install the 32bit stdlibs. I'm not sure how to do this on kali, give it a google. Another thing you can do to avoid having users install external libraries (if you use them at any point) is to statically link you executable. Use the -static flag to do this. However, because all your app's dependencies (including the stdlibs) will be in a single file, it will get pretty big. On the other hand, loading times will be better, because your app doesn't have to run the dynamic linker and wait for it to link your external libraries as you call them.
So from comments one reason could be you executable is 64-bit and centOS a 32-bit sytem. Try compilation with -m32 flag.
how to compile g++ app and run anywhere?
It is not easily possible. For example, an ELF executable produced by GCC on a recent Debian/x86-64 computer won't run on a RaspberryPi (with a linux for ARM 32 bits, e.g. some Raspbian)
Read more about execve(2), elf(5) and about fat binaries
Be aware that the GCC compiler suite can be built (from its source code) as a cross-compiler (but you'll need to rebuild GCC for every different target system).
I recommend to invoke GCC as g++ -Wall -Wextra -g during the debugging phase (and use GDB). Once your software is debugged, compile it with g++ -Wall -Wextra -O2 to get an optimized binary (or even compile and link it with g++ -Wall -Wextra -O3 -flto)
How can I get GCC to use that static library instead of the dynamic one? Normally you add the .a file to the linker parameters. But libssp linking is triggered by the -fstack-protector option. And compiler prefers linking to the shared library if it finds one instead of static library.
If I try to run the resulting program on systems that don't have the libssp.so the program won't run.
(After system upgrade on some build machines, the older boxes on the test system screwed up)
Does
gcc -static static.c -o static -fstack-protector-all
or
gcc -static -lssp static.c -o static -fstack-protector-all
work? Can you run ldd on the resulting binaries?
What version of gcc are you using?
On Linux (kernel 2.6.5) our build system calls gcc with -D_REENTRANT.
Is this still required when using pthreads?
How is it related to gcc -pthread option? I understand that I should use -pthread with pthreads, do I still need -D_REENTRANT?
On a side note, is there any difference that you know off between the usage of REENTRANT between gcc 3.3.3 and gcc 4.x.x ?
When I use -pthread gcc option I can see that _REENTRANT gets defined. Will omitting -D_REENTRANT from command line make any difference, for example could some objects be compiled without multithreaded support and then linked into binary that uses pthreads and will cause problems?
I assume it should be ok just to use: g++ -pthread
> echo | g++ -E -dM -c - > singlethreaded
> echo | g++ -pthread -E -dM -c - > multithreaded
> diff singlethreaded multithreaded
39a40
> #define _REENTRANT 1
We're compiling multiple static libraries and applications that link with the static libraries, both libraries and application use pthreads.
I believe it was required at some stage in the past but want to know if it is still required. Googling hasn't returned any recent information mentioning -D_REENTRANT with pthreads. Could you point me to links or references discussing the use in recent version of kernel/gcc/pthread?
Clarification: At the moment we're using -D_REENTRANT and -lpthread, I assume I can replace them with just g++ -pthread, looking at man gcc it sets the flags for both preprocessor and linker. Any thoughts?
For me the best answer was the comment from pts if only he bothered to submit it as answer:
You investigated properly and answered
your own question. Use g++ -pthread,
it is equivalent to g++ -lpthread -D_REENTRANT.
Using g++ -D_REENTRANT would be different,
it may not set all the linker flags. –
pts May 18 at 0:30
From the gcc info pages:
`-pthread'
Adds support for multithreading with the "pthreads" library. This
option sets flags for both the preprocessor and linker.
So just the -pthread flag should be sufficient. I wouldn't recommend only passing it to some of your code, however.
As Chris suggested in the comments, using gcc -dumpspecs on Linux does indeed confirm that it sets preprocessor flags as well:
%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}
gcc's -pthreads flag sets the relevant compiler and linker flags necessary for pthreads support on the platform you're on.
You're right, on linux x86 (and probably many other platforms), that's equivalent to '-D_REENTRANT -lpthread' but that's not necessarily true on all platforms.
(For at least some time, on aix, -pthread caused g++ to link in a completely different libstdc++.a. I don't know if that's still the case now, though...)