macOS使用LLVM官方发布的tar.xz来安装Clang编译器
之前笔者写过一篇博文 ubuntu使用LLVM官方发布的tar.xz来安装Clang编译器介绍了Ubuntu下使用官方发布的tar.xz包来安装Clang编译。官方发布的版本中也有MacOS版本的tar.xz,那MacOS应该也是可以安装的。
笔者2015款MBP笔记本,CPU是intel
的,出厂系统是MacOS10.12(Sierra),后面自己升级安装到10.13(由于只有128G硬盘,不能安装太新的系统):
目前的Clang
编译器是9.0
,__cplusplus
版本是201406
,支持C++14
,部分支持C++17
,如果想使用新一点的C++标准,就需要更新编译器。
一、安装Clang编译器
LLVM官方在LLVM 15及之前是有出Intel版本的tar.xz安装包的,后面有的版本没macOS
版本的,有的版本有macOS
的,但是是ARM CPU的,后面19.0开始有macOS版本的了,而且ARM与Intel的都有。
只可惜笔者的MBP系统太老,不能安装最新版本的,只能退而求其次,安装LLVM 15.0.7,而且有Intel CPU的x86_64版本:
先下载
clang+llvm-15.0.7-x86_64-apple-darwin21.0.tar.xz
,再使用下面的命令解压:
1tar -xf clang+llvm-15.0.7-x86_64-apple-darwin21.0.tar.xz
解压后,可以将目录改名为llvm-15
,然后移动到/usr/local/
目录下,为了确保独立性,不弄脏/usr/local/
目录,直接将整个llvm-15
目录移动,而不是移动llvm-15
下的子目录。
然后在~/.bash_profile
中设置PATH
,将/usr/local/llvm-15/bin
添加到PATH变量中:
1export PATH=/usr/local/llvm-15/bin:$PATH
二、测试、使用
1.简单测试
添加好后,新开一个终端进行简单测试,测试clang
没问题:
1$ clang -v
2clang version 15.0.7
3Target: x86_64-apple-darwin17.7.0
4Thread model: posix
5InstalledDir: /usr/local/llvm-15/bin
但是测试lldb
就报错了:
1$ lldb
2dyld: Library not loaded: @rpath/liblldb.15.0.7.dylib
3 Referenced from: /usr/local/llvm-15/bin/lldb
4 Reason: no suitable image found. Did find:
5 /usr/local/llvm-15/bin/../lib/liblldb.15.0.7.dylib: cannot load 'liblldb.15.0.7.dylib' (load command 0x80000034 is unknown)
6 /usr/local/llvm-15/bin/../lib/liblldb.15.0.7.dylib: stat() failed with errno=1
7Abort trap: 6
使用otool -l /usr/local/llvm-15/lib/liblldb.15.0.7.dylib
指令查看:
1$ otool -l /usr/local/llvm-15/lib/liblldb.15.0.7.dylib
2/usr/local/llvm-15/lib/liblldb.15.0.7.dylib:
3Mach header
4 magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
5 0xfeedfacf 16777223 3 0x00 6 31 3400 0x00910085
6Load command 0
7 cmd LC_SEGMENT_64
8 cmdsize 872
9 segname __TEXT
10 vmaddr 0x0000000000000000
11 vmsize 0x00000000067c8000
12 fileoff 0
13 filesize 108822528
14 maxprot 0x00000005
15 initprot 0x00000005
16 nsects 10
17 flags 0x0
18Section
19 sectname __text
20
21……
22
23
24Load command 4
25 cmd LC_ID_DYLIB
26 cmdsize 56
27 name @rpath/liblldb.15.0.7.dylib (offset 24)
28 time stamp 1 Thu Jan 1 08:00:01 1970
29 current version 15.0.7
30compatibility version 0.0.0
31Load command 5
32 cmd ?(0x80000034)
33 cmdsize 16
34Load command 6
35 cmd ?(0x80000033)
36 cmdsize 16
37Load command 7
38 cmd LC_SYMTAB
39 cmdsize 24
40 symoff 119381816
41 nsyms 180001
42 stroff 122268616
43 strsize 16367424
44Load command 8
45 cmd LC_DYSYMTAB
发现还真是有未知命令:cmd ?(0x80000034)
,cmd ?(0x80000033)
,暂时无法解决,就还是使用系统自带的lldb
吧。
2. 使用VSCode测试
只要设置好Clang
的路径在PATH
变量中,打开VSCode,重新扫描工具包,即可搜索到新的Clang版本。
切换到Clang 15,VSCode会自动重新执行CMake命令:
1[cmake] FAILED: cmTC_d20cb
2[cmake] : && /usr/local/llvm-15/bin/clang -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/cmTC_d20cb.dir/testCCompiler.c.o -o cmTC_d20cb && :
3[cmake] ld: unknown option: -platform_version
4[cmake] clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
5[cmake] ninja: build stopped: subcommand failed.
无法正确执行CMake,CMake在编译简单的测试程序时,无法通过。
ld: unknown option: -platform_version
提示是ld
找到不到参数,原因是新版本的Clang编译器与系统的链接器ld
不匹配,需要使用Clang自己的链接器lld
,由于是CMake在测试编译器时报的错,那就需要在它之前设置使用lld
。
CMake中要设置链接器使用lld
,有两种方法:
- 可以在cmake命令行参数中设置如下变量:
- CMAKE_EXE_LINKER_FLAGS:设置可执行文件链接器的变量,用法:
-DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld
,注意大小写 - CMAKE_SHARED_LINKER_FLAGS:设置动态链接库链接器的变量,用法:
-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld
- CMAKE_LINK_LIBRARY_FLAG:设置静态链接库链接器的旗标,用法:
-DCMAKE_LINK_LIBRARY_FLAG=-fuse-ld=lld
- CMAKE_LINKER_TYPE:在3.29版本添加的新变量,用法:
-DCMAKE_LINKER_TYPE=LLD
,注意LLD
是大写
在VSCode中需要在settings.json
配置文件中设置:
1"cmake.configureArgs": [
2 "-DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld",
3 "-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld",
4 "-DCMAKE_LINK_LIBRARY_FLAG=-fuse-ld=lld",
5 "-DCMAKE_LINKER_TYPE=LLD" // CMake3.29+才能使用
6],
- 在
CMakeLists.txt
中设置 如果是在CMakeLists.txt
中设置,一定要在最顶层的CMakeLists.txt
中project
命令之前设置:
1cmake_minimum_required(VERSION 3.25)
2set(CMAKE_EXE_LINKER_FLAGS -fuse-ld=lld)
3set(CMAKE_SHARED_LINKER_FLAGS -fuse-ld=lld)
4set(CMAKE_LINK_LIBRARY_FLAG -fuse-ld=lld)
5set(CMAKE_LINKER_TYPE LLD)
6project(demo)
编译链接都没问题了。
3. 使用QtCreator测试
笔者在MBP上安装的是QtCreator 5.03版本,基于Qt5.15.2的:
但Qt的SDK是5.14.2:
可以先使用QtCreator的自动检测,看是否能检测到Clang15,如果不能,手动添加:
在Kits中克隆一个原来的配置,将下面的C/C++编译器设置为clang 15:
并在CMake Configuration
中添加如下配置:
1CMAKE_EXE_LINKER_FLAGS:STRING=-fuse-ld=lld
2CMAKE_LINK_LIBRARY_FLAG:STRING=-fuse-ld=lld
3CMAKE_SHARED_LINKER_FLAGS:STRING=-fuse-ld=lld
如下图所示:
在Qt项目中使用新的Kits编译即可。
但是笔者在设置好后,QtCreator会有一个警告:
cstdlib
源码:
1#if !defined(_LIBCPP_CXX03_LANG)
2using ::at_quick_exit _LIBCPP_USING_IF_EXISTS;
3using ::quick_exit _LIBCPP_USING_IF_EXISTS;
4#endif
5#if _LIBCPP_STD_VER > 14
6using ::aligned_alloc _LIBCPP_USING_IF_EXISTS;
7#endif
原因是at_quick_exit
和quick_exit
函数在C11中添加,而std::at_quick_exit
和std::quick_exit
函数在C++11中添加,参见:
https://cppreference.cn/w/c/program/at_quick_exit
https://cppreference.cn/w/cpp/utility/program/at_quick_exit
aligned_alloc
是在C11中添加,而std::aligned_alloc
是在C++17中添加,参见:
https://cppreference.cn/w/c/memory/aligned_alloc
https://cppreference.cn/w/cpp/memory/c/aligned_alloc
笔者MacOS系统原来的C库缺少这几个函数的,可以在一个头文件中声明一下,不让QtCreator报警告:
lost.h
1#ifndef LOST_H
2#define LOST_H
3
4#include <_ctype.h>
5
6int at_quick_exit(void (*)());
7int quick_exit(void (*)());
8void *aligned_alloc(size_t alignment, size_t size);
9int timespec_get(
10 struct timespec* const time_spec,
11 int const base
12);
13
14#endif // LOST_H
然后在#include <cstdlib>
之前先#include "lost.h"
即可。
不报警告了,但是在代码中不能使用这几个函数,因为系统中没有相应的实现。
如果对你有帮助,欢迎点赞收藏!
- 原文作者:Witton
- 原文链接:https://wittonbell.github.io/posts/2025/2025-01-22-macOS使用LLVM官方发布的tar.xz来安装Clang编译器/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。