使用 Clang 编译器通过 Make 构建 LLVM 项目时出现奇怪的标志

Weird flags when building LLVM project with Make using the Clang Compiler

我最近将 LLVM 构建到以下路径中:C:\LLVM\llvm-new-build。然后我将此路径添加到我的环境 Variables/Path、C:\LLVM\llvm-new-build\Debug\bin。我正在尝试构建我的 LLVM 项目,但我从 Clang 得到了一些奇怪的输出:

clang `llvm-config --cflags` -Wall -Iincludes/ src/*.c -c src/*.c
clang.exe: error: unknown argument: '-wd4146'
clang.exe: error: unknown argument: '-wd4180'
clang.exe: error: unknown argument: '-wd4244'
clang.exe: error: unknown argument: '-wd4258'
clang.exe: error: unknown argument: '-wd4267'
clang.exe: error: unknown argument: '-wd4291'
clang.exe: error: unknown argument: '-wd4345'
clang.exe: error: unknown argument: '-wd4351'
clang.exe: error: unknown argument: '-wd4355'
clang.exe: error: unknown argument: '-wd4456'
clang.exe: error: unknown argument: '-wd4457'
clang.exe: error: unknown argument: '-wd4458'
clang.exe: error: unknown argument: '-wd4459'
clang.exe: error: unknown argument: '-wd4503'
clang.exe: error: unknown argument: '-wd4624'
clang.exe: error: unknown argument: '-wd4722'
clang.exe: error: unknown argument: '-wd4800'
clang.exe: error: unknown argument: '-w14062'
clang.exe: error: unknown argument: '-we4238'
clang.exe: error: no such file or directory: 'C:/Program Files (x86)/Git/DWIN32'

clang.exe: error: no such file or directory: 'C:/Program Files (x86)/Git/D_WINDO
WS'
clang.exe: error: no such file or directory: 'C:/Program Files (x86)/Git/W3'
clang.exe: error: no such file or directory: 'C:/Program Files (x86)/Git/MP'
Makefile:22: recipe for target 'all' failed
make: *** [all] Error 1

它说没有 -wd4146 等参数,但我还没有将它们传递给 clang 编译器,快速 google 搜索显示了关于这些含义的有用答案。这是我的构建文件的样子:

LCC = clang
LCXX = clang++

LLVM_CC_FLAGS=`llvm-config --cflags`
LLVM_LINK_FLAGS=`llvm-config --libs --cflags --ldflags core analysis executionengine jit interpreter native`

C_FLAGS = -Wall -Iincludes/
CXX_FLAGS = -Wall -Wextra -Wno-self-assign

SOURCES = src/*.c

all: ${SOURCES}
    ${LCC} ${LLVM_CC_FLAGS} ${C_FLAGS} ${SOURCES} -c ${SOURCES}
    ${LCXX} ${LLVM_LINK_FLAGS} *.o ${LLVM_FLAGS} -o j4
    -rm *.o

llvm-config --cflags

的输出
-IC:/LLVM/llvm/include -IC:/LLVM/llvm-new-build/include  /DWIN32 /D_WINDOWS /W3
  /MP -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEP
RECATE -D_CRT_NONSTDC_NO_WARNINGS -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WA
RNINGS -wd4146 -wd4180 -wd4244 -wd4258 -wd4267 -wd4291 -wd4345 -wd4351 -wd4355 -
wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4800 -w14062 -we4238 -
D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS

这个问题确实有好几层,所以我将尝试将其分为三个部分:讨论反引号内部发生的事情,未知参数错误,以及 没有这样的文件或目录 错误。

什么是 llvm-config

llvm-config 是 LLVM 基础设施的工具,它获取编译需要 LLVM 的程序所需的配置信息。因此,针对 1 的评论,llvm-config 实际上 旨在与 clang 一起使用,当 clang 用于编译 LLVM 项目时。

--cflags 选项提供 C 编译器标志,包括 LLVM headers,您在 llvm-config --cflags 的输出中看到了它。你说

"It says there are no arguments like -wd4146 etc, but I haven't passed those to the clang compiler"

但是通过将其放在反引号中,您的 shell 获取了 llvm-config --cflags 的输出并将其粘贴到您的原始命令中。所以你确实包含了那些参数,你只是没有意识到!

我还会注意到 llvm-config 的输出高度依赖于您的构建系统和 LLVM 的版本。例如,当安装在 Ubuntu Linux 14.05、带有 GNU Make 和 Ninja 生成器的 LLVM 3.5 上时,llvm-config --cflags 的输出是:

-I/.../llvm-3.5.0/llvm/include -I/.../llvm-3.5.0/build/include  -fPIC -Wall -W -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-comment -ffunction-sections -fdata-sections -g  -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS

它显然不包含任何您的违规选项,如 -wd4146-wd4180,也不包含对 Windows 或预处理器参数的任何引用。

/DWIN32/D_WINDOWS/W3/MP 等奇怪的选项是什么?

  • /D 定义源文件的预处理符号,在本例中为 WIN32 和 _WINDOWS。 2
  • /W3 指示 MSVC 显示级别 1、级别 2 和级别 3(生产质量)警告。 3
  • /MP 导致 MSVC 创建自身的多个实例并尝试并行构建项目。 4

问题是它们被传递给以正斜杠为前缀的编译器参数(请注意,所有其他选项都以连字符传递)。因此,您的构建尝试将它们作为文件名处理,如结果错误所示,例如:

clang.exe: error: no such file or directory: 'C:/Program Files (x86)/Git/DWIN32'

它为什么在 C:/Program Files (x86)/... 中查找取决于您的 LLVM 安装的某些方面 and/or 您的操作系统。我猜它是你执行路径中的最后一个位置或者它是你当前的工作目录。

-wd4146-wd4180 等奇怪的选项是什么?

这些是禁用为 MSVC 发出的某些警告的选项。例如,C4146 是“unary minus operator applied to unsigned type, result still unsigned" and C4180 is "qualifier applied to function type has no meaning; ignored

Here's an example 做完全相同的事情,但是从 GNU Make 文件内部而不是从命令行(查看开始的块 if (MSVC)

为什么我的项目没有生成?

如果不检查您的 LLVM 构建,我无法权威地回答这个问题。然而,

  • 未知参数:您发现 llvm-configclang 版本不兼容。您注意到您已将 C:\LLVM\llvm-new-build\Debug\bin 添加到您的路径,但这并不能确保为每个 llvm-configclang 实际执行的二进制文件来自同一位置。如果您之前安装了规范的 pre-built clang 二进制文件以供通用编译使用,则其在路径中的位置将早于 C:\LLVM\llvm-new-build\Debug\binllvm-config 不太可能包含在您的 pre-built 二进制文件中。这很重要的原因是,如果版本之间存在不匹配,则 llvm-config 生成的必需包含标志可能与 clang 所需的必需包含标志不匹配。在 Windows Server 2003 之后,您可以在 Unix-like 机器上使用 which 并在 Windows 机器上使用 where.exe 来验证执行路径阴影没有发生。我们希望他们会两者都反映执行路径实际上是C:\LLVM\llvm-new-build\Debug\bin。如果没有,那就是你的问题。 我相信这就是 -wd4146-wd4180 等选项出现问题的原因
  • 没有这样的文件或目录:当您构建 LLVM 时,cmake 检测到您正在构建 Windows,并生成了 Visual Studio 生成器文件。同时,您的项目似乎使用了某种 GNU Make-like 构建系统。有关在安装时选择发电机的更多讨论,请参阅 here我相信 MSVC 和另一个 GNU Make-like 构建系统之间的混合是造成 /DWIN32/D_WINDOWS/W3/MP.