简体   繁体   English

链接器未链接我自己的静态库

[英]Linker not linking my own static library

I'm trying to create an application combining Qt 5, VTK 8.0.1 and CUDA 9.1 in Windows 10 x64, using the MSVC 14 (2015, v140) compiler. 我正在尝试使用MSVC 14(2015,v140)编译器在Windows 10 x64中创建结合Qt 5,VTK 8.0.1和CUDA 9.1的应用程序。

Because of VTK, this pretty much has to be done using CMake as opposed to Visual Studio. 由于存在VTK,这几乎必须使用CMake而非Visual Studio来完成。 I have built VTK 8.0.1 from source with the same compiler as above for x64 Release and Debug, and the dlls are in the PATH. 我已经使用与上述x64 Release和Debug相同的编译器从源代码构建了VTK 8.0.1,并且dll位于PATH中。

My project structure is just a single folder with everything in it (the three files below). 我的项目结构只是一个包含所有内容的文件夹(下面的三个文件)。

I decided that the simplest way of handling the different compilation needs for each library was to create a separate static library for CUDA and link it afterwards, everything else being compiled into an executable. 我认为处理每个库的不同编译需求的最简单方法是为CUDA创建一个单独的静态库,然后将其链接,其他所有内容都编译成可执行文件。

The problem is that doesn't matter what I do I get the error below when building 问题是,不管我做什么,我在构建时都会收到以下错误

main.cpp.obj:-1: error: LNK2019: unresolved external symbol addKernel referenced in function "enum cudaError __cdecl addWithCuda(int *,int const *,int const *,unsigned int)" (?addWithCuda@@YA?AW4cudaError@@PEAHPEBH1I@Z)

I'm positive this has something to do with some form of C/C++ name mangling conflict, but that only gets me so far. 我很肯定,这与某种形式的C / C ++名称修改冲突有关,但这只能使我走远。

Please, save my christmas 拜托,保存我的圣诞节

Here is my CMakeLists.txt : 这是我的CMakeLists.txt

cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
project(Test2 LANGUAGES CXX CUDA)

# QT5
find_package(Qt5Widgets)

# VTK
set(VTK_DIR "correctPath" CACHE PATH directory FORCE)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
#message(${VTK_LIBRARIES})

# CUDA
find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})
#message(STATUS "CUDA_LIBRARIES: ${CUDA_INCLUDE_DIRS} ${CUDA_LIBRARIES}")

# Adds all the desired files to their lists
set(SOURCES
    main.cpp
    )

set(KERNELS
    kernelOnly.cu
    )

set(HEADERS
    )

set(UI
    )

set(RESOURCES
    )

# Processes Qt files
QT5_WRAP_CPP(HEADERS_MOC ${HEADERS})
QT5_WRAP_UI(UI_MOC ${UI})
QT5_ADD_RESOURCES(RESOURCES_RCC ${RESOURCES})

# Include bin directories so we can find MOC'd stuff later
set(CMAKE_INCLUDE_CURRENT_DIR ON)
include_directories (${PROJECT_SOURCE_DIR})
include_directories (${PROJECT_BINARY_DIR})

# Compile our CUDA kernel library
list(APPEND CUDA_NVCC_FLAGS -gencode=arch=compute_61,code=sm_61)
add_library(CudaLib STATIC ${KERNELS})
target_compile_features(CudaLib PUBLIC cxx_std_11)
set_target_properties(CudaLib PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
set_target_properties(CudaLib PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)

# Compile Qt+VTK+Cpp into an executable
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS_MOC} ${UI_MOC} ${RESOURCES_RCC})
set_target_properties(${PROJECT_NAME} PROPERTIES CUDA_SEPARABLE_COMPILATION ON)

# Link libraries to the executable
target_link_libraries(${PROJECT_NAME}
    CudaLib
    Qt5::Widgets
    ${VTK_LIBRARIES}
    ${CUDA_LIBRARIES}
    ${CUDA_cusparse_LIBRARY}
    ${CUDA_cublas_LIBRARY}
    )

My main.cpp : 我的main.cpp

#include <cuda_runtime.h>

#include <stdio.h>

#include <QApplication>
#include <QVTKWidget.h>

#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>

cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);
extern "C" void addKernel(int* c, const int* a, const int* b);

int main(int argc, char** argv)
{
    const int arraySize = 5;
    const int a[arraySize] = { 1, 2, 3, 4, 5 };
    const int b[arraySize] = { 10, 20, 30, 40, 50 };
    int c[arraySize] = { 0 };

    // Add vectors in parallel.
    cudaError_t cudaStatus = addWithCuda(c, a, b, arraySize);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "addWithCuda failed!");
        return 1;
    }

    printf("{1,2,3,4,5} + {10,20,30,40,50} = {%d,%d,%d,%d,%d}\n",
        c[0], c[1], c[2], c[3], c[4]);

    // cudaDeviceReset must be called before exiting in order for profiling and
    // tracing tools such as Nsight and Visual Profiler to show complete traces.
    cudaStatus = cudaDeviceReset();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaDeviceReset failed!");
        return 1;
    }
}

// Helper function for using CUDA to add vectors in parallel.
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size)
{
    int *dev_a = 0;
    int *dev_b = 0;
    int *dev_c = 0;
    cudaError_t cudaStatus;

    // Choose which GPU to run on, change this on a multi-GPU system.
    cudaStatus = cudaSetDevice(0);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");
        goto Error;
    }

    // Allocate GPU buffers for three vectors (two input, one output)    .
    cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(int));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!");
        goto Error;
    }

    cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!");
        goto Error;
    }

    cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(int));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!");
        goto Error;
    }

    // Copy input vectors from host memory to GPU buffers.
    cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
        goto Error;
    }

    cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
        goto Error;
    }

    // Launch a kernel on the GPU with one thread for each element.
    // replaces addKernel<<<1, size>>>(dev_c, dev_a, dev_b) syntax
    void* args[] = { &dev_c, &dev_a, &dev_b };
    cudaStatus = cudaLaunchKernel(
      (const void*)&addKernel, // pointer to kernel func.
                      dim3(1), // grid
                   dim3(size), // block
                         args  // arguments
    );

    // Check for any errors launching the kernel
    cudaStatus = cudaGetLastError();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));
        goto Error;
    }

    // cudaDeviceSynchronize waits for the kernel to finish, and returns
    // any errors encountered during the launch.
    cudaStatus = cudaDeviceSynchronize();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
        goto Error;
    }

    // Copy output vector from GPU buffer to host memory.
    cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
        goto Error;
    }

Error:
    cudaFree(dev_c);
    cudaFree(dev_a);
    cudaFree(dev_b);

    return cudaStatus;
}

and my kernelOnly.cu : 和我的kernelOnly.cu

#include <device_launch_parameters.h>

__global__ void addKernel(int *c, const int *a, const int *b)
{
    int i = threadIdx.x;
    c[i] = a[i] + b[i];
}

I think it should be: 我认为应该是:

extern void addKernel(int* c, const int* a, const int* b);

with the "C" . "C"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 与我自己的静态库链接的问题 - Issues Linking with my own static library 链接器正在寻找链接到我自己的静态库的静态库 - Linker is looking for the static libraries that was linked to my own static library 链接自己的静态库时无法解析的外部符号 - Unresolved external symbol when linking my own static library g ++链接器:如果存在静态库,则强制静态链接? - g++ linker: force static linking if static library exists? dll链接静态库-未使用函数中未解析的链接器符号 - dll linking static library - unresolved linker symbols from unused functions 由于忘记了源文件,在链接我自己的静态库时检测到未解析的符号 - Detect unresolved symbols when linking my own static library due to forgotten source files 将构建的 libevent 作为 static 库链接时出现 Linker 错误,但在作为共享库链接时有效 - Linker errors when linking a built libevent as a static library, but works when linking as a shared library 在我的项目中针对libunwind链接库时出现链接器错误 - Getting linker errors when linking against libunwind for a library in my project 静态库的链接器错误 - Linker Error With Static Library Linker 错误编译使用 Boost.Thread 的可执行文件链接到使用 Boost.Thread 的 static 库 - Linker error compiling an executable which uses Boost.Thread linking to a static library using Boost.Thread
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM