繁体   English   中英

如何使用 CMake 为 Visual Studio 解决方案设置程序集引用?

[英]How to set assembly references for Visual Studio solution using CMake?

我正在使用 C 代码,其中生产编译器和 CI 在 Linux 中运行,但开发环境是 Windows 和 VS。 使用的测试框架是 NUnit,它是用 C# 编写的,并通过 Nuget 作为 DLL 导入。

我习惯于 C 并编写面向目标的 CMake,但 VS 解决方案和 .NET 对我来说是未知的领域,C 和 C# 的奇怪组合并没有让事情变得更容易。 更复杂的是,有一个工具可以为 C 代码运行的平台代码生成模拟(我认为平台 Mock 是用 C++ 编写的)。

所以,我使用 CMake 3.15.3 和 Visual Studio 2017,我需要开始工作的设置如下。 顶级 CMakeLists.txt 像:

cmake_minimum_required(VERSION 3.3) 
project(MyApplication)

include(SUTWrapper)

add_subdirectory(source)
add_subdirectory(suttest)

./source/ 中的 CMakeLists.txt 像:

find_package(PlatformInterface)

add_library(${CMAKE_PROJECT_NAME} STATIC
    MyApplication.c)

target_link_libraries(${CMAKE_PROJECT_NAME}
    PUBLIC
        PlatformInterface)

./suttest/ 中的 CmakeLists.txt 像:

enable_language(CSharp)

add_executable(${CMAKE_PROJECT_NAME}_tests
    MyApplication_suite1.cs
    Program.cs
    TestUtils.cs)

add_sut_wrapper()

add_test(
    NAME
        Test${CMAKE_PROJECT_NAME}
    COMMAND
        MyApplication_tests.exe
    CONFIGURATIONS
        Debug)

在包含所有 CMake 模块的 cmake 文件夹中,文件 SUTWrapper.cmake:

function(add_sut_wrapper)
    set(PATH_TO_WRAPPER path/to/wrapper/here)
    add_library(${CMAKE_PROJECT_NAME}_wrapper STATIC
        ${PATH_TO_WRAPPER}/foo.cs
        ${PATH_TO_WRAPPER}/bar.cs
        ${PATH_TO_WRAPPER}/baz.cs)

    set_property(
        TARGET ${CMAKE_PROJECT_NAME}_wrapper
        PROPERTY
        VS_DOTNET_REFERENCES "System")

    set_property(
        TARGET ${CMAKE_PROJECT_NAME}_tests
        PROPERTY
            VS_PACKAGE_REFERENCES "NUnit_3.7.1;NUnitLite_3.7.2")

    set(PATH_TO_PLATFORM_MOCK path/to/PlatformMock/here/)
    add_library(${CMAKE_PROJECT_NAME}_Platform_Mock STATIC
        ${PATH_TO_PLATFORM_MOCK}/Swc_${CMAKE_PROJECT_NAME}.cpp)

    add_library(${CMAKE_PROJECT_NAME}_shared SHARED
        ../source/MyApplication.c)

    target_link_libraries(${CMAKE_PROJECT_NAME}_shared
        PUBLIC
            PlatformInterface
            ${CMAKE_PROJECT_NAME}_Platform_Mock)

    target_link_libraries(${CMAKE_PROJECT_NAME}_tests
        PUBLIC
            ${CMAKE_PROJECT_NAME}_shared)

endfunction()

然后cmake文件夹下还有一个文件FindPlatformInterface.cmake:

add_library(PlatformInterface INTERFACE)

target_include_directories(PlatformInterface 
    INTERFACE
        path/to/PlatformInterface/headers/here
        path/to/more/PlatformInterface/headers/here)

将 find_package 用于 PlatformInterface 的非正统使用是一种临时解决方法,add_sut_wrapper 函数是一种处理在构建此 CMake 项目之前已生成大量包装器代码的方法。 我正在处理大量遗留问题,迫使一些奇怪的工作变通,对于奇怪的事情感到抱歉。

据我了解,NUnit 设置希望将测试构建为链接到应用程序代码的 DLL(进而与 PlatformInterface、PlatformMock 链接)的可执行文件。

这一切在运行 CMake 时都会生成一个 VS 解决方案,没有任何警告,但是当我尝试在 VS 中构建解决方案时,我收到此错误:

错误 CS0246 找不到类型或命名空间名称“Vector”(您是否缺少 using 指令或程序集引用?) MyApplication_tests

Vector 是静态库中名为 MyApplication_wrapper 的命名空间。 所以很明显我链接了包含 Vector 的代码。 我之前遇到过类似的问题,使用命名空间 System 并链接到 NUnit,我通过添加解决了这个问题

set_property(
    TARGET ${CMAKE_PROJECT_NAME}_wrapper
    PROPERTY
    VS_DOTNET_REFERENCES "System")

set_property(
    TARGET ${CMAKE_PROJECT_NAME}_tests
    PROPERTY
        VS_PACKAGE_REFERENCES "NUnit_3.7.1;NUnitLite_3.7.2")

到函数 add_sut_wrapper。 我只是不知道如何为 Vector 添加程序集引用。

我不得不稍微混淆名称和路径,我试图删除一些不相关的细节,但我认为要点就在那里。

如果您希望可以从MyApplication_tests目标访问Vector命名空间,则必须将包含Vector的包装库链接到该目标。 尝试更改您的target_link_libraries()调用以包含MyApplication_tests

此外,不鼓励在 CMake 中使用STATIC C# 目标,并且不保证将来会支持。 C# 术语并没有真正使用 C/C++ 中使用的“静态”和“共享”库术语; 相反,通常使用“netmodule”和“assembly”(请参阅​​此博客文章)。 使用 CMake 定义 C# 库时,您应该使用程序集 ( SHARED ):

add_library(${CMAKE_PROJECT_NAME}_wrapper SHARED
    ${PATH_TO_WRAPPER}/foo.cs
    ${PATH_TO_WRAPPER}/bar.cs
    ${PATH_TO_WRAPPER}/baz.cs)    

...

target_link_libraries(${CMAKE_PROJECT_NAME}_tests
    PUBLIC
        ${CMAKE_PROJECT_NAME}_wrapper
        ${CMAKE_PROJECT_NAME}_shared)

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM