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 的项目和使用 AutotoolsToolchain
的 Conan 包 Recipe。
Autotools: 使用 GNU 风格前端 clang
的 LLVM/Clang¶
为了构建此配置,我们将使用以下 Profile
[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
Profile 快速说明
compiler.runtime
定义是区分 Msys2-Clang 和使用 MSVC 运行时的 LLVM/Clang 的重要区别。LLVM/Clang 定义了这个compiler.runtime
,而 Msys2-Clang 没有。MSVC 运行时可以是动态的或静态的。同样重要的是定义此运行时的运行时版本(工具集版本
v144
),因为可以使用不同的版本。[buildenv]
允许指向 LLVM/Clang 编译器,以防它不在路径中。注意PATH=+(path)
的语法,用于前置该路径,使其具有更高优先级在定义
tools.microsoft.bash:path
时,使用了msys2
bash.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: 使用 MSVC 风格前端 clang-cl
的 LLVM/Clang¶
为了构建此配置,我们将使用以下 Profile
[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
该 Profile 与上面的几乎相同,主要区别在于 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-like
命令语法,例如 -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 的项目。但需要提供该 Clang 组件在 Visual Studio 安装文件夹中的完整路径,以便通过 [buildenv]
和 或 tools.build:compiler_executables
找到它,因为它本质上是由 Visual Studio 安装程序打包和分发的 LLVM/Clang 编译器。