Objective-C 指针类型 'NSString *' 到 C 指针类型 'CFStringRef' 错误的奇怪转换

Weird Cast of Objective-C pointer type 'NSString *' to C pointer type 'CFStringRef' error

我看到有一些主题解决了 "Cast of Objective-C pointer type 'NSString *' to C pointer type 'CFStringRef'" 问题,但我的情况略有不同。

我正在从 linux 进行一些 iOS 交叉编译,我有一台带有 ubuntu 的本地台式电脑,我可以在其中编译我的所有代码而不会出现任何问题。当我尝试将其移植到 AWS 机器时,出现以下编译错误:

"Cast of Objective-C pointer type 'NSString *' to C pointer type 'CFStringRef'" 在此代码上:

- (NSString *)stringByEscapingQueryString:(NSString *)string {
    return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
                                                                                 (CFStringRef)string,
                                                                                 NULL,
                                                                                 (CFStringRef) @":/?#[]@!$&'()*+,;=",
                                                                                 kCFStringEncodingUTF8));
}

使用以下编译命令:

arm-apple-darwin11-clang -v -E  -I/home/ubuntu/source/common -I/home/ubuntu/source/ios -I/home/ubuntu/source/posix -I/home/ubuntu/generated_include  -fmessage-length=0     -fdiagnostics-show-note-include-stack   -fmacro-backtrace-limit=0   -fobjc-arc  -Wno-trigraphs  -fpascal-strings    -O0     -Wno-missing-field-initializers     -Wno-missing-prototypes     -Wno-return-type    -Wno-implicit-atomic-properties     -Wno-arc-repeated-use-of-weak   -Wno-missing-braces     -Wparentheses   -Wswitch    -Wno-unused-function    -Wno-unused-label   -Wno-unused-parameter   -Wno-unused-variable    -Wunused-value  -Wno-empty-body     -Wno-uninitialized  -Wno-unknown-pragmas    -Wno-shadow     -Wno-four-char-constants    -Wno-conversion     -Wno-constant-conversion    -Wno-int-conversion     -Wno-bool-conversion    -Wno-enum-conversion    -Wno-shorten-64-to-32   -Wpointer-sign  -Wno-newline-eof    -Wno-selector   -Wno-strict-selector-match  -Wno-undeclared-selector    -Wno-deprecated-implementations     -fstrict-aliasing   -Wprotocol  -Wno-sign-conversion -Wno-infinite-recursion    -Wmost  -Wno-four-char-constants    -Wno-unknown-pragmas -fmessage-length=0     -fdiagnostics-show-note-include-stack   -Wno-infinite-recursion     -Wmost  -w -fmessage-length=0   -fdiagnostics-show-note-include-stack   -fmacro-backtrace-limit=0   -fobjc-arc  -Wno-trigraphs  -fpascal-strings    -O0     -Wno-missing-field-initializers     -Wno-missing-prototypes     -Wno-return-type    -Wno-implicit-atomic-properties     -Wno-arc-repeated-use-of-weak   -Wno-missing-braces     -Wparentheses   -Wswitch    -Wno-unused-function    -Wno-unused-label   -Wno-unused-parameter   -Wno-unused-variable    -Wunused-value  -Wno-empty-body     -Wno-uninitialized  -Wno-unknown-pragmas    -Wno-shadow     -Wno-four-char-constants    -Wno-conversion     -Wno-constant-conversion    -Wno-int-conversion     -Wno-bool-conversion    -Wno-enum-conversion    -Wno-shorten-64-to-32   -Wpointer-sign  -Wno-newline-eof    -Wno-selector   -Wno-strict-selector-match  -Wno-undeclared-selector    -Wno-deprecated-implementations     -fstrict-aliasing   -Wprotocol  -Wno-sign-conversion    -Wno-infinite-recursion     -Wmost  -Wno-four-char-constants    -Wno-unknown-pragmas -fmessage-length=0     -fdiagnostics-show-note-include-stack   -Wno-infinite-recursion     -Wmost  -w -DW_DEBUG=1 -fvisibility=hidden -DBUILD_VARIATION=DEV -DFF_DEBUG_STRING_ID=1 -DFF_CRASH_HANDLING=1 -DGTEST_USE_OWN_TR1_TUPLE=1 -DENGINE_PLATFORM_IOS=1 -DUSECPP11=1 -miphoneos-version-min=6.0 -Wfatal-errors -Wno-return-type -g -arch arm64 -isysroot /home/ubuntu/ios-linux-cross-compile/cctools-port/usage_examples/ios_toolchain/target/SDK/iPhoneOS10.2.sdk   -o BFAppLinkNavigation.m.o   -c /home/ubuntu/source/ios/BFAppLinkNavigation.m

有趣的是:
- 两台机器的 LLVM/Clang 版本完全相同:3.9.1~svn288847-1~exp1
- 两台机器都使用完全相同的 SDK (iPhoneOS10.2.sdk) - 如果我在 AWS 机器上手动添加第二个参数的“__bridged”属性,其他所有内容都会正确编译。
- 我将生成的代码与 clang -E 进行了比较,生成的文件完全相同。

你们知道可以做些什么来解决这个问题吗?我无法将 __bridged 属性添加到文件中,因为 OSX 不需要它们,我需要获得相同的编译结果。

如果需要,我可以提供更多细节,我已经 运行 没有想法了:(

终于找到问题的根源了。在我的主机中,我没有使用 CCache,但在 AWS 机器上使用它。

AWS 机器有一个旧的 CCache 版本,其中 run_second_cpp 选项设置为 false,编译分为两个步骤:首先 运行 预处理器(带 -E),检查一个如果没有找到,请使用先前的预处理器输出编译代码。在配置上手动将其更改为 "True" 后,一切开始正常工作。

此行为的主要原因在此处解释:Missing bridge cast causes error in preprocessed source but not in real source

感谢 Ken 的提问和帮助,他们让我多思考了一点,四处寻找更多不同之处!非常感谢!