2017-02-24 19 views
0

私は自分のプロジェクトをクラスタで構築しようとしているので、環境には何の影響も与えません。私のローカルマシン上で私はそれを動作させることができます。Cmakeは複数のバージョンのboost/Cmakeをソースファイルの別々のコンパイルにリンクします。

問題点: 私のプロジェクトには、cudaファイルとC++コードが含まれています。後者はgcc/g ++> 6が必要なライブラリを必要とします(afaik std = C++ 14)。一方、cuda 7.5ではcudaが必要です。< 5.

g ++ 6.2.0を標準コンパイラとして使用してこの問題を解決しました。もう1つのgccを-ccbin/path/to/gcc-4.x。

私のコードはうまくコンパイルされますが、ローカルで使用するgcc 6.2.0よりも新しいバージョンのgccを使用する必要があるブーストライブラリも問題になります。正しいものをリンクすると正常に動作するので、これも問題ではありません。BUTこの場合、nvccは古いバージョンのboost(gcc-4.xと互換性があります)をリンクしています。ブーストライブラリバージョンリンク。これにより、古いブーストライブラリの機能が使用されるたびに、実行時にセグメンテーションフォールトが発生します。これが解決するかどう

foo: foo-class.o 
    nvcc foo-class.o foo.cu -o foo 

は、私は現在、わからないよ:

は、だから私は考えていたソリューションを行うだろうちょっと簡単なメイクファイルのターゲットのように、C++のファイルとのみCUDAファイルをコンパイルする最初のだろう問題があり、これがcmakeと関係があるのであれば、そうでない場合には、二重リンケージの世話をする可能性はありますか?鉱山は現在、どのように見えるかの

最小cmakeのファイルの例:任意の助け

cmake_minimum_required(VERSION 3.2) 

project(foo) 

set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) 
set(LINKER_FLAGS "-lboost_program_options -lboost_regex -lSDL2 -lSDL2main -lboost_system -lboost_filesystem") 
set(ADDITIONAL_FLAGS "-g -Wno-error=switch") 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 ${LINKER_FLAGS} ${ADDITIONAL_FLAGS}") 

set(SOURCE_FILES 
    runtime/main.cpp 
    foo.cpp) 

set(CUDA_FILES cuda/food.cu) 

set(CUDA_ADDITIONAL_FLAGS "-ccbin /usr/bin/gcc --Wno-deprecated-gpu-targets") 
set(CUDA_SDK_ROOT_DIR "/afs/crc.nd.edu/x86_64_linux/c/cuda/8.0/") 
find_package(CUDA QUIET REQUIRED) 
set(CUDA_PROPAGATE_HOST_FLAGS OFF) 
set(CUDA_NVCC_FLAGS -g ${CUDA_ADDITIONAL_FLAGS}) 

FIND_PACKAGE(Boost COMPONENTS program_options filesystem system regex REQUIRED) 

cuda_add_executable(isosurfaces ${SOURCE_FILES} ${CUDA_FILES}) 


include_directories(~/lib/include) 
include_directories(${BOOST_ROOT}/incldue) 

target_link_libraries(foo ~/lib/lib/libThorSerialize17.so) 

おかげで、私はそれを本当に感謝しています。私はブーストが提供する変数ではなく、手動設定のスクリプトを見つける使用することをお勧めcmakeのファイルを向上させるために

+0

おそらく私はここで完全に明白な何かを見逃していますが、とにかくホストコードをnvccとリンクしようとしているのはなぜですか? – talonmies

+0

cmakeで1つの実行可能ファイルをビルドする方法はありますか?nvccでコンパイルした部分とgcc/g ++で1つの部分をコンパイルできるのですか? – mimre

答えて

2

(それはしかし、最も可能性の高い問題自体に役立ちますが、一般的にはよくないだろう):

find_package(Threads) 
# set(Boost_USE_STATIC_LIBS ON) # uncomment to try with static libs 
FIND_PACKAGE(Boost REQUIRED COMPONENTS program_options filesystem system regex) 
include_directories(${Boost_INCLUDE_DIRS}) 
link_directories(${Boost_LIBRARY_DIRS}) 

target_link_libraries(isosurfaces 
    ${Boost_LIBRARIES} 
    ${CUDA_LIBRARIES} 
    ${CMAKE_THREAD_LIBS_INIT} 
) 

# remove -lboost_program_options -lboost_regex -lboost_system -lboost_filesystem 
# from LINKER_FLAGS as provided better by ${Boost_LIBRARIES} 

さまざまなバージョンのBoostに関する問題(何らかの理由で実際にBoostをCudaコードで使用する必要がある場合)については、単一の実行可能ファイルの範囲で作業するのは非常に難しいでしょう。ただし、モジュールの1つ(Cudaまたはアプリケーションコード)を別の共有ライブラリに分けることができます。そうすれば、共有ライブラリはアプリケーションの残りのバージョンとは異なるBoostバージョンを使用できます(静的または共有のBoostライブラリを使用して実験することができます。つまり、Boost_USE_STATIC_LIBSはON/OFFを切り替えます)。あなたは何ができるのCUDAコードから共有ライブラリを作成するたとえば

​​

そして、それはおそらくあなたがクーダコードと残りのCとの界面にブーストを使用しないことを提供し、仕事ができる++コード。

また、BoostライブラリシンボルがCuda共有ライブラリからエクスポートされないように、visibility属性を使用してすべてのシンボルをデフォルトで非表示にすることもできます(または、ライブラリが残りのC++コード)。そのために、 "-fvisibility=hidden"コンパイラフラグと "-Wl,--exclude-libs=ALL -Wl,--discard-all"リンカフラグを使用できます。

+0

私はこの方法でプロジェクトを構築しようとしています、そして、これはこれが行くべき方法であるように思えます。私の唯一の問題は、cuda_add_libraryがadd_exectuable呼び出しと同じコンパイルフラグを使用することです。これは私にとっては奇妙なことです。 – mimre

+0

ハム、私は実際にはまだCMakeでCudaを使用していませんでしたが、デフォルトでは同じフラグを使用していると思いますが、おそらくCuda特有のものもあります。あなたは 'set_target_properties(isosurfaces_cuda COMPILE_FLAGS" additional flags ")'を使ってCudaライブラリのコンパイルフラグをやや変更することができますが、それは私が思うに余分なフラグを追加するだけです。したがって、CudaとAppのフラグを別にしたい場合は、アプリに対しても 'set_target_properties'を使用し、デフォルトのCXXフラグを両方で共有する基本セットのみに設定することができます。 – axalis

+0

ありがとう、あなたのポストは、最終的に私を助けたものでした。 私はライブラリにcudaの部分を分けて、CMakeLists.txtのどこにフラグをセットしていくつかのフラグを取り除いたところで遊んでいました。私はどのように/なぜ、それは動作するのか正確には分かりません。 – mimre

関連する問題