CUDA: corner case failure with modern CMake approach
I am on Ubuntu 18.04, GCC 7.3, CUDA 9.1, latest CMake. I encountered a weird problem where a segfault will happen in an application I simply calls a constructor from a nvcc compiled shared library that links to another nvcc compiled shared library that links to a static cpp library.
CMakeLists
cmake_minimum_required(VERSION 3.11)
project(example LANGUAGES CXX CUDA)
set(EXAMPLE1_SRCS ${PROJECT_SOURCE_DIR}/example1.cpp)
set(EXAMPLE1_INCS ${PROJECT_SOURCE_DIR}/example1.h)
add_library(example1 STATIC ${EXAMPLE1_SRCS} ${EXAMPLE1_INCS})
target_include_directories(example1 PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
set(EXAMPLE2_SRCS ${PROJECT_SOURCE_DIR}/example2.cu)
set(EXAMPLE2_INCS ${PROJECT_SOURCE_DIR}/example2.cuh)
add_library(example2 SHARED ${EXAMPLE2_SRCS} ${EXAMPLE2_INCS})
target_include_directories(example2 PUBLIC
$<BUILD_INTERFACE:${EXAMPLE2_SOURCE_DIR}>)
target_link_libraries(example2 example1)
set(EXAMPLE3_SRCS ${PROJECT_SOURCE_DIR}/example3.cu)
set(EXAMPLE3_INCS ${PROJECT_SOURCE_DIR}/example3.cuh)
add_library(example3 SHARED ${EXAMPLE3_SRCS} ${EXAMPLE3_INCS})
target_include_directories(example3 PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
target_link_libraries(example3 example2)
set(PROJECT_SRCS ${PROJECT_SOURCE_DIR}/TestTest.cpp)
add_executable(TestTest ${PROJECT_SRCS})
target_link_libraries(TestTest example3)
example1.h is simply
class example1{
public:
example1();
~example1();
};
example1.cpp is simply
#include "example1.h"
example1::example1(){
}
example1::~example1(){
}
example2.cuh is simply
class example2{
public:
example2();
~example2();
};
example2.cu is simply
#include "example2.cuh"
example2::example2(){
}
example2::~example2(){
}
example3.cuh is simply
class example3{
public:
example3();
~example3();
};
example3.cu is simply
#include "example3.h"
example3::example3(){
}
example3::~example3(){
}
TestTest.cpp is
#include "example3.cuh"
int main(){
example3 e;
return 0;
}
After mkdir build && cd build
, cmake ..
, make
, ./TestTest
it will show Segmentation fault. I tried linking example3
to example1
instead of example2
and the program runs fine, I tried changing example1
to a shared library it also runs fine. I tried not linking example1
to example2
it also runs too. Weirdly enough, if I revert to the old way of using CUDA in CMake like this
cmake_minimum_required(VERSION 3.11)
project(example)
find_package( CUDA REQUIRED )
set(EXAMPLE1_SRCS ${PROJECT_SOURCE_DIR}/example1.cpp)
set(EXAMPLE1_INCS ${PROJECT_SOURCE_DIR}/example1.h)
add_library(example1 STATIC ${EXAMPLE1_SRCS} ${EXAMPLE1_INCS})
target_include_directories(example1 PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
set(EXAMPLE2_SRCS ${PROJECT_SOURCE_DIR}/example2.cu)
set(EXAMPLE2_INCS ${PROJECT_SOURCE_DIR}/example2.cuh)
cuda_add_library(example2 SHARED ${EXAMPLE2_SRCS} ${EXAMPLE2_INCS})
target_include_directories(example2 PUBLIC
$<BUILD_INTERFACE:${EXAMPLE2_SOURCE_DIR}>)
target_link_libraries(example2 example1)
set(EXAMPLE3_SRCS ${PROJECT_SOURCE_DIR}/example3.cu)
set(EXAMPLE3_INCS ${PROJECT_SOURCE_DIR}/example3.cuh)
cuda_add_library(example3 SHARED ${EXAMPLE3_SRCS} ${EXAMPLE3_INCS})
target_include_directories(example3 PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
target_link_libraries(example3 example2)
set(PROJECT_SRCS ${PROJECT_SOURCE_DIR}/TestTest.cpp)
add_executable(TestTest ${PROJECT_SRCS})
target_link_libraries(TestTest example3)
This also works too. I also tried downgrading gcc to 6 and the same segfault shows up.
It seems like it's the combination of modern CUDA CMake with an application that links to nvcc compiled shared library that links to another nvcc compiled shared library that links to a static cpp library that triggers the segfault. I am able to reproduce this in another computer too. Can someone solve this so I don't have to revert my main project to the old way of using CUDA in CMake?