cmake链接了boost/cmake的多个版本的源文件的单独汇编

Cmake links multiple versions of boost/Cmake separate compilation of source files

本文关键字:cmake 版本 源文件 单独 汇编 boost 链接      更新时间:2023-10-16

我正在尝试在集群上构建我的项目,因此我对环境没有任何影响(即没有sudo)。在我本地的机器上,我可以使它工作。

这里的问题:我的项目包含CUDA文件以及C 代码。后一个需要一个需要GCC/G > 6的库(也许> 5也可以使用,Afaik std = C 14)。另一方面,CUDA代码从CUDA 7.5开始需要GCC<5。

我已经通过使用G 6.2.0作为标准编译器来完成此问题,并使用-ccbin/path/path/path/path/gcc-4.x通过其他GCC。

因此,我的代码可以很好地编译,但是问题在于它还使用了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)

感谢您的任何帮助,我非常感谢。

要改进我建议使用boost查找脚本提供的变量而不是手动设置(但是,这很可能对问题本身无济于事,但总体上是好的,):

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_USE_STATIC_LIBS打开/关闭)。

)。

例如,您可以从CUDA代码创建共享库:

cuda_add_library(isosurfaces_cuda ${CUDA_FILES} SHARED)
add_executable(isosurfaces ${SOURCE_FILES})
target_link_libraries(isosurfaces
    isosurfaces_cuda
    ${Boost_LIBRARIES}
    ${CUDA_LIBRARIES}
    ${CMAKE_THREAD_LIBS_INIT}
)

然后,只要您不使用CUDA代码和其余C 代码之间的接口中的Boost。

它也可以帮助使用可见性属性并默认隐藏所有符号,因此,如果从剩余的C 创建库,则不会从CUDA共享库中导出Boost Library符号(或反之亦然)代码)。为此,可以使用" -fvisibility=hidden"编译器标志和" -Wl,--exclude-libs=ALL -Wl,--discard-all"链接标志。