0

I am currently compiling two programs.

The same link line produces no error on one, and a whole lot of undefined references on the other one.

The link line is:

/usr/bin/c++   -Wall -pedantic -std=c++11   -fopenmp -O3 -DNDEBUG  
CMakeFiles/program.dir/src/main.cpp.o  -o program -rdynamic 
/home/felix/Development/local/lib/volop/libvolop.so 
/home/felix/Development/local/lib/ghost/libghost.so 
/home/felix/Development/local/lib/libhwloc.so 
/usr/local/lib/libmpicxx.so 
/usr/local/lib/libmpi.so -lrt -lpthread -L/usr/lib -lgsl -lgslcblas -lm 
/home/felix/Development/PRIMME/libprimme.a 
-L/usr/lib -lgsl -lgslcblas -lm -llapack 
-L/usr/lib -lgsl -lgslcblas -lm /home/felix/libblas/lib/libopenblas.so 
/home/felix/Development/PRIMME/libprimme.a 
-llapack 
/home/felix/libblas/lib/libopenblas.so 
-Wl,-rpath,/home/felix/Development/local/lib/volop:/home/felix/Development/local/lib/ghost:/home/felix/Development/local/lib:/usr/local/lib:/home/felix/libblas/lib 

And the associated error:

/home/felix/Development/local/lib/ghost/libghost.so: undefined reference to `MPI_Allgather'
/home/felix/Development/local/lib/ghost/libghost.so: undefined reference to `MPI_Init_thread'

and so on, all MPI Linker errors. However as you can see from the link line mpi is linked in. And in the other program it works just fine.

This is on the same computer with the same compiler. The link line is generated by cmake. The CMakeLists.txt is identical for both programs.

I stop getting linker errors once I start using MPI Methods explicitely in the program which produces the errors. Why?

EDIT: As requested in the comments

ldd /home/felix/Development/local/lib/ghost/libghost.so
linux-vdso.so.1 =>  (0x00007fff6dff8000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8d70837000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8d70531000)
libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f8d70321000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8d7010b000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f8d6feed000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8d6fb26000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8d70f81000)
Blackclaws
  • 436
  • 5
  • 20
  • possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – PlasmaHH Jul 10 '14 at 11:27
  • I don't think this is a duplicate as it is no general linker error where the symbols are not found. The correct file is linked in and it works fine IF I use an MPI Method in the program I am compiling. If I do not then I get the undefined reference error – Blackclaws Jul 10 '14 at 14:08
  • might be worth listing the symbols in /usr/local/lib/libmpicxx.so to make sure the symbols match what are in libghost.so – powerrox Jul 10 '14 at 18:55
  • What is the output of `ldd /home/felix/Development/local/lib/ghost/libghost.so`? – Hristo Iliev Jul 10 '14 at 23:27
  • I tried a multitude of different test cases with an intermediate shared object that imports MPI symbols and none of them is able to reproduce your problem. Try linking the executable with `mpic++` as directed by Wesley Bland. Also, `libghost.so` does not specify `libmpi.so` in its `DT_NEEDED` section (as evident from the output from `ldd`) which probably means that it also wasn't linked using the appropriate compiler wrapper. – Hristo Iliev Jul 11 '14 at 15:21

2 Answers2

2

Usually when someone gets weird linker errors with MPI, it's because they're not using the compiler wrappers that do the work for them.

When you (or someone else on your behalf) installed MPI on your machine, some wrappers were created to add all of the necessary flags to the compiler line just like the launcher mpiexec was also installed. Those wrappers are called mpicc, mpic++, mpicxx, mpifc, etc. You can use these just like you'd use any other compiler. You're welcome to throw in your own compiler flags if you need to add your own libraries, etc.

Wesley Bland
  • 8,816
  • 3
  • 44
  • 59
0

I can't be 100% sure, but this happened to me lots of times. The reason is the linking order: it DOES matter.

You need to link libraries from the "top" of the hierarchy to the "bottom"; as in, first you put the most complex libraries, and after you put the libraries on which other libraries depend on.

Try putting libmpi.so as last, and see if it works (or shuffle other things around if you think it matters).

Svalorzen
  • 5,353
  • 3
  • 30
  • 54
  • The order only matters when symbols from static archives (`libblabla.a`) are involved. When linking against shared objects that does not apply. Even if the order was significant for shared objects too, `libghost.so` still appears before `libmpi.so` in the link command. – Hristo Iliev Jul 10 '14 at 13:13