首页 > 解决方案 > 在带有 mingw 的 Windows 上使用带有 -fprofile-instr-generate -fcoverage-mapping 的 clang++ 时出现链接错误

问题描述

我最近使用 mingw 在 Windows 机器上将我的工具链从 gcc 更改为 clang。到目前为止一切正常,但现在我正在尝试直接集成 llvm 提供的代码覆盖功能(而不是 gcov 接口),我正在努力完成这项任务。

添加两个编译器选项后,-fprofile-instr-generate -fcoverage-mapping我开始遇到奇怪的链接错误。研究这个问题,我发现了一些提示,我需要添加-fprofile-instr-generate到链接器并将 compiler-rt 库libclang_rt.profile-i386.a(我尝试编译为 32 位)也提供给链接器。但即使在这样做之后,多个符号定义和未定义符号的链接错误仍然存​​在。

虽然覆盖范围llvm-cov gcov和编译器选项--coverage工作正常。我只是认为留在 llvm 环境中会更好,而且我不需要使用 gcovr 等其他工具来创建覆盖率报告。另外我听说原始的 llvm 工具提供了更好的覆盖结果......

我正在使用带有 clang 10 的 mingw32。

我还发现了clang-cl在 Windows 机器上使用而不是使用的建议,clang++但这让我遇到了其他问题,因为我之前没有为 msvc 编译过......

你对此有什么建议吗?谢谢 :)

更新

最小的例子(结合 googletest 在目录中..\googletest):

CMakeLists.txt

cmake_minimum_required(VERSION 3.17.0)
project(minimal_example)

set(COMPILE_OPTIONS 
  -m32
  -O0
  -g

  #the problem starts here
  -fprofile-instr-generate=foo.profraw
  -fcoverage-mapping
)

add_compile_options("${COMPILE_OPTIONS}")
set(CMAKE_EXE_LINKER_FLAGS  "-m32 -fprofile-instr-generate=foo.profraw")

link_directories("C:/msys64/mingw32/lib/clang/10.0.0/lib/windows")

include_directories("../googletest")
add_subdirectory(../googletest ${CMAKE_BINARY_DIR}/unittest)

add_executable(minimal_example MyExampleMain.cpp)
target_link_libraries(minimal_example gtest_main clang_rt.profile-i386)

MyExampleMain.cpp

#include "gtest/gtest.h"

TEST(TestSuite1, Test1)
{
  int x(0);
  int y(3);
  if(x==5)
  {
      y=0;
  }
  EXPECT_EQ(3, y);  
}

我使用以下命令调用 cmake:cmake -Bbuild -G "Unix Makefiles" -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang

产生的链接错误完全填满标准 cmd 缓冲区。

一个例子是:C:\msys64\mingw32\bin\ld: lib/libgtest.a(gtest-all.cc.obj): in function `ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_N7testing8internal12CodeLocationEESt10_Select1stISB_ESt4lessIS5_ESaISB_EE3endEv': C:\/msys64\mingw32\include\c++\10.1.0\bits\stl_tree.h:1011: undefined reference to `__profc__ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_N7testing8internal12CodeLocationEESt10_Select1stISB_ESt4lessIS5_ESaISB_EE3endEv'

通过忽略最小示例的错误,我找不到我在生产代码中观察到的多个符号定义链接错误中的任何一个......

更新 2

链接错误似乎仅与 googletest 框架有关。当编译一个没有 googletest 的简单程序时

#include <iostream>

int main()
{
  int x(0);
  if (x == 1)
  {
    std::cout<<"This is impossible"<<std::endl;
  } 
  else
  {
    std::cout<<"This is more likely"<<std::endl;
  }
  return 0;
}

程序被链接并正确执行。还foo.profraw创建了一个文件。但是创建的输出 proraw 文件是空的。我猜不应该是这种情况。

标签: c++linkerclangmingwcode-coverage

解决方案


推荐阅读