-fopenmp flag in compile and link - compilation

I have this openmp code
#include <omp.h>
#include <stdio.h>
int main()
{
#pragma omp parallel
{
fprintf(stderr, "thread %d\n", omp_get_thread_num());
}
return 0;
}
when I compile and link and use the -fopenmp
gcc-6 -std=c99 -Wall -Wextra -pedantic -fopenmp -Iinclude -c -o build/main.o src/main.c
gcc-6 -o bin/main build/main.o -fopenmp
the code work
$ ./bin/main
thread 0
thread 1
thread 2
thread 3
but don't when I only put the flag in the link
gcc-6 -std=c99 -Wall -Wextra -pedantic -Iinclude -c -o build/main.o src/main.c
src/main.c: In function 'main':
src/main.c:6:0: warning: ignoring #pragma omp parallel [-Wunknown-pragmas]
#pragma omp parallel
gcc-6 -o bin/main build/main.o -fopenmp
the code work but not in parallel
$ ./bin/main
thread 0
why I need add -fopenmp in compile and link time?

why I need add -fopenmp in compile and link time?
Because it is required both at compile time (to enable the #pragma omp handling) and at link time (to link required support libraries).

Related

How to use precompiled headers with gcc if linking against openmp

Minimal example:
// file: main.cpp
#include "pch.h"
int main()
{
std::cout << "test" << std::endl;
return 0;
}
--
// file: pch.h
#include <iostream>
Works fine and as expected if I compile this with
g++ pch.h
g++ main.cpp -Winvalid-pch
However once I change the last line to:
g++ main.cpp -fopenmp -Winvalid-pch
usage of the precompiled header is disabled:
warning: pch.h.gch: not used because `_REENTRANT' is defined [-Winvalid-pch]
How can I still use precompiled headers while linking to OpenMP? Why does the _REENTRANT define conflict with using a precompiled header at all?
You must generate .pch and compile sources with identical flags. -fopenmp implies #pragma omp and -pthread.
g++ -fopenmp pch.h
g++ main.cpp -fopenmp -Winvalid-pch
Or at least
g++ -pthread pch.h
g++ main.cpp -fopenmp -Winvalid-pch

How to get gcc LTO work with library archives?

gcc experts,
I'm trying to use gcc lto with library archives, as the gcc comes with my system (RedHat Enterprise Linux 5.7) doesn't work with -flto (neither for my Ubuntu 14.10), so I build binutils && gcc from scratch.
Here is what I did:
1. Build binutils-2.22 with --enable-plugins
2. Build gcc-4.7.2 with --with-plugin-ld=/path/to/ld/built/in/step1 --enable-lto
3. Then for the following simple test:
// 1.c:
int foo(void)
{ return 0; }
// 2.c:
extern int foo(void)
int main(void)
{ return foo(); }
The following can get foo() inlined:
my_gcc -O3 -flto -c -o 1.o 1.c
my_gcc -O3 -flto -c -o 2.o 2.c
my_gcc -O3 -flto -o a.out 1.o 2.o
While the following can't:
my_gcc -O3 -flto -c -o 1.o 1.c
my_gcc -O3 -flto -c -o 2.o 2.c
my_ar cr --plugin <my_gcc>/libexec/gcc/x86_64-redhat-linux/4.7.2/liblto_plugin.so 1.a 1.o
my_ar cr --plugin <my_gcc>/libexec/gcc/x86_64-redhat-linux/4.7.2/liblto_plugin.so 2.a 2.o
gcc -O3 -flto -fuse-linker-plugin -o a.out 1.a 2.a
As the building system for the product I'm working on has to use archives, then what I can do to let lto work with library archive?
Your help will be much much appreciated.
Thanks a lot.
When linking, the order in which the libraries are listed on the command line, matters. So when compiling from the archives, you should swap 1.a and 2.a:
gcc -O3 -flto -fuse-linker-plugin -o a.out 2.a 1.a
I tested with gcc 4.9.2 and the disassembly, obtained with objdump -d a.out, shows that foo() is being inlined.

Is it possible to turn "-Wwrite-strings" into an error?

I've tested this on GCC 4.8.3, 4.9.2 and trunk 20141210. When using -Werror=write-strings, it correctly enables the warning, but doesn't turn it into an error. The command line I'm using is:
g++ -std=c99 -x c -Werror=write-strings -O2 -Wall -pedantic main.cpp
warning: initialization discards 'const' qualifier from pointer target type
char *s = "test";
However, it turns it into an error in C++ mode:
g++ -Werror=write-strings -O2 -Wall -pedantic -pthread main.cpp
main.cpp:8:15: error: deprecated conversion from string constant to 'char*'
[-Werror=write-strings]
char *s = "test";
Is there something I'm missing or is this just a missing feature?
I've seen the deleted answer, but bear with me…it was actually correct (at least, under my testing). I think what you've found is interesting, and close to being a bug.
As far as my testing goes (GCC 4.9.1 built on Mac OS X 10.9.4 Mavericks, running on Mac OS X 10.10.2 Yosemite), it appears that the -Werror=write-strings does not make the warning into an error (which I regard as being probably a bug, though you may find that the GCC team has a different view on it). It only becomes an error when -Werror is in effect.
Here's what I ran:
$ cat x.c
#include <stdio.h>
int main(void)
{
char *test = "data";
printf("%s\n", test);
return 0;
}
$ gcc -O3 -g -std=c11 -c x.c
$ gcc -O3 -g -std=c11 -c x.c -Wwrite-strings
x.c: In function ‘main’:
x.c:5:18: warning: initialization discards ‘const’ qualifier from pointer target type
char *test = "data";
^
$ gcc -O3 -g -std=c11 -c x.c -Werror=write-strings
x.c: In function ‘main’:
x.c:5:18: warning: initialization discards ‘const’ qualifier from pointer target type
char *test = "data";
^
$ gcc -O3 -g -std=c11 -c x.c -Werror -Wwrite-strings
x.c: In function ‘main’:
x.c:5:18: error: initialization discards ‘const’ qualifier from pointer target type [-Werror]
char *test = "data";
^
cc1: all warnings being treated as errors
$ gcc -O3 -g -std=c11 -c x.c -Wall -Wextra -Werror=write-strings
x.c: In function ‘main’:
x.c:5:18: warning: initialization discards ‘const’ qualifier from pointer target type
char *test = "data";
^
$ gcc -O3 -g -std=c11 -c x.c -Wall -Wextra -Werror
$ gcc -O3 -g -std=c11 -c x.c -Wall -Wextra -Werror -Wwrite-strings
x.c: In function ‘main’:
x.c:5:18: error: initialization discards ‘const’ qualifier from pointer target type [-Werror]
char *test = "data";
^
cc1: all warnings being treated as errors
$ gcc -O3 -g -std=c11 -c x.c -Wall -Wextra -Werror -Werror=write-strings
x.c: In function ‘main’:
x.c:5:18: error: initialization discards ‘const’ qualifier from pointer target type [-Werror]
char *test = "data";
^
cc1: all warnings being treated as errors
$
For your convenience, and for easier viewing, these are the GCC commands I ran:
gcc -O3 -g -std=c11 -c x.c
gcc -O3 -g -std=c11 -c x.c -Wwrite-strings
gcc -O3 -g -std=c11 -c x.c -Werror=write-strings
gcc -O3 -g -std=c11 -c x.c -Werror -Wwrite-strings
gcc -O3 -g -std=c11 -c x.c -Wall -Wextra -Werror=write-strings
gcc -O3 -g -std=c11 -c x.c -Wall -Wextra -Werror
gcc -O3 -g -std=c11 -c x.c -Wall -Wextra -Werror -Wwrite-strings
gcc -O3 -g -std=c11 -c x.c -Wall -Wextra -Werror -Werror=write-strings
If you can't run with -Werror normally, then you're probably going to have to do trial builds with -Werror -Wwrite-strings which will fail because of other problems, but this will also identify the writable strings problems, which you can fix and check. Then, when you're OK on the -Wwrite-strings errors, you can go back to not including -Werror in the compilation (keeping -Wwrite-strings or even -Werror=write-strings in the command line so that if you make a mistake and/or the putative compiler bug is fixed, then you can have it all working the way you really wanted).

linking OpenMP statically with GCC

Given the following file print.cpp
#include <stdio.h>
int main() {
printf("asdf\n");
}
I can link this statically like this
g++ -static print.cpp
or like this
g++ -static-libgcc -Wl,-Bstatic -lc print.cpp -o print
But now let's add a little OpenMP and call the file print_omp.cpp
#include <omp.h>
#include <stdio.h>
int main() {
printf("%d\n", omp_get_num_threads());
}
I can link this statically like this (I checked it with ldd)
g++ -fopenmp -static print_omp.cpp
However, this does not work
g++ -fopenmp -static-libgcc -Wl,-Bstatic -lc print_omp.cpp -o print
I have tried various combinations of -Wl,--whole-archive -lpthread -Wl,--no-whole-archive and -lgomp -lpthread but no luck (I get various problems linking to pthreads). Can someone explain how I can do this without using the -static option?
GCC says
On glibc-based systems, OpenMP enabled applications cannot be statically linked due to limitations of the underlying pthreads-implementation
However, since g++ -fopenmp -static print_omp.cpp works just fine this does not make sense to me.
Edit:
I figured this out. The library GOMP comes with GCC whereas pthreads and libc come from GLIBC. So I can link GOMP statically like this
ln -s `g++ -print-file-name=libgomp.a`
g++ foo.cpp -static-libgcc -static-libstdc++ -L. -o foo -O3 -fopenmp
ldd shows
linux-vdso.so.1 => (0x00007fff71dbe000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc231923000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc23155c000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc231b5c000)
However, if I the try this
ln -s `g++ -print-file-name=libpthread.a`
g++ foo.cpp -static-libgcc -static-libstdc++ -L. -o foo -O3 -fopenmp
It won't link. Pthreads and libc must be linked statically together. So once I add
ln -s `g++ -print-file-name=libc.a`
g++ foo.cpp -static-libgcc -static-libstdc++ -L. -o foo -O3 -fopenmp
ldd returns
not a dynamic executable
I really don't get why you may want to link only libgomp statically, but having separate compilation and linking commands may help. For instance assume main.cpp contains:
#include <omp.h>
#include <stdio.h>
int main() {
#pragma omp parallel
{
printf("%d\n", omp_get_thread_num());
}
}
Then:
~/tmp$ ls
main.cpp
~/tmp$ g++ -Wall -Werror -pedantic -fopenmp main.cpp -c
~/tmp$ ls
main.cpp main.o
~/tmp$ locate libgomp.a
${SOME_PATH_TO_LIBGOMP}/libgomp.a
~/tmp$ g++ -Wall -Werror -pedantic main.o -o main.x ${SOME_PATH_TO_LIBGOMP}/libgomp.a -pthread
~/tmp$ ls
main.cpp main.o main.x
~/tmp$ ldd main.x
linux-gate.so.1 => (0xb7747000)
libstdc++.so.6 => /production/install/gnu/compiler/gcc/lib/libstdc++.so.6 (0xb765c000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb75fa000)
libgcc_s.so.1 => /production/install/gnu/compiler/gcc/lib/libgcc_s.so.1 (0xb75de000)
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb75c2000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7413000)
/lib/ld-linux.so.2 (0xb7748000)
The most clean solution I've found for this is by modifying the libgomp.spec. Mine is at /usr/local/lib64/libgomp.spec. Change the content as follow:
*link_gomp: -l:libgomp.a %{static: -ldl }

enforing check about returning a value in gcc

I am compiling some C/C++ files using gcc.
I noticed today a bug that caused my app to crash. It was caused by the fact that my function didn't return any value (see below). Do you know if there is some flag in gcc enforcing these kind of checking or why the compiler is not warning me about this?
I am compiling C files into object files with a basic -g -D_GNU_SOURCE -o outObjectFile -c myFile.c option.
//.c file
int
myFunc(){
...do something
..without return statement
}
//.h file
extern int myFun();
When using GCC, always compile with:
-std=c99 -pedantic -Wall -Wextra -Wwrite-strings for C
-ansi -pedantic -Wall -Wextra -Weffc++ for C++

Resources