Linking to LAPACK from g++ in cygwin64

  • C/++/#
  • Thread starter pasmith
  • Start date
  • #1
pasmith
Homework Helper
1,754
424

Main Question or Discussion Point

I get an 'undefined reference to 'zcgesv_'' error when I try to link the LAPACK library using g++ on cygwin64.

What am I missing? Google has not turned up anything which solves the problem.

(Documentation for zcgesv here )

My Makefile is as follows:
Code:
GCC := /usr/bin/i686-pc-cygwin-g++
LIBS := -L/usr/lib -llapack -lblas

lapacktest.o: lapacktest.cpp
    $(GCC) -c -o lapacktest.o lapacktest.cpp

lapacktest.exe: lapacktest.o
    $(GCC) -o lapacktest.exe $(LIBS) lapacktest.o
lapacktest.cpp contains the following:
Code:
#include<iostream>

using namespace std;

typedef struct{double real;double imag;} Complex;

extern "C" 
     void zcgesv_(
        int*,            // N 
        int*,            // NRHS
        Complex*,         // A
        int*,             // LDA
        int*,             // IPIV
        Complex*,         // B
        int*,             // LDB
        Complex*,         // X
        int*,             // LDX
        Complex*,        // WORK
        Complex*,        // SWORK
        double*,        // RWORK
        int*,            // ITER
        int*            // INFO
    );

    
int main(int argc, char *argv[])
{
    Complex *A, *b, *x, *work, *swork;
    double * rwork;
    int n, nrhs, lda, ldb, ldx, iter, info, *ipiv;
    
    int i,j;
    
    n = 3;
    nrhs = 1;
    lda = ldb = ldx = n;
    
    
    A = new Complex[n*n];
    b = new Complex[n*nrhs];
    x = new Complex[n*nrhs];
    ipiv = new int[n];
    work = new Complex[n*nrhs];
    swork = new Complex[n*(n+nrhs)];
    rwork = new double[n];
    
    for(i = 0; i < n; i++)
    {
        b[i] = Complex{1.0,0.0};
        
       // The matrix I'm interested in is neither diagonal nor sparse, but this is a simple test.

        for(j = 0; j < n; j++)
            A[n*j + i] = (i == j) ? Complex{2.0,1.0} : Complex{0,0};
    }
    
    
    zcgesv_(&n,&nrhs, A, &lda, ipiv, b, &ldb, x, &ldx, work, swork, rwork, &iter, &info);
    
    for(i = 0; i < n; i++)
        cout << "(" << x[i].real << "," << x[i].imag << ")" << endl;
    
    delete[] A;
    delete[] b;
    delete[] x;
    delete[] work;
    delete[] swork;
    delete[] rwork;
    delete[] ipiv;
    
    return 0;
}
 

Answers and Replies

  • #2
Paul Colby
Gold Member
1,120
258
The first thing is the _ on the function name. I would dump the symbol table (use nm) and see what it's actually called in the library.
 
  • Like
Likes pasmith
  • #3
pasmith
Homework Helper
1,754
424
The first thing is the _ on the function name. I would dump the symbol table (use nm) and see what it's actually called in the library.
I tried that; sadly nm told me "file fornat not recognised".

Every example I've seen of linkin g LAPACK includes the trailing underscore; in any event, removing the underscore resulted in the linker telling me that "zcgesv" was not defined.

I have now located the source code for LAPACK 3.9.0 and will attempt to compile my own lapack.a

EDIT: nm can cope with the new liblapack.a, but I still get the same error from the linker.

Running nm over zcgesv.o gives this:
Code:
00000000 b .bss
00000000 d .data
00000000 r .rdata
00000000 r .rdata$zzz
00000000 t .text
         U _cgetrf_
         U _cgetrs_
         U _clag2z_
         U _dlamch_
         U _izamax_
         U _xerbla_
         U _zaxpy_
00000000 T _zcgesv_
         U _zgemm_
         U _zgetrf_
         U _zgetrs_
         U _zlacpy_
         U _zlag2c_
         U _zlange_
 
Last edited:
  • #4
Paul Colby
Gold Member
1,120
258
gfortran has a -fno-underscoring compile switch you might explore.
 
  • #5
pasmith
Homework Helper
1,754
424
Success!

THe -fno-underscoring option caused issues with linkning to the FORTRAN library.

I was able to get it to compile and run with the following make rules:

Code:
lapacktest.o: lapacktest.c
    $(GPP) -static -c -o lapacktest.o lapacktest.cpp

lapacktest.exe: lapacktest.o
    $(GPP)  -static -o lapacktest.exe lapacktest.o ~/lapack-3.9.0/liblapack.a ~/lapack-3.9.0/librefblas.a ~/lapack-3.9.0/librefblas.a -lgfortran -lquadmath
This does suggest tat the linker isn't actually looking for libraries in directories where you tell it to look.
 
  • #6
Paul Colby
Gold Member
1,120
258
Cool.

Another thing to look at is pkg-config. If the lapack library install by sygwin has a config then

pkg-config --cflags --libs lapack

will return the needed command line switches.

On Mac OS using brew I installed lapack using homebrew. Also installed is lapacke - C Standard Interface to LAPACK. pkg-config works but one needs to set PKG_CONFIG_PATH correctly. The Mac OS may have an indigenous lapack with which brew interferes.
 
Last edited:

Related Threads on Linking to LAPACK from g++ in cygwin64

Replies
2
Views
1K
Replies
1
Views
4K
Replies
22
Views
3K
  • Last Post
Replies
1
Views
6K
Replies
7
Views
2K
Replies
5
Views
5K
Replies
4
Views
5K
Replies
6
Views
1K
  • Last Post
Replies
2
Views
2K
Replies
3
Views
609
Top