I having a hell of a time tracking down documentation for all of the gcc options. I'm on an ubuntu machine so not even sure if this is relevant to me.
Comes from this make rule:
my-server: my-server.c
$(CC) -Wall -pthread my-server.c -o my-server
I've found this option summary:
https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Option-Summary.html
From man gcc
-pthread
Add support for multithreading using the POSIX threads library. This option sets flags for both the preprocessor and linker. It does not affect the thread safety of object code produced by the compiler or that of libraries supplied with it. These are HP-UX specific flags.
Note that it differs from -lpthread. The -lpthread option doesn't set the preprocessor flags. For instance, the macros _REENTRANT and __USE_REENTRANT, etc.
In the documentation for GCC (6.2.0), it is treated as a platform-specific option. For RS6000 and PowerPC, it says:
-pthread.
Adds support for multithreading with the pthreads library. This option sets flags for both the preprocessor and linker.
For Solaris 2, it says:
-pthreads.
Add support for multithreading using the POSIX threads library. This option sets flags for both the preprocessor and linker. This option does not affect the thread safety of object code produced by the compiler or that of libraries supplied with it.
-pthread.
This is a synonym for -pthreads.
The common 'thread' (sorry — couldn't resist) is that it ensures that the code is compiled and linked with options that ensure that the POSIX threads library is used. The same will be true on other platforms where the option works (Linux, macOS Sierra, Mac OS X before it, …) it will link with the right library and enable any relevant preprocessor options.
You could compare the output of:
gcc -v -pthread -o x1 pthread-prog.c
gcc -v. -o x2 pthread-prog.c
to see what differences the -pthread option makes. On macOS Sierra, it adds -D_REENTRANT to the cc1 phase, and -pthread to the 'COLLECT_GCC_OPTIONS' setting.
Related
I'm using the Windows version of Clang (LLVM) 8 under Windows.
I'm compiling a code which uses OpenMP.
Under the lib folder of Clang there are 2 files which are OpenMP related:
libomp.lib.
libiomp5md.dll.
My questions are:
When I compile the code I use the flags -Xclang -fopenmp for the compiler. In in GCC and ICC using the flags tell the compiler to link the OpenMP library automatically. What about Clang? Does it do it automatically or must I link with libomp.lib manually? Is there a way to trigger automatic linking to the OpenMP library?
Answer: This was answered in Michael Klemm's answer below - Use the clang driver both for compiling and linking and then the -fopenmp will work as in GCC.
When I link with libomp.lib manually (Defining as a library for the linker) the output exe requires libomp.dll while the supplied OpenMP Dynamic Library is libiomp5md.dll. Is that a bug or is it because I link manually?
Answer: The libomp.dll is supplied in the bin folder and not the lib folder.
What's the proper way to utilize OpenMP in Clang under Windows? The clang-cl driver doesn't work with /openmp or -openmp as the MSVC's cl compiler.
Answer: Currently it can be done either with clang -fopenmp ..., clang-cl -Xclang -fopenmp ... or clang-cl /clang:-fopenmp ... (Which is equivalent of -Xclang -fopenmp).
Remark
On Windows I use Windows Driver of Clang using clang-cl.
Adding clarity to what the OpenMP libraries actually are, and how to use them on Windows with clang-cl
libomp.dll and libiomp5md.dll ARE THE SAME FILES!
When compiling for Windows, you link against libomp.lib OR libiomp5md.lib which will link to the same-named DLL at runtime, i.e. libomp.dll OR libiomp5md.dll respectively.
If you load 2 files that use the "different-name DLL," the interpreter will crash and give you a nasty error like: OMP: Error #15: Initializing libiomp5md.dll, but found libomp.dll already initialized.
Why? Because the program has no idea they are the same DLL, they have different names, so it assumes they are different. And it crashes. For this reason only, you can choose to swap which OpenMP DLL you link to in your program.
If your program doesn't crash and give you an error, you can keep using the same link to OpenMP. Otherwise, to silence the error, link to the one that is loaded by another program already.
If using clang-cl.exe which is the "drop-in" Clang replacement for MSVC cl.exe you should pass a compiler argument such as -Xclang -fopenmp which will convert the argument over to "Clang language." Don't forget to still pass to the linker the OpenMP LIB you chose, because on Windows, it won't be automatic.
That's all I've learned as brief as possible about OpenMP linking on Windows.
To compile and link OpenMP code with clang on Windows, you will have to pass -fopenmp to both the compiler and the linker:
clang -fopenmp -o bla.obj -c bla.c
clang -fopenmp -o bla.exe bla.obj
I am currently porting my compiler from AIX XLC compiler to GCC compiler on AIX.
I want to know if there is an GCC equivalent compiler option available for the -qthreaded (XLC).
-pthread is the closest GCC option for use cases where -qthreaded is applied for XL; however, it is not equivalent to the -qthreaded option for IBM XL.
The GCC documentation for -pthread merely states that it sets macros (http://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-pthread) and modifies the link step (http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#index-pthread-1). -qthreaded does not cause _THREAD_SAFE to be defined as a macro, nor does it cause -lpthreads to be present in the link step. GCC's -pthread is more like XL's _r invocations (which does set the macro and modify the link step).
What -qthreaded does is to disable optimizations that are unsafe for multithreaded programs. It appears that, at least historically, -fno-tree-loop-if-convert-stores would at least partially be a GCC equivalent to -qthreaded.
Does anyone know if it is possible to compile MPI with gcc?. I need to use gcc, no mpicc.
mpicc is just a wrapper around certain set of compilers. Most implementations have their mpicc wrappers understand a special option like -showme (Open MPI) or -show (Open MPI, MPICH and derivates) that gives the full list of options that the wrapper passes on to the backend compiler.
For example, in Open MPI, wrappers are C++ programs that read plain text configuration files and build command line options that are further passed on to the compiler. mpicc -showme shows the full list of such options:
$ mpicc -showme
icc
-I/opt/MPI/openmpi-1.5.3/linux/intel/include
-I/opt/MPI/openmpi-1.5.3/linux/intel/include/openmpi
-fexceptions
-pthread
-I/opt/MPI/openmpi-1.5.3/linux/intel/lib
-Wl,-rpath,/opt/MPI/openmpi-1.5.3/linux/intel/lib
-I/opt/MPI/openmpi-1.5.3/linux/intel/lib
-L/opt/MPI/openmpi-1.5.3/linux/intel/lib
-lmpi
-ldl
-Wl,--export-dynamic
-lnsl
-lutil
(it's really a single line that I have split here to improve readability)
It that particular case Intel C Compiler icc is used as the backend compiler but we also have variants that use GCC. You can also get the list of options needed for the comple phase (usually known as CFLAGS) with mpicc -showme:compile:
$ mpicc -showme:compile
-I/opt/MPI/openmpi-1.5.3/linux/intel/include
-I/opt/MPI/openmpi-1.5.3/linux/intel/include/openmpi
-fexceptions
-pthread
-I/opt/MPI/openmpi-1.5.3/linux/intel/lib
as well as the list of options that you need to pass to the linker (known as LDFLAGS) with mpicc -showme:link:
$ mpicc -showme:link
-fexceptions
-pthread
-I/opt/MPI/openmpi-1.5.3/linux/intel/lib
-Wl,-rpath,/opt/MPI/openmpi-1.5.3/linux/intel/lib
-I/opt/MPI/openmpi-1.5.3/linux/intel/lib
-L/opt/MPI/openmpi-1.5.3/linux/intel/lib
-lmpi
-ldl
-Wl,--export-dynamic
-lnsl
-lutil
These could be used, e.g. in a Makefile, like this:
...
CFLAGS += $(shell mpicc -showme:compile)
LDFLAGS += $(shell mpicc -showme:link)
...
As far as I know -showme:compile and -showme:link are specific to Open MPI and other implementations only give the full list of options when called with -show.
I still think it's better to use mpicc directly because if it happens that something in the MPI setup is changed, it will be immediately reflected in the wrapper while you would have to change your build script / Makefile manually (unless you use -showme:compile and -showme:link to obtain the options automatically).
mpicc -compile_info for MPICH.
Yes, you can use gcc actually. But in my case (on Ubuntu) mpicc is just a wrapper of gcc, here is the output of command mpicc -showme:
gcc -I/usr/lib/openmpi/include/openmpi/opal/mca/event/libevent2021/libevent -I/usr/lib/openmpi/include/openmpi/opal/mca/event/libevent2021/libevent/include -I/usr/lib/openmpi/include -I/usr/lib/openmpi/include/openmpi -pthread -Wl,-rpath -Wl,/usr/lib/openmpi/lib -Wl,--enable-new-dtags -L/usr/lib/openmpi/lib -lmpi
While in Open MPI docs:
The Open MPI team strongly recommends that you simply use Open MPI's "wrapper" compilers to compile your MPI applications. That is, instead of using (for example) gcc to compile your program, use mpicc.
We repeat the above statement: the Open MPI Team strongly recommends that the use the wrapper compilers to compile and link MPI applications.
If you find yourself saying, "But I don't want to use wrapper compilers!", please humor us and try them. See if they work for you. Be sure to let us know if they do not work for you.
Many people base their "wrapper compilers suck!" mentality on bad behavior from poorly-implemented wrapper compilers in the mid-1990's. Things are much better these days; wrapper compilers can handle almost any situation, and are far more reliable than you attempting to hard-code the Open MPI-specific compiler and linker flags manually.
That being said, there are some -- very, very few -- situations where using wrapper compilers can be problematic -- such as nesting multiple wrapper compilers of multiple projects. Hence, Open MPI provides a workaround to find out what command line flags you need to compile MPI applications.
Here this answer is useful for you.
For MPICH, according to the mpicc man pages, mpicc -compile_info shows the flags for compiling a program, and mpicc -link_info shows the flags for linking a program.
Yes, you can certainly compile an MPI program without the convenience of the mpicc wrapper. On most implementations mpicc is a shell script (or similar) which sets environment variables, finds and links various libraries, all the sort of stuff that you might otherwise put into a Makefile.
I suggest that you find an instance of the mpicc script and deconstruct it.
mpicc is already using gcc as a backend
It is almost common knowledge that one should always compile with -Wall.
What other useful options are you using when compiling with gcc/g++?
You may want -Wextra in addition of -Wall.
When debugging your program, -g is needed by gdb.
and GCC accepts both -g and -O if you really want
At last, recent versions of GCC (i.e. 4.6 or the 4.7 snapshot) gives better warnings than older ones.
You could use -pedantic and restrict yourself to some standard, avoiding GNU extensions.
I love GNU extensions so I don't want to avoid them.
So I use -std=gnu99 for C code, and -std=gnu0x or -std=gnu11 for C++11 code because I like extensions.
And you might consider using or even developing a GCC plugin or a MELT extension for your own specific needs.
The code I'm working on is supposed to be possible to build for both hosted and freestanding environments, providing private implementations for some stdlib functions for the latter case.
Can I reliably test this with just GCC on a normal workstation/build server? Compile for freestanding environment with GCC
The "-ffreestanding" option looked promising, but it seems that it "only" disables built-ins and sets the STDC_HOSTED macro properly, it still provides all system headers.
The option "-nostdinc" is too restrictive; I still want to use the headers required for a freestanding implementation (in particular stddef.h and limits.h).
What am I missing here?
Oh, and I'm using GCC 4.4.3 for the moment, will upgrade to 4.5.0 "soon".
Well, since no answer is given yet I'd might as well describe how I made this work. It's pretty simple although depending on the target system it can be tedious.
Using "-nostdinc" means that the standard system include paths will be skipped; other include-paths given with "-I" will of course still be searched for headers.
So, for the freestanding build target I create a folder 'include-freestanding-c89' and link the relevant system headers -- float.h, iso646.h, limits.h, stdarg.h and stddef.h -- there. Other headers might be included in these, depending on your platform, so you might have to do some research and set up more links (hence the tediousness if you need to do this for several target platforms).
The C89 directory can then be used as base for 'include-freestanding-c99', the extra headers to link are stdbool.h and stdint.h
The command-line to use is then
gcc -std=c89 -nostdinc -nostdlib -ffreestanding -I include-freestanding-c89
or
gcc -std=c99 -nostdinc -nostdlib -ffreestanding -I include-freestanding-c99
This Xen Makefile uses gcc -print-search-dirs to get the directory with stddef.h and similar, adds it with -isystem, then uses -nostdinc to build:
https://github.com/mirage/xen/blob/2676bc915157ab474ee478d929b0928cf696b385/stubdom/Makefile#L35