C C ++ Linking Error - PullRequest
       39

C C ++ Linking Error

2 голосов
/ 16 июля 2009

Я пишу программу на C ++, которая использует библиотеку CLAPACK ATLAS. Однако я не могу заставить программу успешно связаться с библиотекой. Я написал небольшую программу на C, чтобы лучше продемонстрировать проблему. Интересно, что эта небольшая демонстрационная программа прекрасно работает, если я компилирую ее с помощью GCC, но при компиляции с G ++ я получаю те же ошибки компоновщика. Я надеялся, что кто-нибудь может помочь мне точно определить, что G ++ и GCC делают по-разному, чтобы связать исходную программу (исходная программа - это программа C ++, и я не могу просто «использовать GCC»)

Вот небольшая демонстрационная программа:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <cblas.h>
#include <clapack.h>

// a is a column-major array of all the values in the matrix to invert
// The matrix's height and width are the same because it is a square matrix.
void invertMatrix(float *a, unsigned int height)
{
    int info, ipiv[height];
    info = clapack_sgetrf(CblasColMajor, height, height, a, height, ipiv);
    info = clapack_sgetri(CblasColMajor, height, a, height, ipiv);
}

void displayMatrix(float *a, unsigned int height, unsigned int width)
{
    int i, j;
    for(i = 0; i < height; i++)
    {
            for(j = 0; j < width; j++)
            {
                    printf("%1.3f ", a[height*j + i]);
            }
            printf("\n");
    }
    printf("\n");
}

void multiplyMatrix(float *a, unsigned int aheight, unsigned int awidth, float *b, unsigned int bwidth, float *c)
{
    cblas_sgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, aheight, bwidth, awidth, 1.0f, a, aheight, b, awidth, 0.0f, c, aheight);
}

int main(int argc, char *argv[])
{
    int i;
    float a[9], b[9], c[9];
    srand(time(NULL));
    for(i = 0; i < 9; i++)
    {
            a[i] = 1.0f*rand()/RAND_MAX;
            b[i] = a[i];
    }
    displayMatrix(a, 3, 3);
    invertMatrix(a, 3);
    multiplyMatrix(a, 3, 3, b, 3, c);
    displayMatrix(c, 3, 3);
    return 0;
}

И когда я пытаюсь скомпилировать это с GCC, все работает просто отлично:

$ gcc -o linearalgebra linearalgebra.c -I /usr/include/atlas -L /usr/lib64/atlas/ -llapack -lblas
$ ./linearalgebra
0.723 0.755 0.753
0.179 0.912 0.349
0.642 0.265 0.530

1.000 -0.000 0.000
0.000 1.000 0.000
0.000 0.000 1.000

$

И когда я пытаюсь скомпилировать это с G ++, выдает ошибки компоновщика:

$ g++ -o linearalgebra linearalgebra.c -I /usr/include/atlas -L /usr/lib64/atlas/ -llapack -lblas
/tmp/ccuhmDKE.o: In function `multiplyMatrix(float*, unsigned int, unsigned int, float*, unsigned int, float*)':
linearalgebra.c:(.text+0x7b): undefined reference to `cblas_sgemm(CBLAS_ORDER, CBLAS_TRANSPOSE, CBLAS_TRANSPOSE, int, int, int, float, float const*, int, float const*, int, float, float*, int)'
/tmp/ccuhmDKE.o: In function `invertMatrix(float*, unsigned int)':
linearalgebra.c:(.text+0x182): undefined reference to `clapack_sgetrf(CBLAS_ORDER, int, int, float*, int, int*)'
linearalgebra.c:(.text+0x1a0): undefined reference to `clapack_sgetri(CBLAS_ORDER, int, float*, int, int const*)'
collect2: ld returned 1 exit status
$

Последнее, но не менее важное: некоторая информация о моей системе:
Операционная система: Fedora 10 (Linux hostname 2.6.27.25-170.2.72.fc10.x86_64 #1 SMP Sun Jun 21 18:39:34 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux)
Библиотеки:

$ yum list | grep lapack
lapack.x86_64                        3.1.1-4.fc10                 installed
lapack-debuginfo.x86_64              3.1.1-4.fc10                 installed
lapack-devel.x86_64                  3.1.1-4.fc10                 @fedora
$ yum list | grep blas
blas.x86_64                          3.1.1-4.fc10                 installed
blas-devel.x86_64                    3.1.1-4.fc10                 installed
$ yum list | grep atlas
atlas.x86_64                         3.6.0-15.fc10                installed
atlas-debuginfo.x86_64               3.6.0-15.fc10                installed
atlas-devel.x86_64                   3.6.0-15.fc10                @fedora

Кроме того, для бонусных баллов: каковы исторические и функциональные отношения между LAPACK и ATLAS?

1 Ответ

5 голосов
/ 16 июля 2009

Если вы хотите связать программу C ++ с библиотекой C, вы должны убедиться, что все функции и т. Д. В библиотеке C имеют префикс extern "C". Компилятор C ++ изменяет имена символов C ++, что делает невозможным сопоставление компоновщиком символов с именами в библиотеке C. Вы можете использовать блок для объявления ваших символов C:

extern "C" {
  ...
}

Возможно, вы сможете определить символ препроцессора, чтобы указать cblas.h и clapack.h, что необходимо включить extern "C" перед всеми объявлениями.

...