2017-10-03 6 views
2

私はOpenCLフレームワークを使ってGPU計算を行うことができるライブラリを持っています。残念ながら、OpenCLはすべてのプラットフォームで利用できるわけではありません。しかし、私はまだOpenCLの機能を除いて、それらのプラットフォームで自分のコードをコンパイルできるようにしたいと思います。ライブラリAPIを台無しにすることなく条件付きコンパイルを実装するにはどうすればよいですか?

この質問は、常に利用可能なわけではない可能性のある外部リソースを条件付きでコンパイルするすべての状況に当てはまり、ライブラリAPIを使いこなすことになります。

現在、私はそれがこのように設定している:

CMakeの:

if(ENABLE_OPENCL) 
    add_definitions(-DENABLE_OPEN_CL) 
    find_package(OpenCL REQUIRED) 
    include_directories(${OpenCL_INCLUDE_DIR}) 
    target_link_libraries(mylibrary ${OpenCL_LIBRARY}) 
endif() 

C++

// settings.hpp, exposed to public API 
class settings 
{ 
    int general_setting_1; 
    bool general_setting_2; 
    // ... Other general settings 
#ifdef ENABLE_OPEN_CL 
    int open_cl_platform_id; 
    // ... Other settings available only when OpenCL is available 
#endif 
    // More settings, possibly also conditionally compiled on other external libraries 
}; 
// computation.cpp, internal to the library 

#ifdef ENABLE_OPEN_CL 
#include <CL/cl.hpp> 
#endif 

void do_things() 
{ 
    // ... 

#ifdef ENABLE_OPEN_CL 
    if(settings.open_cl_platform_id != -1) 
    { 
     // Call OpenCL code 
    } 
#endif 

    // ... 
} 

だから私ならば、私は、ライブラリのコンパイル私はOpenCLを有効にしたいcmake .. -DENABLE_OPEN_CL

これは動作しますが、クライアントはENABLE_OPEN_CLでコンパイルされたライブラリを消費している場合、それは同じENABLE_OPEN_CLを定義するためにクライアントを強制し、そうでない場合は付属のライブラリのヘッダファイルがクライアントで使用されるものと一致していない、と非常に悪いこと起こる。

これは、ワームの完全な蓋を開きます。例えば、クライアントがそれをやめたらどうしますか?同じ識別子の名前を他のものに使用するとどうなりますか?

これを避けることはできますか?そうでなければ、ヘッダファイルがクライアントとライブラリで一致することを確認してコンパイルエラーを起こすことができる方法はありますか?または、少なくとも実行時例外をスローしますか?このシナリオに対する正しいアプローチは何ですか?

+0

ダイナミックローディングとレイトバインディングについて考えましたか? –

+0

ENABLE_OPEN_CL定義に依存しないヘッダーを作成できますか?しかし、このフラグを付けずにコンパイルした場合は、すべてのAPIに対して空のスタブ関数の実装を提供します。つまり、ERROR_NOTIMPLEMENTEDを返します。クライアントは何も定義する必要はありませんが、OpenCLをサポートしないライブラリに対してリンクすると、十分に文書化された方法)? –

+0

もう1つの方法は、ビルド設定に基づいてすべての適切な定義を含むヘッダーファイル(library_config.h)を生成し、このヘッダーをクライアント(配布するパブリックHファイルに含めます)に配布して、クライアントが追加する必要がないようにすることです任意のコードを定義する –

答えて

2

OpenCLがサポートされていない場合でも、open_cl_platform_idsettingsのメンバーとして残すことは明らかです。ライブラリがコンパイルされていないときにOpenCLの機能を使用しようとすると、ユーザーは実行時エラーを受け取ります。

また、2つのヘッダーファイルsettings_no_open_cl.hppsettings_open_cl.hppを持っていて、ユーザーには正しいヘッダーファイルを含める必要があります。

+0

私がやったことは、「open_cl_platform_id」をそのまま残しておいたことです。しかし、APIを十分に明示していないように感じたので、別の設定 'bool use_open_cl'を追加しました。この設定は、その機能を使用する意図を明示するためにtrueに設定する必要があります。 'use_open_cl'が真だが' ENABLE_OPEN_CL'が定義されていなければ、例外をスローします。 –

関連する問題