【问题标题】:CMake with clang shows undefined symbol, and with cl links correctly带有clang的CMake显示未定义的符号,并且带有正确的cl链接
【发布时间】:2021-01-01 19:23:56
【问题描述】:

TLDR

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

版本:

  • cmake 版本 3.18.1

  • clang 版本 11.0.0

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

小例子

我的项目结构如下:

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 的错误。

【问题讨论】:

    标签: c++ makefile cmake nmake cl


    【解决方案1】:

    我刚刚遇到了同样的问题,但使用 Clang 13。可以通过在 CMakeLists 中将 clang 指定为编译器来解决,而不是让 CMake 自动确定它。

    set(CMAKE_CXX_COMPILER "clang++")
    

    (是的,我正确地阅读了您的原始问题,使用这个:

    -DCMAKE_CXX_COMPILER=clang++
    

    作为 cmake 的附加参数对我也不起作用,即使它看起来应该与在 CMakeLists.txt 中设置它的行为相同)

    【讨论】:

      【解决方案2】:

      我再次测试:

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

      而且它运行良好。好像是clang 11的问题

      【讨论】:

        猜你喜欢
        • 2022-09-27
        • 2014-09-08
        • 2016-09-06
        • 1970-01-01
        • 2015-07-06
        • 1970-01-01
        • 2020-02-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多