Cmake 和包含第三方库的问题

问题描述 投票:0回答:1

我正在尝试为我的 CUDA 项目正确配置 Cmake。我正在使用第三方库 CGBN:https://github.com/NVlabs/CGBN/tree/master 和 Catch2 进行单元测试。

基本上我正在尝试构建两个目标:主目标和测试。
问题是,当我尝试为目标编译多个源文件(其中包括包含此 CGBN 头文件的头文件)时,我在构建过程中遇到了多重定义错误

CGBN 库中的示例在 Makefile 中使用此命令:

nvcc $(INC) $(LIB) -I../../include -arch=sm_70 modinv_odd_faster.cu -o mo_faster -lgmp
所以我使用
target_include_directories
-I
标志从 Makefile 映射到我的 Cmake。

示例:

add_executable(
tests
tests/test_add_points_ECC79p.cu -> includes header file main.cuh which itself includes cgbn
src/main.cu -> includes main.cuh too
).

完成Cmake配置:

    cmake_minimum_required(VERSION 3.28)
    project(cuda-rho-pollard CUDA)
    
    # General
    set(CMAKE_CUDA_STANDARD 17)
    set(CMAKE_CUDA_ARCHITECTURES 75)
    
    # MAIN
    add_executable(main
            src/main.cu
            src/test.cu
    )
    # set_target_properties(main PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
    
    # CGBN
    target_link_libraries(main PRIVATE gmp)
    target_include_directories(main PRIVATE include/CGBN/include)
    
    # TESTS
    find_package(Catch2 3 REQUIRED)
    
    add_executable(
            tests
            tests/test_add_points_ECC79p.cu
            src/main.cu
            )
    target_compile_definitions(tests PRIVATE UNIT_TESTING)
    
    # CGBN
    target_link_libraries(tests PRIVATE gmp)
    target_include_directories(tests PRIVATE include/CGBN/include)
    
    set_target_properties(tests PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
    set_target_properties(tests PROPERTIES LINKER_LANGUAGE CUDA)
    target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)
    
    include(CTest)
    include(Catch)
    catch_discover_tests(tests)

我收到的错误消息:

[main] Building folder: /home/atlomak/PROJECTS/inz/thesis/build tests
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /home/atlomak/PROJECTS/inz/thesis/build --config Debug --target tests --
[build] [2/4  25% :: 1.897] Building CUDA object CMakeFiles/tests.dir/tests/test_add_points_ECC79p.cu.o
[build] [2/4  50% :: 4.417] Building CUDA object CMakeFiles/tests.dir/src/main.cu.o
[build] [3/4  75% :: 4.487] Linking CUDA executable CMakeFiles/tests.dir/cmake_device_link.o
[build] [4/4 100% :: 4.686] Linking CUDA executable tests
[build] FAILED: tests tests-b12d07c_tests.cmake /home/atlomak/PROJECTS/inz/thesis/build/tests-b12d07c_tests.cmake 
[build] : && /usr/bin/g++  CMakeFiles/tests.dir/tests/test_add_points_ECC79p.cu.o CMakeFiles/tests.dir/src/main.cu.o CMakeFiles/tests.dir/cmake_device_link.o -o tests  -lgmp  /usr/lib64/libCatch2Main.a  /usr/lib64/libCatch2.a  -lcudadevrt  -lcudart_static  -lrt  -lpthread  -ldl -L"/usr/local/cuda-12.4/targets/x86_64-linux/lib/stubs" -L"/usr/local/cuda-12.4/targets/x86_64-linux/lib" && cd /home/atlomak/PROJECTS/inz/thesis/build && /usr/bin/cmake -D TEST_TARGET=tests -D TEST_EXECUTABLE=/home/atlomak/PROJECTS/inz/thesis/build/tests -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/atlomak/PROJECTS/inz/thesis/build -D TEST_SPEC= -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_LIST=tests_TESTS -D TEST_REPORTER= -D TEST_OUTPUT_DIR= -D TEST_OUTPUT_PREFIX= -D TEST_OUTPUT_SUFFIX= -D TEST_DL_PATHS= -D CTEST_FILE=/home/atlomak/PROJECTS/inz/thesis/build/tests-b12d07c_tests.cmake -P /usr/lib64/cmake/Catch2/CatchAddTests.cmake
[build] /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/tests.dir/src/main.cu.o: in function `cgbn_error_report_alloc(cgbn_error_report_t**)':
[build] /home/atlomak/PROJECTS/inz/thesis/include/CGBN/include/cgbn/cgbn.cu:25: multiple definition of `cgbn_error_report_alloc(cgbn_error_report_t**)'; CMakeFiles/tests.dir/tests/test_add_points_ECC79p.cu.o:/home/atlomak/PROJECTS/inz/thesis/include/CGBN/include/cgbn/cgbn.cu:25: first defined here
[build] /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/tests.dir/src/main.cu.o: in function `cgbn_error_report_free(cgbn_error_report_t*)':
[build] /home/atlomak/PROJECTS/inz/thesis/include/CGBN/include/cgbn/cgbn.cu:42: multiple definition of `cgbn_error_report_free(cgbn_error_report_t*)'; CMakeFiles/tests.dir/tests/test_add_points_ECC79p.cu.o:/home/atlomak/PROJECTS/inz/thesis/include/CGBN/include/cgbn/cgbn.cu:42: first defined here
[build] /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/tests.dir/src/main.cu.o: in function `cgbn_error_report_check(cgbn_error_report_t*)':
[build] /home/atlomak/PROJECTS/inz/thesis/include/CGBN/include/cgbn/cgbn.cu:46: multiple definition of `cgbn_error_report_check(cgbn_error_report_t*)'; CMakeFiles/tests.dir/tests/test_add_points_ECC79p.cu.o:/home/atlomak/PROJECTS/inz/thesis/include/CGBN/include/cgbn/cgbn.cu:46: first defined here
[build] /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/tests.dir/src/main.cu.o: in function `cgbn_error_report_reset(cgbn_error_report_t*)':
[build] /home/atlomak/PROJECTS/inz/thesis/include/CGBN/include/cgbn/cgbn.cu:50: multiple definition of `cgbn_error_report_reset(cgbn_error_report_t*)'; CMakeFiles/tests.dir/tests/test_add_points_ECC79p.cu.o:/home/atlomak/PROJECTS/inz/thesis/include/CGBN/include/cgbn/cgbn.cu:50: first defined here
[build] /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/tests.dir/src/main.cu.o: in function `cgbn_error_string(cgbn_error_report_t*)':
[build] /home/atlomak/PROJECTS/inz/thesis/include/CGBN/include/cgbn/cgbn.cu:61: multiple definition of `cgbn_error_string(cgbn_error_report_t*)'; CMakeFiles/tests.dir/tests/test_add_points_ECC79p.cu.o:/home/atlomak/PROJECTS/inz/thesis/include/CGBN/include/cgbn/cgbn.cu:61: first defined here
[build] /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/tests.dir/src/main.cu.o: in function `cgbn_check(cgbn_error_report_t*, char const*, int)':
[build] /home/atlomak/PROJECTS/inz/thesis/src/main.cuh:15: multiple definition of `cgbn_check(cgbn_error_report_t*, char const*, int)'; CMakeFiles/tests.dir/tests/test_add_points_ECC79p.cu.o:/home/atlomak/PROJECTS/inz/thesis/tests/../src/main.cuh:15: first defined here
[build] collect2: error: ld returned 1 exit status
[build] ninja: build stopped: subcommand failed.
[proc] The command: /usr/bin/cmake --build /home/atlomak/PROJECTS/inz/thesis/build --config Debug --target tests -- exited with code: 1
[driver] Build completed: 00:00:04.708
[build] Build finished with exit code 1

项目仓库供参考:project

我对如何处理这个问题没有更多的想法。怎样做才是正确的?
编译测试目标的唯一方法是直接将

src/main.cu
文件包含在
tests/test_add_points_ECC79p.cu
中。但我认为这也不是正确的方法。
我对 Cmake/C/Cuda 不太有经验(在我的日常工作中,我主要处理 Go 和 Python)。 将不胜感激任何帮助。

我尝试将库中的源代码编译为

add_library
,然后仅包含一个头文件,但也出现了编译错误。我认为这不是正确的方法,因为它迫使我查看库中的所有源文件并事实上为其创建构建脚本。

c++ cmake cuda
1个回答
0
投票

不幸的是,我无法测试您的代码,因为我的计算机环境不支持 CUDA,但是我看到您的错误消息表明您的链接器抱怨您正在以某种不受支持的方式重新定义函数。因此,我会尝试通过保护命名空间内重新定义的函数来解决这个问题,如本示例代码所示:

#include <iostream>

class A {
        public: 
                void test_message(){
                std::cout << "hello from global A" << std::endl;
                }
};

namespace redefineme {
        class A{
                public: 
                        void test_message(){
                                std::cout << "hello from scoped A" << std::endl;
                        }
        };
}

int main(){
        redefineme::A test_redefine = *(new redefineme::A());
        test_redefine.test_message();
}

打印

hello from scoped A
。更多内容请参见 c++ 命名空间

© www.soinside.com 2019 - 2024. All rights reserved.