Cmake链接多个版本的boost/Cmake独立编译的源文件
我想在集群上构建我的项目,所以我对环境没有任何影响(即没有sudo)。在我的本地机器上,我可以使它工作。Cmake链接多个版本的boost/Cmake独立编译的源文件
这里的问题: 我的项目包含cuda文件以及C++代码。后者需要一个需要gcc/g ++> 6(也许> 5也可以,afaik std = C++ 14)的库。另一方面,cuda代码需要gcc < 5.
我已经通过使用g ++ 6.2.0作为标准编译器并通过其他gcc与-ccbin /路径/到/ GCC-4.x的。
因此,我的代码编译得很好,但问题是它也使用boost库,它需要是群集上的新版本才能与我在本地使用的gcc 6.2.0一起工作。这也不是问题本身,因为链接正确的工作,但是这样做时,nvcc仍然链接一个较旧版本的boost(这是与gcc-4.x兼容),从而导致有多个提升链接库的版本。在运行时,无论何时使用旧的boost库的函数,都会导致分段错误。
因此,一个解决方案,我在想会是第一个编译的C++文件,然后只CUDA文件,有点像一个简单的makefile目标会做:
foo: foo-class.o
nvcc foo-class.o foo.cu -o foo
我目前不能确定这是否会解决问题,如果这可能与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的文件我建议使用由升压发现脚本而不是手动设置提供的变量(将然而,最有可能不是这个问题本身有帮助,但在总体上是好的):
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的不同版本有关的问题本身(如果您真的需要在Cuda代码中出于某种原因使用Boost),恐怕很难在单个可执行文件的范围内工作。但是,您可以执行的操作是将其中一个模块(Cuda或应用程序代码)分隔到单独的共享库。这种方式可以相对简单地工作,因为共享库可以使用与应用程序其余部分不同的Boost版本(您可以尝试使用静态或共享Boost库,即Boost_USE_STATIC_LIBS
切换开/关)。
例如创建一个从Cuda的代码共享库,你可以这样做:
那么它可能可以工作,前提是你没有在CUDA代码,其余C之间的接口使用升压++码。
它也可以帮助使用可见性属性并默认隐藏所有符号,以便Boost库符号不会从Cuda共享库中导出(或者反过来,如果库是从剩余的库中创建的C++代码)。为此,可以使用“-fvisibility=hidden
”编译器标志和“-Wl,--exclude-libs=ALL -Wl,--discard-all
”链接器标志。
我试图用这种方式来构建项目,而且看起来应该是这样的方式。我唯一的问题是,cuda_add_library使用与add_exectuable调用相同的编译标志,这对我来说很奇怪。 – mimre
嗡嗡声,我其实并没有将Cuda与CMake一起使用,但是我会假设它默认使用相同的标志,也许还有一些Cuda特有的附加标志。你可以通过使用'set_target_properties(isosurfaces_cuda COMPILE_FLAGS“附加标志)'来稍微改变Cuda库的编译标志',但那只会增加额外的标志,我认为。因此,如果你想为Cuda和App设置不同的标志,你也可以在应用中使用'set_target_properties',并将默认的CXX标志设置为只有两个共享的基本集合。 – axalis
谢谢,你的帖子终于帮了我。 我把cuda部分分隔成一个库,然后在CMakeLists.txt中的任何位置玩弄我设置的标志,并删除了一些标志。最终我得到了它的工作。我不完全知道如何/为什么,但它的工作原理。 – mimre
也许我错过了一些在这里完全明显的东西,但为什么你试图将任何主机代码与nvcc连接? – talonmies
有没有办法用cmake构建一个可执行文件,它允许使用nvcc编译一部分,使用gcc/g ++编译一部分? – mimre