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...)
Related
Does the gcc's option -static affect only one library that follows immediately or does it affect all libraries provided on command line?
g++ -static -lutils1 -lutils2
GGC's -static linkage option prevents linkage with shared libraries. So
all libraries that the linkage requires must be static. The
linker must be able to find a static library to resolve all -lname options that
are passed, as well as static versions of all default libraries that GCC silently
appends to the linkage.
That is the intended use of the -static option, although it is possible to make it more flexible.
GCC's -static option works simply by causing GCC to pass the option -static|-Bstatic to the linker (ld), at
a position in the generated ld commandline that precedes all the libraries in
the linkage.
The linker's -static option has a different meaning from GCC's. From the ld manual:
-Bstatic
-dn
-non_shared
-static
Do not link against shared libraries. This is only meaningful on platforms for which shared libraries are supported.
he different variants of this option are for compatibility with various systems.
You may use this option multiple times on the command line: it affects library searching for -l options which follow it.
(My emphasis)
So the linker's -static|-Bstatic option means: Do not link any shared libraries until further notice. At a later
point in the ld commandline you may cancel the effect of -static|-BStatic with the option -Bdynamic, which
will allow dynamic libraries to be linked again, from that point on, until further notice.
Unlike the linker, GCC has no option that cancels the effect of its -static option. However, GCC allows you to pass abitrary options through to ld, via -Wl,<ld-options>.
So you can in fact cancel GCC's -static option at a later point in the commandline like this:
gcc -static -o prog main.o -lfoo -lbar -Wl,-Bdynamic -lgum ...
This will generate a linkage commandline in which -lfoo and -lbar must be resolved to
static libraries but -lgum and any subsequent library can be resolved to
a shared library or a static library, as usual. Though if you wanted to "turn on/turn off"
dynamic linkage like this at different points in the commandline, it would be more
natural not to use GCC's -static option and instead write the equivalent:
gcc -o prog main.o -Wl,-Bstatic -lfoo -lbar -Wl,-Bdynamic -lgum ...
I have 3 classes - I denote those by firstClass,secondClass,thirdClass.
My headers - firstClass.h, secondClass.h, thirdClass.h and sources firstClass.cpp, secondClass.cpp, thirdClass.cpp.
In class thirdClass I create instance of firstClass and two instance of secondClass.
In main.cpp I deamonize and create instance thirdClass.
I want to create static library of thirdclass and linking to main.cpp.
firstClass and thirdClass used the same library libm.a
I created library step by step as following:
g++ -c -I-/usr/include/ -I-/usr/lib/ -I-/home/projects/Learninig firstClass.cpp -lstdc++ -lm-o WsChannel.o -w -m32
g++ -c -I-/usr/include/ -I-/usr/lib/ --I-/home/projects/Learninig secondClass -lstdc++ -o secondClass.o -w -m32
g++ -c -I-/usr/include/ -I-/usr/lib/ --I-/home/projects/Learninig thirdClass.cpp -lstdc++ -lm -o thirdClass.o -w -m32
ar rcs libLearning.a firstClass.o secondClass.o thirdClass.o
g++ main.cpp -L. -lLearning -lm -o MnLearning.o -m32
Compiling was maked correctly without any errors, but when I execute program I have same error. I spent some hours on checking code, but I don't find bugs. So then maybe compiling was incorrect. I did this using some tutorial in web.
If whatever was unclearly I am ready to more explain my question.
Edit: My error:
segfault at 557400000045 ip 00005574bd509dcd sp 00007ffd9e887900 error 4 in MnLearning[5574bd4f2000+26000]
The error is surely inside your own source code. Avoid undefined behavior in it, and be scared of UB.
Your use of -I- is strange, and probably wrong. I recommend removing it (and also, at first, remove the -m32 flag if your computer and distribution is 64 bits; work first to have your program run correctly on your laptop, then port it later to 32 bits Linux by adding the -m32 flag). You might use preprocessor options like -H to be shown what files are included.
I recommend building your library and your program with some build automation tool, such as GNU make or ninja.
Configure your build to compile with all warnings and debug info, i.e. using g++ -Wall -Wextra -g with GCC. Improve your source code to get no warnings. Then use the gdb debugger to understand the behavior of your program (and library).
So then maybe compiling was incorrect.
No, the compiler is probably good, and you should trust it.
The bug is very likely to be in your own code.
My error: segfault at 557400000045 ip 00005574bd509dcd sp 00007ffd9e887900 error 4 in MnLearning[5574bd4f2000+26000]
Segmentation fault is a symptom of some error in your own code (e.g. some buffer overflow, some bad pointer dereference, etc; or other kind of UB).
You might also use valgrind.
I spent some hours on checking code, but I don't find bugs.
You did not spend enough time (some bugs may take you weeks of work to be found), and you forgot to use the debugger, a very handy tool to help you understand the behavior of your program and find bugs in it. Be aware that programming is difficult, and don't be discouraged.
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 am very strange about the toolchains, arm-eabi-gcc, arm-linux-gcc, and arm-elf-gcc.
For arm-linux-gcc and arm-elf-gcc, in my opinion, just used the different the libc.
But what's the difference between arm-eabi-gcc and arm-linux-gcc ?
i regard that arm-eabi-gcc dont built in the libc. Am i right ?
if not, could you help to correct me ?
And also why uboot used arm-linux-gcc for the default arm cross compiler ?
As i know, the uboot dont need that libc for dependency.
so that is my problem.
thx!
It's called the target alias or the target-triplet of the toolchain what it's for, basically, is to identify that toolchain from other toolchains and from the native one you have. It tells you what architecture, ABI and target host the toolchain is built for, example:
arm-none-gnueabi: bare metal (no operating system) gnu ABI
arm-linux-eabi: produces binaries for a hosted system (running a Linux environment)
The GCC compiler *gcc is a driver program running other programs. So run
arm-linux-gcc -v -O -Wall helloworld.c -o hellworld-linux-gcc
arm-elf-gcc -v -O -Wall helloworld.c -o hellworld-elf-gcc
arm-eabi-gcc -v -O -Wall helloworld.c -o helloworld-eabi-gcc
and you'll understand the differences. They probably all run some cc1 program doing the translation to assembly code, some as program doing the assembling of assembler code to object code, some ld program doing the linking with some standard libraries. They may also run some collect2 wrapping some linking etc etc.
You may also want to run simply arm-linux-gcc -v or arm-elf-gcc -v or arm-eabi-gcc -v to understand how your compilers have been configured, and their precise version.
I am trying to cross-compile linux for an ARM architecture.
The host is an X86 machine running ubuntu-jaunty. I downloaded a cross-compile toolchain for ARM from http://ftp.arm.linux.org.uk/pub/armlinux/toolchain/. I downloaded the 2.95.3 version of the toolchain.
The problem I am having is that GCC is passing in some default flags by itself that is causing GCC to then output error:
/usr/local/arm/2.95.3/bin/arm-linux-gcc -specs=/home/feroze/wnr834m/marvell_WNR834M/gcc_specs -D__KERNEL__ -I/home/feroze/wnr834m/marvell_WNR834M/linux-88fxx81-1_1_3_gtk/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -DLED_DUAL_COLOR -DFOR_ROUTER -I/home/feroze/wnr834m/marvell_WNR834M/linux-88fxx81-1_1_3_gtk/arch/arm/mach-mv88fxx81/Soc/gpp/ -Uarm -fno-common -pipe -mapcs-32 -D__LINUX_ARM_ARCH__=5 -march=armv5 -mtune=arm9tdmi -mshort-load-bytes -msoft-float -Uarm -march=strongarm -DKBUILD_BASENAME=main -c -o init/main.o init/main.c
cc1: bad value (strongarm) for -march= switch
make[1]: *** [init/main.o] Error 1
make[1]: Leaving directory `/home/feroze/wnr834m/marvell_WNR834M/linux-88fxx81-1_1_3_gtk'
I checked the whole makefile, and could not find any place where LINUX_ARM_ARCH_5 and -march=armv5 are being defined. I am defining -march=strongarm in the makefile, but then it gets appended by theh ARMv5 defines.
So, I created a defs file from gcc, modified it to only have options for ARMv4, and then used it by specifying the -specs= option. However, that still doesnt solve the problem.
Can somemone help? How do I resolve this?
Thanks!
feroze
The -march flag is set in arch/ARM/Makefile, and depends on the machine you selected in your config file. If you don't want the armv5 flag, be sure to select the correct architecture in the config file.
You should assume the kernel appended CFLAGS are right (provided your config is ok) and if your toolchain does not support one of them, then you have no choice but to cross compile a toolchain by yourself, using the original crosstol script that should work with 2.95.3
Edit : original answer
What are you trying to build ?
a 2.95.3 toolchain is fairly ancient. You should try a more recent toolchain. You can find a precompiled one here
Pick the EABI one to start.
This is not a direct answer to your problem, but if you are building the linux kernel, you should not need to mess with the Makefiles. You will get more help if you can get a more "standard" toolchain.
This won't strictly help you eliminate the issue, but you can do gcc -dM -E <empty_file.c> or gcc -dM -E -x c /dev/null to print out a listing of all the predefined #defines for gcc. Combine -dM with another flag like your -march and you might be able to track down what's causing your #define issue.
Be sure to check your environment variables, as they can persuade make to do unexpected things.
If the Makefile includes another file, it could be modifying CFLAGS before CC is called. Can you print the contents of CFLAGS just before the CC call?