I am compiling a third-part software, with mpif90, that in my case is the mpi version of gcc. The package comes with a makefile. After compiling the object files, the makefile creates the archive with ar, but this fails because there are not input object files. In effect I tried to compile by hand the object files (.o) with
mpif90 -lmkl_gf -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm -openmp -O3 -DMPI -c a.f90
and the a.o is not created, a .mod file is created instead. I don't have much experience with fortran, and I am a bit puzzled, because the -c flag should create an object, shouldn' it?
I have verified that gfortran does create the object file if I remove the flag openmp
Notes:
mpif90 -v
gcc version 4.4.3
OS : Ubuntu 10.04.4 LTS
I changed the flag openmp to fopenmp
http://gcc.gnu.org/onlinedocs/gfortran/OpenMP.html
In case anyone comes across this question in the future ... the flags used by the OP are specific to the intel fortran compiler while it seems the mpif90 wrapper is using the gfortran compiler. The proper flag to use OpenMP with gfortran is -fopenmp and the library is -lgomp. It is possible to use the intel library with a different vendors compiler, but its easiest to stick with one vendor.
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
One of my users is getting an error message when trying to compile a C part of our mixed C/C++ codebase on ubuntu 12.04 with gcc 4.8.1
We have a library in C++ with some C-linkage functions in, and want to compile a C program linking to it. The library is compiled with g++ and builds fine. The c program fails like this:
> gcc -O3 -g -fPIC -I/media/Repo/lcdm/code/cosmosis/ -Wall -Wextra -pedantic -Werror -std=c99 -o c_datablock_t c_datablock_test.c -L . -lcosmosis
cc1plus: error: command line option ‘-std=c99’ is valid for C/ObjC but not for C++ [-Werror]
The program has a lower case .c file suffix, so why does gcc try to compile it as c++ ? We have not seen this on other OSes.
(I know we could kick the problem down the road by removing -Werror or handle this particular file with -x c but I'd like to solve the real problem.)
why does gcc try to compile it as c++
I can think of only two plausible explanations, and they both are end-user's fault.
It could be that the user transferred sources via Windows, and the file is really called C_DATABLOCK_TEST.C, and the user is misleading you.
It could also be that the user overwrote his gcc with g++ (surprisingly many people believe that gcc and g++ are the same thing, but they are not).
To disprove the first possibility, ask the user to execute his build commands under script, and send you resulting typescript.
To disprove the second, ask the user to add -v to the compile command.
This look like GCC Bug 54641, which has been fixed in a later release of GCC. It is only a warning, but your compile flags are causing GCC to treat all warnings as errors.
For a test I have written a code of matrix multiplication in C(cuda) and compiled it using nvcc to create shared library using following command.
nvcc -c MatMul.cu -o libmatmul.so
Then i wrote a OpenCV code in C and tried to compile with following command.
gcc ImgMul.c `pkg-config --cflags --libs opencv` -L. -L/usr/local/cuda/lib64 -I/usr/local/cuda/include -I. -lmatmul -lcudart -o ImgMul
and I am getting following error.
gputest.c:(.text+0x3f): undefined reference to `matmul'
Could anyone tell me how to include cuda libraries while compiling a code in gcc.
OS: Ubuntu
gcc : 4.4.0
The first point to make is that
nvcc -c MatMul.cu -o libmatmul.so
does not make a shared library, it just compiles to an object file. Shared libraries and object files are not at all the same thing.
That aside, the reason for the symbol not found error is C++ name mangling. Host code in CUDA source files is compiled using the host C++ compiler, not C. So symbol names in the host code emitted by the compiler are subject to name mangling. To get around this, the easiest way is to declare functions which you wish to call from plain C code using the extern "C" declarator (see here for a reasonable overview of the perils of C/C++ interoperability).
I've installed GCC 3.4 to /opt/gcc-3.4, and I'm using it to compile legacy code which is incompatible with GCC 4. This also means old versions of the C(++) standard libraries, binutils, and utility libraries.
It works fine for some libraries, but fails when compiling libtiff, because it picks up the system libraries in /usr/lib (see output below). This might be an autotools/configure issue, but I'm not sure. I can't find a configure switch or environment variable, and I'd rather not modify my system /usr/lib/libc.so .
So how to make sure it links to the standard library in /opt/gcc-3.4.4/lib, and ignores /lib and /usr/lib completely?
Output of make (excerpt):
libtool: link: g++ -shared -nostdlib /usr/lib/crti.o /opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3/crtbeginS.o .libs/tif_stream.o -Wl,--whole-archive ../port/.libs/libport.a -Wl,--no-whole-archive -Wl,-rpath -Wl,/home/jason/d0src34/prereq/tiff-3.9.4/libtiff/.libs -Wl,-rpath -Wl,/opt/gcc-3.4.3/lib -Wl,-rpath -Wl,/home/jason/d0src34/prereq/usr/lib -Wl,-rpath -Wl,/opt/gcc-3.4.3/lib ../libtiff/.libs/libtiff.so -L/usr/lib /usr/lib/libjpeg.so -lz -L/opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3 -L/opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3/../../.. /opt/gcc-3.4.3/lib/libstdc++.so -L/home/jason/Downloads/gcc-3.4.3/build/i686-pc-linux-gnu/libstdc++-v3/src -L/home/jason/Downloads/gcc-3.4.3/build/i686-pc-linux-gnu/libstdc++-v3/src/.libs -L/home/jason/Downloads/gcc-3.4.3/build/gcc -lm -lc -lgcc_s /opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3/crtendS.o /usr/lib/crtn.o -Wl,-soname -Wl,libtiffxx.so.3 -o .libs/libtiffxx.so.3.9.4
/home/jason/d0src34/prereq/usr/bin/ld:/usr/lib/libc.so: file format not recognized; treating as linker script
/home/jason/d0src34/prereq/usr/bin/ld:/usr/lib/libc.so:5: parse error
I've found a (hackish) answer to my own question:
I've been using binutils 2.15, because later versions have an incompatibility with GCC 3.4. In more recent versions, the format of /usr/lib/libc.so has changed, and the old binutils can't parse it.
I temporarily commented out the last line (with "GROUP"), and my code compiled:
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
/* GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.2 ) ) */
However, I'm not really satisfied, since I can hardly tell other people who want to use the code to edit their system files. Also, I'm not sure if I've linked it to the correct glibc version, since the system /usr/lib is still in the search path, so I can't tell for sure if the binaries will work on other systems.
I am trying to write a matlab mex function which uses libhdf5; My Linux install provides libhdf5-1.8 shared libraries and headers. However, my version of Matlab, r2007b, provides a libhdf5.so from the 1.6 release. (Matlab .mat files bootstrap hdf5, evidently). When I compile the mex, it segfaults in Matlab. If I downgrade my version of libhdf5 to 1.6 (not a long-term option), the code compiles and runs fine.
question: how do I solve this problem? how do I tell the mex compilation process to link against /usr/lib64/libhdf5.so.6 instead of /opt/matlab/bin/glnxa64/libhdf5.so.0 ? When I try to do this using -Wl,-rpath-link,/usr/lib64 in my compilation, I get errors like:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../x86_64-pc-linux-gnu/bin/ld: warning: libhdf5.so.0, needed by /opt/matlab/matlab75/bin/glnxa64/libmat.so, may conflict with libhdf5.so.6
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
mex: link of 'hdf5_read_strings.mexa64' failed.
make: *** [hdf5_read_strings.mexa64] Error 1
ack. the last resort would be to download a local copy of the hdf5-1.6.5 headers and be done with it, but this is not future proof (a Matlab version upgrade is in my future.). any ideas?
EDIT: per Ramashalanka's excellent suggestions, I
A) called mex -v to get the 3 gcc commands; the last is the linker command;
B) called that linker command with a -v to get the collect command;
C) called that collect2 -v -t and the rest of the flags.
The relevant parts of my output:
/usr/bin/ld: mode elf_x86_64
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/crtbeginS.o
hdf5_read_strings.o
mexversion.o
-lmx (/opt/matlab/matlab75/bin/glnxa64/libmx.so)
-lmex (/opt/matlab/matlab75/bin/glnxa64/libmex.so)
-lhdf5 (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/libhdf5.so)
/lib64/libz.so
-lm (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/libm.so)
-lstdc++ (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libstdc++.so)
-lgcc_s (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libgcc_s.so)
/lib64/libpthread.so.0
/lib64/libc.so.6
/lib64/ld-linux-x86-64.so.2
-lgcc_s (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libgcc_s.so)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/crtendS.o
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crtn.o
So, in fact the libhdf5.so from /usr/lib64 is being referenced. However, this is being overriden, I believe, by the environment variable LD_LIBRARY_PATH, which my version of Matlab automagically sets at run-time so it can locate its own versions of e.g. libmex.so, etc.
I am thinking that the crt_file.c example works either b/c it does not use the functions I am using (H5DOpen, which had a signature change in the move from 1.6 to 1.8 (yes, I am using -DH5_USE_16_API)), or, less likely, b/c it does not hit the parts of Matlab internals that need hdf5. ack.
The following worked on my system:
Install hdf5 version 1.8.4 (you've already done this: I installed the source and compiled to ensure it is compatible with my system, that I get gcc versions and that I get the static libraries - e.g. the binaries offered for my system are icc specific).
Make a target file. You already have your own file. I used the simple h5_crtfile.c from here (a good idea to start with this simple file first a look for warnings). I changed main to mexFunction with the usual args and included mex.h.
Specify the static 1.8.4 library you want to load explicitly (the full path with no -L for it necessary) and don't include -lhdf5 in the LDFLAGS. Include a -t option so you can ensure that there is no dynamic hdf5 library being loaded. You also need -lz, with zlib installed. For darwin we also need a -bundle in LDFLAGS:
mex CFLAGS='-I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -bundle' h5_crtfile.c -v
For linux, you need an equivalent position-independent call, e.g. fPIC and maybe -shared, but I don't have a linux system with a matlab license, so I can't check:
mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v
Run the h5_crtfile mex file. This runs without problems on my machine. It just does a H5Fcreate and H5Fclose to create "file.h5" in the current directory, and when I call file file.h5 I get file.h5: Hierarchical Data Format (version 5) data.
Note that if I include a -lhdf5 above in step 3, then matlab aborts when I try to run the executable (because it then uses matlab's dynamic libraries which for me are version 1.6.5), so this is definitely solving the problem on my system.
Thanks for the question. My solution above is definitely much easier for me than what I was doing before. Hopefully the above works for you.
I am accepting Ramashalanka's answer because it led me to the exact solution which I will post here for completeness only:
download the hdf5-1.6.5 library from the hdf5 website, and install the header files in a local directory;
tell mex to look for "hdf5.h" in this local directory, rather than in the standard location (e.g. /usr/include.)
tell mex to compile my code and the shared object library provided by matlab, and do not use the -ldfh5 flag in LDFLAGS.
the command I used is, essentially:
/opt/matlab/matlab_default/bin/mex -v CC#gcc CXX#g++ CFLAGS#"-Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include" CXXFLAGS#"-Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include " -O -lmwblas -largeArrayDims -L/usr/lib64 hdf5_read_strings.c /opt/matlab/matlab_default/bin/glnxa64/libhdf5.so.0
this gets translated by mex into the commands:
gcc -c -I/opt/matlab/matlab75/extern/include -DMATLAB_MEX_FILE -Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include -O -DNDEBUG hdf5_read_strings.c
gcc -c -I/opt/matlab/matlab75/extern/include -DMATLAB_MEX_FILE -Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include -O -DNDEBUG /opt/matlab/matlab75/extern/src/mexversion.c
gcc -O -pthread -shared -Wl,--version-script,/opt/matlab/matlab75/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -o hdf5_read_strings.mexa64 hdf5_read_strings.o mexversion.o -lmwblas -L/usr/lib64 /opt/matlab/matlab_default/bin/glnxa64/libhdf5.so.0 -Wl,-rpath-link,/opt/matlab/matlab_default/bin/glnxa64 -L/opt/matlab/matlab_default/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++
this solution should work on all my various target machines and at least until I upgrade to matlab r2009a, which I believe uses hdf5-1.8. thanks for all the help, sorry for being so dense with this--I think I was overly-committed to using the packaged version of hdf5, rather than a local set of header files.
Note this would all have been trivial if Mathworks had provided a set of the header files with the Matlab distribution...