首页 > 解决方案 > 使用 clang 编译时无法解析引用 macOS SDK 标头

问题描述

我正在尝试将我的 Rust 库与 macOS SDK 链接起来。尝试在 macOS SDK 中包含标头时.m文件中包含来自 macOS SDK 的标头并进行编译时,链接器会返回错误。

代码示例:

#import <Foundation/Foundation.h>
#import <IOKit/KextManager.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSLog(@"Something");
    }
    return 0;
}

错误:

main.m:11:9:致命错误:找不到“IOKit/KextManager.h”文件

#import <IOKit/KextManager.h>

    ^~~~~~~~~~~~~~~~~~~~~ 1 error generated.

当我引用完整路径时,会包含标头,但对于某些未找到的类,我会收到其他链接器错误:

代码示例:

#import <Foundation/Foundation.h>
#import "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/IOKit.framework/Headers/kext/KextManager.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSLog(@"Something");
    }
    return 0;
}

我得到的错误:

架构x86_64的未定义符号:“_NSLog”,引用自:main-891267.o中的_main“___CFConstantStringClassReference”,引用自:main-891267.o中的CFString“_objc_autoreleasePoolPop”,引用自:main-891267.o中的_main“_objc_autoreleasePoolPush ",引用自:main-891267.o ld 中的 _main:未找到架构 x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

我怀疑这是因为其他标头没有正确解析。

如何使标头解析正常工作,以便所有内容不仅包括来自 Xcode 的工作?

此代码直接从 Xcode 编译和运行,没有任何额外的引用,但不是从终端编译:

#import <Foundation/Foundation.h>
#import "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/IOKit.framework/Headers/kext/KextManager.h"
//#import <IOKit/KextManager.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {

        CFDictionaryRef result = KextManagerCopyLoadedKextInfo(NULL, NULL);

        NSLog(@"%@", result);
    }
    return 0;
}

获得相同的链接器错误:

ld:警告:紧急:为 OSX 构建,但链接到为(未知)构建的 dylib (/usr/lib/libSystem.dylib)。注意:这将是未来的错误。架构x86_64的未定义符号:
“_KextManagerCopyLoadedKextInfo”,引用自:main-abff3c.o中的_main“_NSLog”,引用自:main-abff3c.o中的_main“___CFConstantStringClassReference”,引用自:main-abff3c.o中的CFString“_objc_autoreleasePoolPop ”,引用自:main-abff3c.o 中的 _main “_objc_autoreleasePoolPush”,引用自:main-abff3c.o 中的 _main ld:未找到架构 x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用-v 查看调用)

更新 2:

编译器命令:

clang -framework IOKit -framework Foundation main.m -o main

适用于标题的完整路径,但不适用于#include <IOKit/KextManager.h>

标签: objective-cmacos

解决方案


解决方案是将 Xcode 包含的框架链接到包含文件夹中。

对于稳定版本:

ln -s /Applications/Xcode.app/Contents/Frameworks/ /usr/local/include/

对于 Xcode 测试版:

ln -s /Applications/Xcode-beta.app/Contents/Frameworks/ /usr/local/include/

然后 KextManager 像这样导入:

#import <IOKit/kext/KextManager.h>


推荐阅读