MinGW linker can't find MPICH2 libraries - linker

MPICH2 is installed in C:\Program Files\MPICH2. There are two subdirectories (of interest), \include which contains .h files, and \lib which contains .lib files.
The readme that comes with MPICH2 has the following instructions:
create a makefile
add –I...mpich2\include
add –L...mpich2\lib
add –lmpi
add the rules for your source files
compile
Since there are no other rules in my project, I don't create a makefile, I just go to the command line and try compiling like this:
g++ -I"C:\Program Files\MPICH2\include" main.cpp -L"C:\Program Files\MPICH2\lib" -lmpi
This gives me a fistful of undefined reference errors on every single MPI symbol in the code. I spent hours trying to fix it, juggling -I, -L and -l switches around, shuffling the order of the parameters, even copied all the .lib files into the same directory as my source, but nothing seems to work.
What kind of voodoo is needed to get this thing to link?
EDIT: I think I found the problem: here's an excerpt of the linker's output in verbose mode (adding -Wl,--verbose to the compile command):
attempt to open C:\Program Files\MPICH2\lib/libmingwex.dll.a failed
attempt to open C:\Program Files\MPICH2\lib/mingwex.dll.a failed
attempt to open C:\Program Files\MPICH2\lib/libmingwex.a failed
attempt to open C:\Program Files\MPICH2\lib/mingwex.lib failed
attempt to open C:\Program Files\MPICH2\lib/libmingwex.dll failed
attempt to open C:\Program Files\MPICH2\lib/mingwex.dll failed
attempt to open C:\Program Files\MPICH2\lib\libmingwex.a failed
Apparently, the linker adds a / instead of a \ to the directory names I supply it with (except when looking for the lib___.a format for some reason), which is obviously not a valid path. Is there any way to tell the linker to use backslashes instead of slashes?
This also caught my eye:
attempt to open /mingw/lib/libmingwex.a succeeded
So I tried compiling like this:
g++ -I"/Program Files/MPICH2/include" -L"/Program Files/MPICH2/lib" objManager.cpp ongom.cpp io.cpp main.cpp -lmpi -lcxx
But I still get the same undefined reference errors.

GCC is able to find your library. Otherwise it would report: cannot find -lmpi.
Somehow it happens that the routines cannot be found in that library. I managed to compile an example with this syntax:
g++ -I../include cpilog.c ../lib/mpi.lib ../lib/mpe.lib
I did that inside msys though. And my directory does not contain spaces.
After removing libmpi.a file, this also works:
g++ -I../include -L../lib cpilog.c -lmpi -lmpe

try adding -lmpicxx (the lib for the c++ bindings), and make sure the -l... come after the cpp source file *. this works for me:
g++ -Iinclude -Llib test/cxxpi.cpp -lmpicxx -lmpi
EDIT: re: "undefined reference to 'MPI_Comm_rank'": could it be that your are mixing up / using c and / instead of c++? MPI_Comm_rank seems to be the c binding - the c++ binding would be MPI::Comm::Get_rank(). maybe try compiling your program as c, or, if you want to use c++, using the proper bindings (see cxxpi.cpp in the examples dir)?
* http://newsgroups.derkeiler.com/Archive/Comp/comp.parallel.mpi/2006-08/msg00036.html

I had the similar problem resulting from linking 32-bit object files with 64-bit MPICH library. Linking with 32-bit libmpi.a solved the problem.

I had a similar issue with mingw: for those library files with a .lib ending, I had to put the name of the library without the ending (e.g. -llibboost_system-mgw34-mt when the filename is libbboost_system-mgw34-mt.lib). For library files with a .a ending, I had to put the name of the library excluding the starting "lib" and the trailing .a (e.g. -lws2_32 for libws2_32.a).
So in your case - try -llibmpi (or whatever your file is called without the .lib ending), perhaps it's the same issue.
from: http://www.mingw.org/node/98/revisions/358/view
Note: some paths were printed with “/” as the path separator while some other was printed with “\” as the path separator. I've substitued all with “/” as MinGW GCC accept both.
So I would not put too much time into finding a way to correct the path seperator. Is your library compiled for mingw?
perhaps: http://www.mingw.org/wiki/LibraryPathHOWTO helps you a bit further.

Related

How do I use an external library with gcc?

I am attempting to compile this code:
#include <GLFW/glfw3.h>
int main() {
glfwInit();
glfwTerminate();
return 0;
}
Using this command in MSYS2 on Windows 10:
gcc -Wall runVulkan.c -o runVulkan
as well as this:
gcc -Wall -Llibs/glfw runVulkan.c -o runVulkan
libs/glfw is where I downloaded the library to.
For some reason I keep getting this:
runVulkan.c:1:10: fatal error: GLFW/glfw3.h: No such file or directory
1 | #include <GLFW/glfw3.h>
| ^~~~~~~~~~~~~~
compilation terminated.
It seems like I'm getting something very basic wrong.
I'm just getting started with C, I'm trying to import Vulkan libraries.
Run pacman -S mingw-w64-x86_64-glfw to install GLFW.
Then build using gcc -Wall runVulkan.c -o runVulkan runVulkan.c `pkg-config --cflags --libs glfw3`.
The pkg-config command prints the flags necessary to use GLFW, and the ` backticks pass its output to GCC as flags. You can run it separately and manually pass any printed flags to GCC.
Note that any -l... flags (those are included in pkg-config output) must be specified after .c or .o files, otherwise they'll have no effect.
For me pkg-config prints -I/mingw64/include -L/mingw64/lib -lglfw3.
-I fixes No such file or directory. It specifies a directory where the compiler will look for #included headers. Though it's unnecessrary when installing GLFW via pacman, since /mingw64/include is always searched by default.
-l fixes undefined reference errors, which you'd get after fixing the previous error. -lglfw3 needs a file called libglfw3.a or libglfw3.dll.a (or some other variants).
-L specifies a directory where -l should search for the .a files, though it's unnecessrary when installing GLFW via pacman, since /mingw64/lib is always searched by default.
#include are just headers, for declarations. gcc, as any compilers, needs to know where those .h should be searched.
You can specify that with -I option (or C_INCLUDE_PATH environment variable).
You'll also need -L option, this times to provide the library itself (.h does not contain the library. Just declarations that the compiler needs to know how to compile codes that use the library function's and types).
-L option tells the compiler where to search for libraries.
But here, you haven't specify any libraries (just headers. And I know that it seems logical that they go together. But strictly speaking, there is no way to guess from #include <GLFW/glfw3.h> which library that file contain headers for (that is not just theory. In practice, for example, the well known libc declarations are in many different headers)
So, you will also have to specify a -l option. In your case -lglfw.
This seems over complicated, because in your case you compile and like in a single command (goes from .c to executable directly). But that are two different operations done in one command.
Creation of an executable from .c code source is done in two stage.
Compilation itself. Creating .o from .c (many .c for big codes), so many compilation commands. Using command such as
gcc -I /path/where/to/find/headers -c mycode.c -o mycode.o
Those are not related to the library. So no -l (and therefore no -L) for that. What is compiled is your code, so just your code is needed at this stage. Plus the header files, because your code refers to unknown function and types, and the compiler needs to know, not their code, but at least declarations that they really exist, and what are the types expected and returned by the functions is the headers files.
Then, once all the .o are compiled, you need to put together all compiled code, yours (the .o) and the libraries (which are somehow a sort of .zip of .o) to create an executable. That is called linking. And is done with commands like
gcc -o myexec mycode1.o mycode2.o -L /path/where/to/search/for/libraries -lrary
(-lbla is a compact way to include /path/where/to/search/for/libraries/libbla.so or /path/where/to/search/for/libraries/libbla.a)
At this stage, you no longer need -I or anything related to headers. The code is already compiled, headers has no role left. But you need everything needed to find the compile code of the libraries.
So, tl;dr
At compilation stage (the stage that raises the error you have for now), you need -I option so that the compiler knows where to find GLFW/glfw3.h
But that alone wont avoid you the next error that will occur at linking stage. At this stage, you need -lglfw to specify that you want to use that library, and a -L option so that the compiler knows where to find a libglfw.so

Compiling c program with dependencies, h and h0 files

I am trying to compile the gjh solver - written in C - into an executable file in windows. It is available on netlib
I downloaded the c file and am using gcc compiler via WinGW on windows' command prompt. Trying to compile the gjh.c file directly gave me an error that says:
gjh.c:33:21: fatal error: getstub.h: No such file or directory
#include "getstub.h"
compilation terminated.
I assumed that compiling gjh.c requires the dependency getstub.h.
getstub.h is not the only dependency required, there are other dependencies, namely: arith.h, asl.h, funcadd.h, and stdio1.h. All of these files are available on the same link where I found getstub.h. However, arith.h0 and stdio1.h0 are available instead of arith.h and stdio1.h.
Are these files the same? I tried to rename the .h0 files to .h and tried to compile gjh.c, but I got this error:
collect2.exe: error: ld returned 1 exit status
Are the two files the same? If not, is there any way for me to compile the gjh solver successfully into an .exe?
If that's the only problem in compiling, try using the -I switch in gcc:
gcc -I/my/path/to/include/files -o gjh gjh.c
the -I switch hints to gcc where to find your #include files.
I am not sure about the stdio1.h. I think your approach to rename is OK but that reference to external functions such as Sprintf. You need to link with a library defining that. If you know where it comes from, use the -L and -l switch in gcc for that:
gcc -I/my/path/to/include/files -L/my/path/to/library -lnameoflibrary \
-o gjh gjh.c

How to use shared object file in c compilation

I'm trying to use this C library using gcc Apple LLVM version 8.0.0 (clang-800.0.42.1) on macOS Sierra. I've done the following steps:
make libquirc.so
Copied libquirc.so into my project directory
gcc -o quirc_test quirc_test.c -L. -l libquirc.so.1.0
It produces the error:
quirc_test.c:1:10: fatal error: 'quirc.h' file not found
#include <quirc.h>
^
1 error generated.
quirc_test.c
#include <quirc.h>
This is the first time I've tried to do anything in C and other related questions about compiling with the link flag didn't seem to help as seen above.
C is somewhat primitive. Shared object libraries do not contain the declaration of the API they implement - at least not in enough detail or a form that the compiler can understand.
You'll need the header file quirc.h somewhere you can find it. You could just copy it into the current directory just like the library, but you'll need a minor adjustment to the include statement.
#include "quirc.h"
If the included file is surrounded by double quotes instead of angle brackets, it will first look in the source code directory instead of the system header directories.
An alternative is to install the library somewhere e.g. /usr/local. Your library would go in /usr/local/lib nd your header in /usr/local/include. If you do that, use the -I directive on the compiler command line to tell the compiler where to look for the header e.g.
cc -I/usr/local/include -L/usr/local/lib -lquirc quirc_test.c

tcc: error: undefined symbol 'pthread_create'

I am trying to compile this with tcc
and I have these errors
Before the error it was "Cannot find pthread.h" and I copied
pthread,pthread_compat,pthread_signal,pthread_time,pthread_unistd header files from gcc include dir to tcc include dir ! ... and now I have the above errors.. I think is something with linking but I don't know exactly :/
Copying header files from the gcc include dir was neither required nor a good idea; better use tcc option: -Igcc-include-dir-path.
Anyway, now you will need to link your program to the pthread library in order complete build. Look in the gcc directory for a file named pthread.a or pthread.lib, there you have the gcc libraries directory. Then when you get this directory path, add the following options to the tcc command-line: -Lgcc-library-dir-path -pthread.

Compiling Small Gcc Project on Windows Using MinGW

so I've been programming in C++ for almost 2 years now, and the whole while I've had the pleasure of using an IDE (VS) with lovely project settings and automatic linking and the like. I've always stayed away from any external libraries which required me to compile via makefiles, or at least the ones which were meant for linux environments/other compilers.
Anyways I now want to use a super handy utility (Bob Jenkins Perfect Minimal Hash) but it requires me to compile via makefiles, not only that but using the g++ compiler.
I went ahead and got the mingW32-make utility and am now trying to get it to work. Where I'm at now:
Succesfully installed minGW
Succesfully called the make utility
Failed to succesfully make the project.
The error I get is:
C:\gen_progs\ph>mingw32-make
mingw32-make: *** No rule to make
target lookupa.c', needed by lookupa.o'. Stop.
And the makefile itself:
CFLAGS = -O
.cc.o:
gcc $(CFLAGS) -c $<
O = lookupa.o recycle.o perfhex.o perfect.o
const64 : $(O)
gcc -o perfect $(O) -lm
# DEPENDENCIES
lookupa.o : lookupa.c standard.h lookupa.h
recycle.o : recycle.c standard.h recycle.h
perfhex.o : perfhex.c standard.h lookupa.h recycle.h perfect.h
perfect.o : perfect.c standard.h lookupa.h recycle.h perfect.h
Now the error seems reasonable, at least from my minimal understanding of makefiles, I have all the referenced .c, .h files, however I have none of the .o files and there doesn't appear to be any instructions on how to make these. So my question/s are:
am I calling the make utility wrong? Or do I need to compile the object files first? Or... do I need to add something to the make file?
Again I have all the referenced .c and .h files.
Edit: Sorry about that I was actually missing that specific file it seems to have disapeared somewhere along the line. However, adding it back in this is the error I now get:
c:\gen_progs\ph>mingw32-make
cc -O -c -o lookupa.o lookupa.c
process_begin: CreateProcess(NULL, cc -O -c -o lookupa.o lookupa.c, ...) failed.
make (e=2): The system cannot find the file specified.
mingw32-make: *** [lookupa.o] Error 2
Regarding your error "process_begin: CreateProcess(NULL, cc -O -c -o lookupa.o lookupa.c, ...) failed."
This is because the make utility wants to use the "cc" compiler to compile your program, but that compiler is not part of the Mingw-package.
Solution: Change the ".cc.o:" to ".c.o:". This changes the implicit rule which tells Make what compiler to use (gcc on the next line) when compiling .c files (the original line tells it how to compile .cc files).
Saying either make -DCC=gcc at the command line or adding the line CC=gcc to the top of the Makefile would cure the issue as well. Make's built in rules for handling C source code all name the C compiler with the variable CC, which defaults to "cc" for reasons of backward compatibility even in Gnu Make.
It looks like the original Makefile author tried to work around that problem by supplying a custom rule for compiling .cc files, but since there are no .cc files in the project that rule was not actually used.
Specifying the correct value for CC is superior to fixing the explicit rule to name .c files IMHO because Makefiles are generally easier to use and maintain and are the most portable when the least possible information is specified.
I don't think not having .o files is the problem. Make will make them from the source files (the files to the right of the colon).
Your immediate problem seems to be that make can't file the file "lookupa.c". From the rules you posted, it looks to me like that file should be sitting in the same directory as the makefile, but it isn't. You need to figure out where that file is, and how to get it there.
(For some reason I have a mental image of Wile E. Coyote sitting at his computer, seeing that file name, looking up, and getting plastered with an anvil).

Resources