CMake:如何使用 Clang 和 lld 在 Windows 上使用 MinGW-w64 运行时编译 C

CMake: How to compile C on Windows with clang and lld with MinGW-w64 runtime

我正在 Windows 上构建一个 LLVM 环境,它可以在没有 Microsoft 编译器和 SDK 以及没有 GCC 编译器或 GNU 链接器的情况下工作,只有 LLVM (the official build) 和 MinGW-w64 运行时。 当使用 clang 编译器和 lld 链接器以及 x86_64-windows-gnu 目标(MinGW-w64 运行时)编译此 C 程序时,它有效:

> type c1.c
#include <stdio.h>

int main() {
    printf("hello 1\n");
    return 0;
}

> clang c1.c -target x86_64-windows-gnu -fuse-ld=lld -o c1.exe

> c1
hello 1

如何用CMake实现同样的功能? CMake 是否有高级选项来自动设置这些标志?或者,当尝试手动设置这些标志时(使用 CMAKE_EXE_LINKER_FLAGSCMAKE_C_FLAGS)看起来它混淆了 CMake 并且它仍然在链接期间传递一些 Visual C++ 样式标志(如 /subsystem:console):

> type CMakeLists.txt
project (P1 C)
cmake_minimum_required(VERSION 3.0)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -target x86_64-windows-gnu -fuse-ld=lld")
add_executable (c1 c1.c)

> cmake -G Ninja -B build -DCMAKE_C_COMPILER=clang
-- The C compiler identification is Clang 12.0.0 with GNU-like command-line
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/LLVM/bin/clang.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/build

> cmake --build build
[2/2] Linking C executable c1.exe
FAILED: c1.exe
cmd.exe /C "cd . && C:\PROGRA~1\LLVM\bin\clang.exe -fuse-ld=lld-link -nostartfiles -nostdlib -g -Xclang -gcodeview -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -target x86_64-windows-gnu -fuse-ld=lld  -Xlinker /subsystem:console CMakeFiles/c1.dir/c1.c.obj -o c1.exe -Xlinker /implib:c1.lib -Xlinker /pdb:c1.pdb -Xlinker /version:0.0   -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames && cd ."
lld: error: unable to find library -loldnames
clang: error: linker command failed with 

请在此处查看有关工具链的文档:https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-using-clang

由于您要覆盖默认的 Clang 目标,CMake 需要在编译器检测期间知道这一点。当您进入 CMakeLists.txt 时,为时已晚。以下 clang-x86_64_windows_gnu.cmake 工具链文件可能有效(我无法在不复制您的环境的情况下对其进行测试):

set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET x86_64-windows-gnu)

set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld")

那你的CMakeLists.txt错了,应该是:

cmake_minimum_required(VERSION 3.20)
project(P1 LANGUAGES C)

add_executable(c1 c1.c)

注意 cmake_minimum_requiredproject 命令的顺序。它们应该 始终 是您 CMakeLists.txt 中的前两行。