我正在用-arch i386 -isysroot /Applications/Xcode-7.2.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -mmacosx-version-min=10.4
编译一些断言。因此,断言代码不会使用__assert_rtn
而是使用__eprintf
。
来自 assert.h 的相关摘录:
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) < 1070)
#define __assert(e, file, line) \
__eprintf ("%s:%u: failed assertion `%s'\n", file, line, e)
#else
/* 8462256: modified __assert_rtn() replaces deprecated __eprintf() */
#define __assert(e, file, line) \
__assert_rtn ((const char *)-1L, file, line, e)
#endif
到目前为止一直很好,除非链接时间到来时,它找不到__eprintf
。这个库定义在哪个库中?
重新获得__eprintf
assert
的方法
cat <<EOF >/tmp/x.c
#include <assert.h>
#ifdef __clang__
# if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) <= 1040)
# if ! __DARWIN_UNIX03
# warning "compiling for 10.4 (not __DARWIN_UNIX03), with __eprintf"
# endif
# endif
#endif
int xxx( int a)
{
assert( a);
return( a);
}
EOF
clang -E -arch i386 -mmacosx-version-min=10.4 -isysroot /Applications/Xcode-7.2.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -o /tmp/x.txt /tmp/x.c
使用上面的代码,制作一个dylib并观察问题:
clang -c -arch i386 -mmacosx-version-min=10.4 -isysroot /Applications/Xcode-7.2.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -O0 -o /tmp/x.o /tmp/x.c
ld -arch i386 -macosx_version_min 10.4.0 -syslibroot /Applications/Xcode-7.2.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -t -o /tmp/x.dylib -ldylib1.o /tmp/x.o -lSystem -lgcc_s.10.4
这些调用是从
xcodebuild
生成的内容中逐渐减少的。
答案 0 :(得分:1)
感谢您提供的有用回复。
在我的特定情况下,答案结果为/Applications/Xcode-7.2.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/7.0.2/lib/darwin/libclang_rt.10.4.a
。
这是一个由clang
本身在幕后添加的库(DarwinClang::AddLinkRuntimeLibArgs)。请注意,此库仅适用于10.4代码,并且似乎与编译器版本相关联。
我不知道哪个魔术(在调用中没有看到它)链接器决定它需要链接哪个编译器版本。
最简单的解决方案是定义自己的__eprintf
,而不是搞乱工具链:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) <= 1040)
# if ! __DARWIN_UNIX03
__attribute__((visibility("hidden")))
void __eprintf( const char* format, const char* file,
unsigned line, const char *expr)
{
fprintf( stderr, format, file, line, expr);
abort();
}
# endif
#endif
int main( int argc, char *argv[])
{
assert( argc == 2);
return( 0);
}