时时勤拂拭,勿使惹尘埃

TOC

Categories

macOS(四)10.15 Catalina上编译的坑


0x0 前言

macOS系统更新到Catalina后,编译环境出现不少问题,简单整理如下
(持续更新记录) 

0x1 头文件如’stdio.h’ file not found

hello.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
         ^~~~~~~~~
1 error generated.

Mac 下 stdio.h 应该位于 /usr/include,但更新系统后该文件夹消失了,虽然可以ln过去,但由于SIP保护,需要重启进入Recover Modecsrutil disable才能remount 根目录:

sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ /usr/include
ln: /usr/include: Read-only file system

所以可以在编译时候添加-isysroot参数:

build/bin/clang hello.c -o hello -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk

0x2 ld未知参数-platform_version

$ clang hello.c -o hello 
ld: unknown option: -platform_version
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)

这个问题主要在于macOS Catalina系统中已经不再使用-platform_version参数,但llvm编译时还会继续往ld参数里添加-platform_version,可以在clang后面添加-v来查看详细内容


通过检索源码,可以发现在/clang/lib/Driver/ToolChains/Darwin.cpp中有如下代码,当Version[0] >= 520时,会往链接指令中添加-platform_version参数:


clang-mlinker-version=参数可以指定Version[0]的值,Version[0]的值用于控制是否使用特定链接参数,-mlinker-version=在LLVM-10.0.0中默认为556.6


所以编译时,设置clang-mlinker-version=参数,当其小于520即可忽略-platform_version参数,如下:

$ clang hello.c -o hello -mlinker-version=519
...
$ clang hello.c -o hello -mlinker-version=0

0x3 ld: unexpected token: !tapi-tbd-v3

$ clang hello.c -o hello
ld: unexpected token: !tapi-tbd-v3 file '/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/lib/libSystem.tbd' for architecture x86_64
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)

这个问题主要是由于ld链接器版本过老,依赖的libtapi库不支持TAPIv3版本的token,使用macport重装ld即可:

sudo port -v uninstall ld64
sudo port -v install ld64 +ld64_xcode

如果macOS更新过大版本,macport提示内核不支持,可以按照官方说明更新macport版本,https://trac.macports.org/wiki/Migration

Error: Current platform "darwin 19" does not match expected platform "darwin 18"