2017-09-11 25 views
4

私のC++コードにLapackを使用しています。私はライブラリに正しくリンクする方法がかなり混乱しています。ここでLAPACKから関数を呼び出して、私のコードに対応した小さな例です。C++のFortranライブラリ(Lapack)へのリンク

#include <iostream> 

namespace lapack { extern "C" { 
    void ilaver(int* major, int* minor, int* patch); } } 

int main() 
{ 
    int major = 0; 
    int minor = 0; 
    int patch = 0; 
    lapack::ilaver(&major, &minor, &patch); 
    std::cout << major << "." << minor << "." << patch << std::endl; 
    return 0; 
} 

私はGCC 4.8.5(LinuxのopenSUSEの)でそれをコンパイルしようとすると、私は次のエラーを取得する:

> g++ ilaver.cpp -o ilaver -L /softs/lapack/3.7.1/64/gcc/4.8.5/lib64 -l lapack 
/tmp/ccHvDCAh.o: In function `main': 
ilaver.cpp:(.text+0x33): undefined reference to `ilaver' 
collect2: error: ld returned 1 exit status 

名前マングリング問題だと分かりました。

#include <iostream> 

namespace lapack { extern "C" { 
    void ilaver_(int* major, int* minor, int* patch); } } 

int main() 
{ 
    int major = 0; 
    int minor = 0; 
    int patch = 0; 
    lapack::ilaver_(&major, &minor, &patch); 
    std::cout << major << "." << minor << "." << patch << std::endl; 
    return 0; 
} 

しかし、それはWindowsでIntelのコンパイラでコンパイルしていない:私は、関数名の末尾にアンダースコアを追加し、私のコードを変更した場合、それはGCCと正しくコンパイルされます。そこでは、マングリングが異なっているので、それをlapack::ILAVERに変更してからコンパイルしなければなりません。

私のコードはいくつかのコンパイラ(GCC、Intel、MSVC)でいくつかの設定(Linux/Mac/Windows)でコンパイルする必要があります。より包括的で、大規模なコンパイラパネルの下でコンパイルする方法を教えてください。

+2

lapackeを使用してください。彼らはすでにこれを動作させるために必要な厄介なマクロトリッキーをやっており、それは公式のCインターフェイスです。 –

答えて

2

あなたがすでに発見したように、アンダースコアの追加のようなハックはその性質上プラットフォーム固有です。 "手作業"のような広範囲のプラットフォームとコンパイラをサポートすることは、大量の不快で退屈な作業を必要とします。

移植性を得る最も簡単な方法は、LAPACKへの公式のCインターフェイスであるLAPACKEを使用することです。これには、必要なすべての関数を再宣言する必要がなくなるという利点もあります。

は簡単な例です:

#include <iostream> 
#include <lapacke.h>  

int main() 
{ 
    // By using lapack_int, we also support LAPACK-ILP64 
    lapack_int major = 0; 
    lapack_int minor = 0; 
    lapack_int patch = 0; 
    LAPACKE_ilaver(&major, &minor, &patch); 
    std::cout << major << "." << minor << "." << patch << std::endl; 
    return 0; 
} 

詳しい情報はofficial documentationで見つけることができます。

LAPACKEはLAPACKのみを処理しますが、BLASルーチンも必要な場合はCBLASから取得できます。

+0

それは解決策かもしれませんが、私たちが使用するさまざまな設定ではデフォルトでlapackeはインストールされません。これは、すべての設定でlapackのすべてのインストールを更新する追加のコストを引き起こします。 – Caduchon

+2

@Caduchon私は前にその議論を聞いたことがありますが、私はラパックのインストールと更新が、自家製のラッパックを書いて維持するよりもずっと速くて簡単だと言います。 –

+0

lapackeにはBLAS関数も含まれていますか(blasはコンパイル時にlapackで与えられました)?私は 'dgemm'(私はそれを使用する)を見つけることができません。 – Caduchon

関連する問題