CMake链接共享库时如何移除默认/usr/lib路径?解决libSystem.dylib依赖
首先得明确说:你没法移除对libSystem.B.dylib的依赖,也没必要尝试移除CMake默认的/usr/lib路径,原因如下:
1. libSystem.B.dylib是macOS二进制的核心依赖
macOS上几乎所有Mach-O格式的二进制(包括你的共享库)都必须依赖libSystem.B.dylib——它是系统的核心库集合,封装了libc、libm、libpthread、系统调用等最基础的底层功能。哪怕你写一个空的C/C++文件编译成共享库,otool -L也会显示它依赖libSystem.B.dylib。
你可以尝试用-nostdlib编译选项跳过默认库链接,但这样你的代码必须自己实现所有系统级的入口逻辑(比如_main函数的系统调用封装、内存管理函数等),这对于普通的用户态共享库来说完全不现实,几乎没有可操作性。
2. 关于CMake中的/usr/lib路径
CMake默认会把系统库路径(包括/usr/lib)加入链接搜索路径,这是正常且必要的行为——系统库本身就安装在这些路径下。如果想强制跳过默认库链接,可以通过以下方式设置:
# 跳过所有默认系统库链接 target_link_options(libtarget PRIVATE -nodefaultlibs) # 但此时你必须手动链接libSystem,否则编译会直接失败 target_link_libraries(libtarget PRIVATE /usr/lib/libSystem.B.dylib)
但这种操作没有任何实际意义,因为你最终还是得链接libSystem.B.dylib,只是把自动链接改成了手动指定而已。
补充:关于你移除libc++.dylib的情况
你能成功移除libc++.dylib依赖,应该是因为你的代码没有用到C标准库功能,或者你指定了-stdlib=libstdc++(不过libstdc在新版macOS已经被废弃)。但这和libSystem的依赖完全不是一个层级——libSystem是操作系统层面的强制依赖,和语言标准库无关。
如果你的需求是让共享库的依赖列表里不显示/usr/lib的绝对路径?那可以用install_name_tool修改库的rpath,但这只是修改路径的显示形式,实际运行时系统还是会去/usr/lib加载libSystem.B.dylib,强行修改反而可能导致运行错误。
内容的提问来源于stack exchange,提问作者Alpha234

