带有 clang 的 CMake 显示未定义的符号,并且带有正确的 cl 链接 正确链接未定义符号

问题描述

TLDR

我正在构建一个静态库并将其链接一个可执行文件。我用 cmake 生成 makefile。当我为 cl(visual studio 的编译器)生成 makefile 时,我没有问题,但是当我为 clang 生成 makefile 时,我得到一个未定义的符号。

版本:

  • cmake 3.18.1 版

  • clang 11.0.0 版

    • 目标:x86_64-pc-windows-msvc
    • 线程模型:posix
  • 用于 x64 的 cl 版本 19.26.28806

最小示例

我有以下项目结构:

Proyect Root
│   CMakeLists.txt
│   foo.cpp
│   foo.hpp
│   main.cpp
│
└───bin

这是文件内容

foo.hpp

namespace foo {
    void do_stuff(void);
}

foo.cpp

#include <foo.hpp>

namespace foo {

void do_stuff(void) {}

}

ma​​in.cpp

#include <foo.hpp>

int main(void) {
    foo::do_stuff();
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(CompileAndLinkLib)

include_directories(".")

file(GLOB FOO_SRC "foo.cpp")
add_library(foo STATIC ${FOO_SRC})

add_executable(main "main.cpp")
target_link_libraries(main foo)

正确链接

首先我调用 vcvarsall.bat。我使用以下命令生成一个 nmake 文件

cmake .. -G "NMake Makefiles"

并编译:

nmake

项目编译和链接正确

未定义符号

我使用以下命令生成 make 文件

cmake .. -G "Unix Makefiles" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++

当我用 make 编译时,我得到以下输出

Scanning dependencies of target foo
[ 25%] Building CXX object CMakeFiles/foo.dir/foo.cpp.obj
[ 50%] Linking CXX static library foo.lib
[ 50%] Built target foo
Scanning dependencies of target main
[ 75%] Building CXX object CMakeFiles/main.dir/main.cpp.obj
[100%] Linking CXX executable main.exe
lld-link: error: undefined symbol: void __cdecl foo::do_stuff(void)
>>> referenced by C:\Users\pabsa\temp\main.cpp:4
>>>               CMakeFiles/main.dir/main.cpp.obj:(main)
clang++: error: linker command Failed with exit code 1 (use -v to see invocation)
make[2]: *** [main.exe] Error 1
make[1]: *** [CMakeFiles/main.dir/all] Error 2
make: *** [all] Error 2

我不确定我是否做错了什么,比如我是否遗漏了什么,或者这是否是由 cmake 生成的 makefile 的错误

解决方法

我再次测试:

  • clang 版本 12.0.0
    • 目标:x86_64-pc-windows-msvc
    • 线程模型:posix

它工作得很好。好像是clang 11的问题