AutoTools: 使用 LLVM/Clang Windows 编译器¶
Windows 中的 Clang 编译器可以来自 2 种不同的安装或发行版
使用 MSVC 运行时程序的 LLVM/Clang 编译器
使用 Msys2 运行时程序 (libstdc++6.dll) 的 Msys2 Clang 编译器
本示例解释使用 MSVC 运行时程序的 LLVM/Clang。这种 Clang 发行版反过来可以通过两种不同的方式使用
使用下载的 LLVM/Clang 编译器(仍然使用 MSVC 运行时程序),通过类似 GNU 的前端
clang使用下载的 LLVM/Clang 编译器(仍然使用 MSVC 运行时程序),通过类似 MSVC 的前端
clang-cl
让我们从一个简单的 autotools_exe 模板开始
$ conan new autotools_exe -d name=mypkg -d version=0.1
这将创建一个简单的基于 Autotools 的项目和 Conan 包配方,该配方使用 AutotoolsToolchain。
AutoTools: 使用 clang 类似 GNU 的前端的 LLVM/Clang¶
要构建此配置,我们将使用以下配置文件
[settings]
os=Windows
arch=x86_64
build_type=Release
compiler=clang
compiler.version=18
compiler.cppstd=14
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.runtime_version=v144
[buildenv]
PATH=+(path)C:\ws\LLVM\18.1\bin
[conf]
tools.compilation:verbosity=verbose
tools.build:compiler_executables = {"c": "clang", "cpp": "clang++"}
tools.microsoft.bash:subsystem=msys2
tools.microsoft.bash:path=C:\ws\msys64\usr\bin\bash.exe
配置文件快速说明
compiler.runtime定义是区分 Msys2-Clang 和使用 MSVC 运行时程序的 LLVM/Clang 的重要区分因素。LLVM/Clang 定义了这个compiler.runtime,而 Msys2-Clang 没有。MSVC 运行时程序可以是动态的或静态的。同样重要的是定义此运行时程序(工具集版本
v144)的版本,因为可以使用不同的版本。[buildenv]允许指向 LLVM/Clang 编译器,如果它尚未在路径中。**注意**PATH=+(path)语法,以**前置**该路径,使其具有更高的优先级在定义
tools.microsoft.bash:path时,已使用msys2bash.exe的完整路径。否则,可能会找到 Windows 系统中的另一个bash.exe,该程序无效。
让我们构建它
$ conan build . -pr=llvm_clang
...
conanfile.py (mypkg/0.1): Calling build()
conanfile.py (mypkg/0.1): RUN: autoreconf --force --install
conanfile.py (mypkg/0.1): RUN: "/c/projectpath/clang/configure" --prefix=/ --bindir=${prefix}/bin --sbindir=${prefix}/bin --libdir=${prefix}/lib --includedir=${prefix}/include --oldincludedir=${prefix}/include
conanfile.py (mypkg/0.1): RUN: make -j8
...
clang++ -DPACKAGE_NAME=\"mypkg\" -DPACKAGE_TARNAME=\"mypkg\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"mypkg\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"mypkg\" -DVERSION=\"0.1\" -I. -I/c/projectpath/clang/src -DNDEBUG -std=c++14 -D_DLL -D_MT -Xclang --dependent-lib=msvcrt -O3 -c -o main.o /c/projectpath/clang/src/main.cpp
source='/c/projectpath/clang/src/mypkg.cpp' object='mypkg.o' libtool=no \
DEPDIR=.deps depmode=none /bin/sh /c/projectpath/clang/depcomp \
clang++ -DPACKAGE_NAME=\"mypkg\" -DPACKAGE_TARNAME=\"mypkg\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"mypkg\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"mypkg\" -DVERSION=\"0.1\" -I. -I/c/projectpath/clang/src -DNDEBUG -std=c++14 -D_DLL -D_MT -Xclang --dependent-lib=msvcrt -O3 -c -o mypkg.o /c/projectpath/clang/src/mypkg.cpp
clang++ -std=c++14 -D_DLL -D_MT -Xclang --dependent-lib=msvcrt -O3 -fuse-ld=lld-link -o mypkg.exe main.o mypkg.o
请注意,使用了 clang++ 编译器,运行时程序使用 -D_DLL -D_MT -Xclang --dependent-lib=msvcrt 选择。
我们可以运行我们的可执行文件,并查看 Clang 编译器版本和 MSVC 运行时程序是否与定义的版本匹配
$ build-release\src\mypkg.exe
mypkg/0.1: Hello World Release!
mypkg/0.1: _M_X64 defined
mypkg/0.1: __x86_64__ defined
mypkg/0.1: MSVC runtime: MultiThreadedDLL
mypkg/0.1: _MSC_VER1943
mypkg/0.1: _MSVC_LANG201402
mypkg/0.1: __cplusplus201402
mypkg/0.1: __clang_major__18
mypkg/0.1: __clang_minor__1
AutoTools: 使用 clang-cl 类似 MSVC 的前端的 LLVM/Clang¶
要构建此配置,我们将使用以下配置文件
[settings]
os=Windows
arch=x86_64
build_type=Release
compiler=clang
compiler.version=18
compiler.cppstd=14
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.runtime_version=v144
[buildenv]
PATH=+(path)C:/ws/LLVM/18.1/bin
[conf]
tools.compilation:verbosity=verbose
tools.microsoft.bash:subsystem=msys2
tools.build:compiler_executables = {"c": "clang-cl", "cpp": "clang-cl"}
tools.microsoft.bash:path=C:\ws\msys64\usr\bin\bash.exe
配置文件几乎与上述相同,主要区别在于 tools.build:compiler_executables 的定义,该定义定义了 clang-cl 编译器。
注意
使用 clang-cl 编译器定义 tools.build:compiler_executables 是 Conan 用于区分不同前端的依据,也用于其他构建系统。这个前端不是一个 setting,因为编译器仍然相同,并且生成的二进制文件应该是二进制兼容的。
让我们构建它
$ conan build . -pr=llvm_clang_cl
...
clang-cl -DPACKAGE_NAME=\"mypkg\" -DPACKAGE_TARNAME=\"mypkg\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"mypkg\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"mypkg\" -DVERSION=\"0.1\" -I. -I/c/projectpath/clang/src -DNDEBUG -std:c++14 -MD -O2 -c -o main.obj `cygpath -w '/c/projectpath/clang/src/main.cpp'`
source='/c/projectpath/clang/src/mypkg.cpp' object='mypkg.obj' libtool=no \
DEPDIR=.deps depmode=msvc7msys /bin/sh /c/projectpath/clang/depcomp \
clang-cl -DPACKAGE_NAME=\"mypkg\" -DPACKAGE_TARNAME=\"mypkg\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"mypkg\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"mypkg\" -DVERSION=\"0.1\" -I. -I/c/projectpath/clang/src -DNDEBUG -std:c++14 -MD -O2 -c -o mypkg.obj `cygpath -w '/c/projectpath/clang/src/mypkg.cpp'`
clang-cl -std:c++14 -MD -O2 -o mypkg.exe main.obj mypkg.obj
...
请注意如何使用所需的 clang-cl,以及如何使用类似 MSVC 的命令行语法,例如 -std:c++14。这种类似 MSVC 的语法使用 -MD/-MT 标志来区分动态/静态 MSVC 运行时程序。
我们可以运行我们的可执行文件,并查看 Clang 编译器版本和 MSVC 运行时程序是否与定义的版本匹配
$ build\Release\mypkg.exe
mypkg/0.1: Hello World Release!
mypkg/0.1: _M_X64 defined
mypkg/0.1: __x86_64__ defined
mypkg/0.1: MSVC runtime: MultiThreadedDLL
mypkg/0.1: _MSC_VER1943
mypkg/0.1: _MSVC_LANG201402
mypkg/0.1: __cplusplus201402
mypkg/0.1: __clang_major__18
mypkg/0.1: __clang_minor__1
正如预期的那样,输出与前一个相同,因为除了编译器前端之外,没有任何变化。
注意
有可能使用作为 Visual Studio 组件分发的 clang-cl 来构建类似 autotools 的项目。但是,必须通过 [buildenv] 和/或 tools.build:compiler_executables 提供该 Clang 组件在 Visual Studio 安装文件夹中的完整路径,以便找到它,因为它本质上是 LLVM/Clang 编译器,由 Visual Studio 安装程序打包和分发。