Search code examples
c++codeblockslapack

How I can be sure that I install LAPACK and Armadillo libraries correctly?


I am new in LAPACK library for c++. I work on large scale matrices and their QR factorization. I have problem with using Lapack library in Codeblocks. I linked this library and code blocks based on the following link: How do I link to a library with Code::Blocks?. My code::blocks knows all of the headers,commands and functions in Lapacks but I couldn't run dgeqrffunction for QR factoization with this error: undefined reference todgeqrf`.

I also tried to use armadillo library. I am able to run its simple commands but when I wanted to run qr(Q,R,X) for factorization, it gives this error: undefined reference to _gfortran_compare_string'. So, I think that the problem might be in installation procedure ( for lapack). I have downloaded the new version of LAPACK and installed it by using CMakein C:\lapack . My operation system is Windows 7(64 bite). Who can tell where is my mistake? In installation step or linking step?How I can find the reason of this problem and how it can be solved? The build log message for lapack library:

 -------------- Build: Debug in lllll (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -LC:\lapack -LC:\arma -LC:\ttmath-0.9.3 -L"C:\Program Files\R\R-3.2.1\include" -LC:\lapack\lib -LC:\arma -o bin\Debug\lllll.exe obj\Debug\main.o   C:\lapack\lib\libblas.a C:\lapack\lib\liblapack.a C:\lapack\lib\liblapacke.a C:\lapack\lib\libtmglib.a C:\arma\examples\lib_win64\blas_win64_MT.lib C:\arma\examples\lib_win64\lapack_win64_MT.lib
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x376): undefined reference to `_gfortran_compare_string'
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x3a1): undefined reference to `_gfortran_compare_string'
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x3e6): undefined reference to `_gfortran_compare_string'
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x40d): undefined reference to `_gfortran_compare_string'
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x434): undefined reference to `_gfortran_compare_string'
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x45b): more undefined references to `_gfortran_compare_string' follow
C:/Program Files (x86)/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/4.9.2/../../../../mingw32/bin/ld.exe: C:\lapack\lib\liblapack.a(ilaenv.f.obj): bad reloc address 0x60 in section `.rdata'
C:/Program Files (x86)/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/4.9.2/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status

Also for Armadillo library:

-------------- Build: Debug in ltest (compiler: GNU GCC Compiler)---------------
mingw32-g++.exe -Wall -fexceptions -g -IC:\ttmath-0.9.3 -I"C:\Program Files\R\R-3.2.1\include" -IC:\lapack\include -IC:\arma\include -c "D:\c++ code\ltest\main.cpp" -o obj\Debug\main.o
mingw32-g++.exe -LC:\ttmath-0.9.3 -L"C:\Program Files\R\R-3.2.1\include" -LC:\lapack\lib -LC:\arma -o bin\Debug\ltest.exe obj\Debug\main.o   C:\arma\examples\lib_win64\blas_win64_MT.lib C:\arma\examples\lib_win64\lapack_win64_MT.lib C:\lapack\lib\libblas.a C:\lapack\lib\liblapack.a C:\lapack\lib\liblapacke.a C:\lapack\lib\libtmglib.a
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x376): undefined reference to `_gfortran_compare_string'
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x3a1): undefined reference to `_gfortran_compare_string'
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x3e6): undefined reference to `_gfortran_compare_string'
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x40d): undefined reference to `_gfortran_compare_string'
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x434): undefined reference to `_gfortran_compare_string'
C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x45b): more undefined references to `_gfortran_compare_string' follow
C:/Program Files (x86)/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/4.9.2/../../../../mingw32/bin/ld.exe: C:\lapack\lib\liblapack.a(ilaenv.f.obj): bad reloc address 0x60 in section `.rdata'
C:/Program Files (x86)/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/4.9.2/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status

Solution

  • Contrary to what you have written, the build logs show no undefined reference to dgeqrf. They both show an undefined reference to _gfortran_compare_string:

    C:\lapack\lib\liblapack.a(ilaenv.f.obj):ilaenv.f:(.text+0x376): undefined reference to `_gfortran_compare_string'
    

    This error message tells you that the object file ilaenv.f.obj in library liblapack.a makes a call to function _gfortran_compare_string, but the linker finds that you have provided it with no object file or library in which that function is defined.

    The reason for that is that liblapack.a is a Fortran library - compiled with GCC Fortran (gfortran) - that is dependent on libgfortran.

    When you link a library on which your program depends you must also link any further libraries upon which the first library depends.

    You appear to be under the impression that your LAPACK libraries are C++ libraries. They are Fortran libraries: LAPACK is written in Fortran. That is no obstacle to linking them in a C++ program, provided that you satisfy the linkage requirements.

    In this case, that means you must add libgfortran to your linkage. And you must add it in the linkage sequence after any object file or library that depends on it.

    You say that you installed LAPACK with CMake. If so, then you built your LAPACK libraries from source, with the make system generated by CMake, and make must have used a gfortran compiler installed on your system to do that.

    Since you have gfortran somewhere, you also have libgfortran. Find the installation directory of gfortran - it will contain a subdirectory bin, containing gfortran.exe - and ask Windows to search under that installation directory for a static library libgfortran.a or a dynamic library (probably) libgfortran-3.dll. You seem to be going with static libraries: in that case add the libgfortran.a at the end of your linkage.

    BTW there is considerable redundancy in the way you are specifying your linkage libraries. Since you are specifying all of your libraries by absolute pathnames - e.g. C:\lapack\lib\liblapack.a - it is pointless to specify any -L options, since the -L linker option exists only for telling the linker what directories to search for libaries that you specify in the usual short form, e.g.

    ... -LC:\lapack\lib  ... -llapack ... -ltmglib ...
    

    It is additionaly pointless to give the linker -L options for directories that do not contain any of the libraries you are linking, including directories that contain header files. In Codeblocks, you can delete all of the Search directories -> Linker from your project's build options, unless you choose to specfy libraries in short form in Linker -> Other linker options.