【问题标题】:how to compile objective-c source code with clang in mingw64-x86 via apple libobjc.dll?如何通过苹果libobjc.dll在mingw64-x86中使用clang编译objective-c源代码?
【发布时间】:2012-10-15 17:09:03
【问题描述】:

我在windows平台上编译objective-c源代码时遇到问题。 当然是在windows平台编译objective-c源码,我们一般使用gnustep环境(gcc objecitve-c编译器.gnustep libojc动态库.gnustep基础框架...等等)。

但我想要一个干净的环境尝试编译器objective-c,并使用不同的libobjc库。

从 mac os x 10.6 开始。苹果将​​macosx系统移至x86平台(不再支持ppc),并通过cocoa tech.include iTunes重写系统应用程序。

iTunes 有 windows 版本。

在安装 iTunes 后搜索系统文件夹。我在以下位置找到了任何支持 dll 文件: C:\Program Files (x86)\Common Files\Apple\Apple Application Support

顺便说一下,我的系统是windows 7 x86_64。

我发现它有:

ApplePushService.dll
AppleVersions.dll
APSDaemon_main.dll
ASL.dll
AVFoundationCF.dll
CFNetwork.dll
CoreAudioToolbox.dll
CoreFoundation.dll
CoreGraphics.dll
CoreMedia.dll
CoreText.dll
CoreVideo.dll
Foundation.dll
icudt46.dll
icuin40.dll
icuuc40.dll
JavaScriptCore.dll
libcache.dll
libdispatch.dll
libicuin.dll
libicuuc.dll
libtidy.dll
libxml2.dll
libxslt.dll
MediaToolbox.dll
objc.dll
pthreadVC2.dll
QTMovieWin.dll
QuartzCore.dll
SQLite3.dll
VideoToolbox.dll
WebKit.dll
WebKitQuartzCoreAdditions.dll
YSCrashDump.dll
YSUtilities.dll
zlib1.dll

看起来,苹果将这些低级框架实现到windows平台。

CFNetwork.framework -> CFNetwork.dll 

CoreGraphics.framework -> CoreGraphics.dll

Foundation.framework -> Foundation.dll

libobjc.a.dylib -> objc.dll

WebKit.framework -> WebKit.dll

所以,我认为使用苹果的 libobjc 发行版更好(iTunes 运行良好)。其他库文件也很有用。

我想为 Objective-c 初学者(我的同学和我)建立一个学习环境。

所以我复制 objc.dll 并将其重命名为 libobjc.dll

使用 mingw 工具 "pexports" 将 libobjc.dll 的 def 导出到 libobjc.def 然后使用 Visual Studio 命令工具 "lib.exe" 将 .def 文件转换为 libobjc.lib。

然后我下载

  • mingw64 的 x86(32 位)编译器 dng 预编译包。
  • mingw64 的 clang+llvm(32 位)编译器 dng 预编译包。
  • mingw64的msys环境预编译包。

将这 3 个软件包安装到系统中。 然后将 libobjc.dll,libobjc.lib 复制到 /lib(在 windows 平台上,.a 和 .lib 使用相同的 bin 格式)。

然后我写了一个示例objective-c源代码。代码在这里: 文件:test.m

#import <stdio.h>

@interface Foo {
    int count;
}

+ (void)fooWithBar;

@end

@implementation Foo

+ (void)fooWithBar {
    printf("abc");
}

@end


int main(){
    [Foo fooWithBar];
    return 0;
}

只需编译它:

clang test.m

发生错误,然后使用 -v 选项显示详细信息:

clang version 3.1 (branches/release_31)
Target: i686-w64-mingw32
Thread model: posix
 "c:/mingw64w32/bin/clang.exe" -cc1 -triple i686-w64-mingw32 -S -disable-free -main-file-name test.m -mrelocation-model static -mdisable-fp-elim -mconstructor-aliases -target-cpu pentium4 -target-linker-version 2.20.51.0.2 -momit-leaf-frame-pointer -v -resource-dir "c:/mingw64w32/bin\\..\\lib\\clang\\3.1" -fmodule-cache-path "C:/Users/Joe/AppData/Local/Temp\\clang-module-cache" -fno-dwarf-directory-asm -fdebug-compilation-dir C:/MINGW64-X86-MSYS-20111123/home/Joe -ferror-limit 19 -fmessage-length 0 -mstackrealign -fno-use-cxa-atexit -fgnu-runtime -fobjc-runtime-has-arc -fobjc-runtime-has-weak -fobjc-fragile-abi -fobjc-exceptions -fdiagnostics-show-option -o C:/Users/Joe/AppData/Local/Temp/test-709512.s -x objective-c test.m
clang -cc1 version 3.1 based upon LLVM 3.1 default target i686-w64-mingw32
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "c:/mingw64w32/bin/../lib/clang/3.1/../../../x86_64-w64-mingw32/include"
ignoring nonexistent directory "/mingw/include"
ignoring nonexistent directory "c:/mingw/include"
ignoring nonexistent directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
 c:/mingw64w32/bin/../lib/clang/3.1/include
 c:/mingw64w32/bin/../lib/clang/3.1/../../../i686-w64-mingw32/include
 c:/mingw64w32/bin/../lib/clang/3.1/../../../include
End of search list.
 "c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe" -v -c -o C:/Users/Joe/AppData/Local/Temp/test-709513.o -x assembler C:/Users/Joe/AppData/Local/Temp/test-709512.s
Using built-in specs.
COLLECT_GCC=c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe
Target: i686-w64-mingw32
Configured with: /home/drangon/work/mingw-w64-dgn_32/source/gcc/configure --host=i686-w64-mingw32 --target=i686-w64-mingw32 --disable-nls --enable-languages=c,c++,objc,obj-c++ --with-gmp=/home/drangon/work/mingw-w64-dgn_32/build/for_target --enable-twoprocess --disable-libstdcxx-pch --disable-win32-registry --prefix=/home/drangon/work/mingw-w64-dgn_32/target --with-sysroot=/home/drangon/work/mingw-w64-dgn_32/target
Thread model: win32
gcc version 4.7.2 20120823 (prerelease) (GCC) 
COLLECT_GCC_OPTIONS='-v' '-c' '-o' 'C:/Users/Joe/AppData/Local/Temp/test-709513.o' '-mtune=generic' '-march=pentiumpro'
 c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/as.exe -v -o C:/Users/Joe/AppData/Local/Temp/test-709513.o C:/Users/Joe/AppData/Local/Temp/test-709512.s
GNU assembler version 2.23.51 (i686-w64-mingw32) using BFD version (GNU Binutils) 2.23.51.20120823
COMPILER_PATH=c:/mingw64w32/bin/../libexec/gcc/i686-w64-mingw32/4.7.2/;c:/mingw64w32/bin/../libexec/gcc/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/
LIBRARY_PATH=c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/;c:/mingw64w32/bin/../lib/gcc/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/../lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../
COLLECT_GCC_OPTIONS='-v' '-c' '-o' 'C:/Users/Joe/AppData/Local/Temp/test-709513.o' '-mtune=generic' '-march=pentiumpro'
 "c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe" -v -o a.out C:/Users/Joe/AppData/Local/Temp/test-709513.o
Using built-in specs.
COLLECT_GCC=c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe
COLLECT_LTO_WRAPPER=c:/mingw64w32/bin/../libexec/gcc/i686-w64-mingw32/4.7.2/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: /home/drangon/work/mingw-w64-dgn_32/source/gcc/configure --host=i686-w64-mingw32 --target=i686-w64-mingw32 --disable-nls --enable-languages=c,c++,objc,obj-c++ --with-gmp=/home/drangon/work/mingw-w64-dgn_32/build/for_target --enable-twoprocess --disable-libstdcxx-pch --disable-win32-registry --prefix=/home/drangon/work/mingw-w64-dgn_32/target --with-sysroot=/home/drangon/work/mingw-w64-dgn_32/target
Thread model: win32
gcc version 4.7.2 20120823 (prerelease) (GCC) 
COMPILER_PATH=c:/mingw64w32/bin/../libexec/gcc/i686-w64-mingw32/4.7.2/;c:/mingw64w32/bin/../libexec/gcc/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/
LIBRARY_PATH=c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/;c:/mingw64w32/bin/../lib/gcc/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/../lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../
COLLECT_GCC_OPTIONS='-v' '-o' 'a.out' '-mtune=generic' '-march=pentiumpro'
 c:/mingw64w32/bin/../libexec/gcc/i686-w64-mingw32/4.7.2/collect2.exe --sysroot=/home/drangon/work/mingw-w64-dgn_32/target -m i386pe -Bdynamic -o a.out c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/../lib/crt2.o c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/crtbegin.o -Lc:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2 -Lc:/mingw64w32/bin/../lib/gcc -Lc:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/../lib -Lc:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../lib -Lc:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib -Lc:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../.. C:/Users/Joe/AppData/Local/Temp/test-709513.o -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/crtend.o
C:/Users/Joe/AppData/Local/Temp/test-709513.o:fake:(.text+0x4d): undefined reference to `objc_lookup_class'
C:/Users/Joe/AppData/Local/Temp/test-709513.o:fake:(.text+0x62): undefined reference to `objc_msg_lookup'
C:/Users/Joe/AppData/Local/Temp/test-709513.o:fake:(.text+0x9e): undefined reference to `__objc_exec_class'
c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/ld.exe: C:/Users/Joe/AppData/Local/Temp/test-709513.o: bad reloc address 0x14 in section `.data'
c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
clang: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)

通过谷歌搜索,我发现 objc_lookup_class 是在 gnustep 的 libobjc 库中定义的方法。在苹果的 libojbc.dll 的 .def 文件中:“libojbc.def”,我发现了另一个名为“objc_lookUpClass”的方法。 谷歌再次搜索。所以, 苹果的 libojbc 与 gnustep 的 libobjc 不同。 苹果的 libojbc 使用 NextStep 库 interface.gnustep 做了一个不同的。

man gcc

gcc 对此有两种选择。

-fgnu-runtime 。这是 gcc 的默认选项,使用 gnu 样式运行时。
-fnext-runtime ,这是使用 nextstep(现在是苹果)样式运行。

所以我将 nextstep 样式选项传递给 clang(或 gcc?)。 clang -fnext-runtime

编译.o到.s没有错误。似乎ld.exe从苹果的libobjc库文件中找到了它需要的所有方法。但是另一个错误发生了,使用-v选项,这里有详细信息:

clang version 3.1 (branches/release_31)
Target: i686-w64-mingw32
Thread model: posix
 "c:/mingw64w32/bin/clang.exe" -cc1 -triple i686-w64-mingw32 -S -disable-free -main-file-name test.m -mrelocation-model static -mdisable-fp-elim -mconstructor-aliases -target-cpu pentium4 -target-linker-version 2.20.51.0.2 -momit-leaf-frame-pointer -v -resource-dir "c:/mingw64w32/bin\\..\\lib\\clang\\3.1" -fmodule-cache-path "C:/Users/Joe/AppData/Local/Temp\\clang-module-cache" -fno-dwarf-directory-asm -fdebug-compilation-dir C:/MINGW64-X86-MSYS-20111123/home/Joe -ferror-limit 19 -fmessage-length 0 -mstackrealign -fno-use-cxa-atexit -fobjc-fragile-abi -fobjc-exceptions -fdiagnostics-show-option -o C:/Users/Joe/AppData/Local/Temp/test-467378.s -x objective-c test.m
clang -cc1 version 3.1 based upon LLVM 3.1 default target i686-w64-mingw32
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "c:/mingw64w32/bin/../lib/clang/3.1/../../../x86_64-w64-mingw32/include"
ignoring nonexistent directory "/mingw/include"
ignoring nonexistent directory "c:/mingw/include"
ignoring nonexistent directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
 c:/mingw64w32/bin/../lib/clang/3.1/include
 c:/mingw64w32/bin/../lib/clang/3.1/../../../i686-w64-mingw32/include
 c:/mingw64w32/bin/../lib/clang/3.1/../../../include
End of search list.
 "c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe" -fnext-runtime -v -c -o C:/Users/Joe/AppData/Local/Temp/test-467379.o -x assembler C:/Users/Joe/AppData/Local/Temp/test-467378.s
Using built-in specs.
COLLECT_GCC=c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe
Target: i686-w64-mingw32
Configured with: /home/drangon/work/mingw-w64-dgn_32/source/gcc/configure --host=i686-w64-mingw32 --target=i686-w64-mingw32 --disable-nls --enable-languages=c,c++,objc,obj-c++ --with-gmp=/home/drangon/work/mingw-w64-dgn_32/build/for_target --enable-twoprocess --disable-libstdcxx-pch --disable-win32-registry --prefix=/home/drangon/work/mingw-w64-dgn_32/target --with-sysroot=/home/drangon/work/mingw-w64-dgn_32/target
Thread model: win32
gcc version 4.7.2 20120823 (prerelease) (GCC) 
COLLECT_GCC_OPTIONS='-fnext-runtime' '-v' '-c' '-o' 'C:/Users/Joe/AppData/Local/Temp/test-467379.o' '-mtune=generic' '-march=pentiumpro'
 c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/as.exe -v -o C:/Users/Joe/AppData/Local/Temp/test-467379.o C:/Users/Joe/AppData/Local/Temp/test-467378.s
GNU assembler version 2.23.51 (i686-w64-mingw32) using BFD version (GNU Binutils) 2.23.51.20120823
C:/Users/Joe/AppData/Local/Temp/test-467378.s: Assembler messages:
C:/Users/Joe/AppData/Local/Temp/test-467378.s:4: Error: unknown pseudo-op: `.lazy_reference'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:57: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:57: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:67: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:67: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:76: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:76: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:92: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:92: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:99: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:99: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:107: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:107: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:123: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:123: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:128: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:128: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:133: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:133: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:137: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:137: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:146: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:146: Error: junk at end of line, first unrecognized character is `,'
clang: error: assembler (via gcc) command failed with exit code 1 (use -v to see invocation)

我不知道汇编语言。但似乎汇编应用程序无法理解这个 .s 文件。 所以我使用 -S 选项来保留 .s 文件。one 与 -fgnu-runtime 是铿锵的。另一个是-fnext-runtime。

//test.s ,clang 带有 -fgnu-runtime 选项

    .def     __c_Foo__fooWithBar;
    .scl    3;
    .type    32;
    .endef
    .text
    .align    16, 0x90
__c_Foo__fooWithBar:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    12(%ebp), %eax
    movl    8(%ebp), %ecx
    leal    L_.str, %edx
    movl    %ecx, -4(%ebp)
    movl    %eax, -8(%ebp)
    movl    %edx, (%esp)
    calll    _printf
    movl    %eax, -12(%ebp)
    addl    $16, %esp
    popl    %ebp
    ret

    .def     _main;
    .scl    2;
    .type    32;
    .endef
    .globl    _main
    .align    16, 0x90
_main:
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %esi
    subl    $20, %esp
    calll    ___main
    leal    L_.class_name, %eax
    movl    $0, -8(%ebp)
    movl    %eax, (%esp)
    calll    _objc_lookup_class
    leal    _.objc_selector_list, %ecx
    movl    %eax, (%esp)
    movl    %ecx, 4(%esp)
    movl    %eax, -12(%ebp)
    calll    _objc_msg_lookup
    movl    $0, %ecx
    leal    _.objc_selector_list, %edx
    movl    -12(%ebp), %esi
    movl    %esi, (%esp)
    movl    %edx, 4(%esp)
    movl    %ecx, -16(%ebp)
    calll    *%eax
    movl    -16(%ebp), %eax
    addl    $20, %esp
    popl    %esi
    popl    %ebp
    ret

    .def     _.objc_load_function;
    .scl    3;
    .type    32;
    .endef
    .align    16, 0x90
_.objc_load_function:
    .cfi_startproc
    pushl    %ebp
Ltmp2:
    .cfi_def_cfa_offset 8
Ltmp3:
    .cfi_offset %ebp, -8
    movl    %esp, %ebp
Ltmp4:
    .cfi_def_cfa_register %ebp
    pushl    %eax
    leal    ___unnamed_1, %eax
    movl    %eax, (%esp)
    calll    ___objc_exec_class
    addl    $4, %esp
    popl    %ebp
    ret
    .cfi_endproc

    .data
L_.str:
    .asciz     "abc"

    .globl    ___objc_class_name_Foo
    .align    4
___objc_class_name_Foo:
    .long    0

L___unnamed_2:
    .asciz     "count"

L___unnamed_3:
    .asciz     "i"

    .globl    ___objc_ivar_offset_value_Foo.count
    .align    4
___objc_ivar_offset_value_Foo.count:
    .long    0

    .align    4
_.ivar.offsets:
    .long    ___objc_ivar_offset_value_Foo.count

    .lcomm    _.objc_property_list,8,8
L___unnamed_4:
    .asciz     "v8@0:4"

L___unnamed_5:
    .asciz     "fooWithBar"

    .align    16
_.objc_method_list:
    .long    0
    .long    1
    .long    L___unnamed_5
    .long    L___unnamed_4
    .long    __c_Foo__fooWithBar

    .align    8
_.objc_ivar_list:
    .long    1
    .long    L___unnamed_2
    .long    L___unnamed_3
    .long    0

    .globl    ___objc_ivar_offset_Foo.count
    .align    4
___objc_ivar_offset_Foo.count:
    .long    _.objc_ivar_list+12

L_.class_name:
    .asciz     "Foo"

    .globl    __OBJC_METACLASS_Foo
    .align    16
__OBJC_METACLASS_Foo:
    .long    0
    .long    0
    .long    L_.class_name
    .long    0
    .long    18
    .long    72
    .long    0
    .long    _.objc_method_list
    .long    0
    .long    0
    .long    0
    .long    0
    .long    0
    .long    1
    .long    0
    .long    0
    .long    0
    .long    0

    .lcomm    _.objc_protocol_list,8,8
    .globl    __OBJC_CLASS_Foo
    .align    16
__OBJC_CLASS_Foo:
    .long    __OBJC_METACLASS_Foo
    .long    0
    .long    L_.class_name
    .long    0
    .long    17
    .long    4
    .long    _.objc_ivar_list
    .long    0
    .long    0
    .long    0
    .long    0
    .long    _.objc_protocol_list
    .long    0
    .long    1
    .long    _.ivar.offsets
    .long    _.objc_property_list
    .long    1
    .long    1

    .section    .rdata$__objc_class_ref_Foo,"r"
    .linkonce discard
    .globl    ___objc_class_ref_Foo
    .align    4
___objc_class_ref_Foo:
    .long    ___objc_class_name_Foo

    .data
L___unnamed_6:
    .asciz     "AnotherHack"

L___unnamed_7:
    .asciz     "__ObjC_Protocol_Holder_Ugly_Hack"

    .lcomm    _.objc_protocol_list1,8,8
    .align    16
___unnamed_8:
    .long    L___unnamed_6
    .long    L___unnamed_7
    .long    0
    .long    0
    .long    _.objc_protocol_list1

    .section    .rdata$.objc_sel_namefooWithBar,"r"
    .linkonce discard
    .globl    _.objc_sel_namefooWithBar
_.objc_sel_namefooWithBar:
    .asciz     "fooWithBar"

    .data
    .align    8
_.objc_selector_list:
    .long    _.objc_sel_namefooWithBar
    .long    L___unnamed_4
    .zero    8

    .align    16
___unnamed_9:
    .long    1
    .long    _.objc_selector_list
    .short    1
    .short    1
    .long    __OBJC_CLASS_Foo
    .long    ___unnamed_8
    .long    0
    .long    0

L_.objc_source_file_name:
    .asciz     "./test.m"

    .align    8
___unnamed_1:
    .long    8
    .long    16
    .long    L_.objc_source_file_name
    .long    ___unnamed_9

    .section    .ctors,"w"
    .align    4
    .long    _.objc_load_function

//test.s ,clang 带有 -fnext-runtime 选项

    .objc_class_name_Foo=0
    .globl .objc_class_name_Foo
    .lazy_reference .objc_class_name_Foo


    .def     _2B__5B_Foo_20_fooWithBar_5D_;
    .scl    3;
    .type    32;
    .endef
    .text
    .align    16, 0x90
_2B__5B_Foo_20_fooWithBar_5D_:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    12(%ebp), %eax
    movl    8(%ebp), %ecx
    leal    L_.str, %edx
    movl    %ecx, -4(%ebp)
    movl    %eax, -8(%ebp)
    movl    %edx, (%esp)
    calll    _printf
    movl    %eax, -12(%ebp)
    addl    $16, %esp
    popl    %ebp
    ret

    .def     _main;
    .scl    2;
    .type    32;
    .endef
    .globl    _main
    .align    16, 0x90
_main:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    calll    ___main
    movl    $0, %eax
    movl    $0, -4(%ebp)
    movl    L_OBJC_CLASS_REFERENCES_, %ecx
    movl    L_OBJC_SELECTOR_REFERENCES_, %edx
    movl    %ecx, (%esp)
    movl    %edx, 4(%esp)
    movl    %eax, -8(%ebp)
    calll    _objc_msgSend
    movl    -8(%ebp), %eax
    addl    $16, %esp
    popl    %ebp
    ret

    .data
L_.str:
    .asciz     "abc"

    .section    __TEXT,__cstring,cstring_literals,"w"
L_OBJC_METH_VAR_NAME_:
    .asciz     "fooWithBar"

L_OBJC_METH_VAR_TYPE_:
    .asciz     "v8@0:4"

L_OBJC_CLASS_NAME_:
    .asciz     "Foo"

    .section    __OBJC,__cls_meth,regular,no_dead_strip,"w"
    .align    4
L_OBJC_CLASS_METHODS_Foo:
    .long    0
    .long    1
    .long    L_OBJC_METH_VAR_NAME_
    .long    L_OBJC_METH_VAR_TYPE_
    .long    _2B__5B_Foo_20_fooWithBar_5D_

    .section    __OBJC,__meta_class,regular,no_dead_strip,"w"
    .align    4
L_OBJC_METACLASS_Foo:
    .long    L_OBJC_CLASS_NAME_
    .long    0
    .long    L_OBJC_CLASS_NAME_
    .long    0
    .long    2
    .long    48
    .long    0
    .long    L_OBJC_CLASS_METHODS_Foo
    .long    0
    .long    0
    .long    0
    .long    0

    .section    __TEXT,__cstring,cstring_literals,"w"
L_OBJC_METH_VAR_NAME_1:
    .asciz     "count"

L_OBJC_METH_VAR_TYPE_2:
    .asciz     "i"

    .section    __OBJC,__instance_vars,regular,no_dead_strip,"w"
    .align    4
L_OBJC_INSTANCE_VARIABLES_Foo:
    .long    1
    .long    L_OBJC_METH_VAR_NAME_1
    .long    L_OBJC_METH_VAR_TYPE_2
    .long    0

    .section    __OBJC,__class,regular,no_dead_strip,"w"
    .align    4
L_OBJC_CLASS_Foo:
    .long    L_OBJC_METACLASS_Foo
    .long    0
    .long    L_OBJC_CLASS_NAME_
    .long    0
    .long    1
    .long    4
    .long    L_OBJC_INSTANCE_VARIABLES_Foo
    .long    0
    .long    0
    .long    0
    .long    0
    .long    0

    .section    __OBJC,__cls_refs,literal_pointers,no_dead_strip,"w"
    .align    4
L_OBJC_CLASS_REFERENCES_:
    .long    L_OBJC_CLASS_NAME_

    .section    __OBJC,__message_refs,literal_pointers,no_dead_strip,"w"
    .align    4
L_OBJC_SELECTOR_REFERENCES_:
    .long    L_OBJC_METH_VAR_NAME_

    .section    __TEXT,__cstring,cstring_literals,"w"
L_OBJC_CLASS_NAME_3:
    .zero    1

    .section    __OBJC,__symbols,regular,no_dead_strip,"w"
    .align    4
L_OBJC_SYMBOLS:
    .long    0
    .long    0
    .short    1
    .short    0
    .long    L_OBJC_CLASS_Foo

    .section    __OBJC,__module_info,regular,no_dead_strip,"w"
    .align    4
L_OBJC_MODULES:
    .long    7
    .long    16
    .long    L_OBJC_CLASS_NAME_3
    .long    L_OBJC_SYMBOLS

我认为关键问题在于 .s 文件的创建方式。

谁能帮我解决这个问题? 虽然使用这些 .dll 文件无法创建业务应用程序。

但是通过使用这些.dll,我们可以在window平台上构建一个更好的可可学习环境。所有框架的windows版本都比gnustep更稳定有用。

谢谢。

【问题讨论】:

    标签: objective-c windows gcc runtime clang


    【解决方案1】:

    嗯,首先这违反了 iTunes EULA,所以无论是否商业,你都不应该这样做。

    第二个问题是 clang/gcc 中的 -fnext-runtime 仅适用于 Darwin,它缺少 Windows 和其他操作系统的各种零碎。我(受过教育)猜测并假设 -fgnu-runtime 对于链接 Apple 自己的框架是无用的。

    如您所见,-fnext-runtime 正在发出达尔文特定的汇编命令,例如.lazy_reference,在 Windows 上,不是一个好的开始。

    gcc 中的 -fnext-runtime 一直是这种情况,现在已经很长一段时间了,没有人在非达尔文系统的主线中维护 -fnext-runtime。

    我粗略的理解是Apple其实并没有直接在Windows上使用clang,他们将Objective-C改写成C,然后使用Visual Studio为Windows编译。

    您可以开始对 clang 进行一些严肃的黑客攻击,或者不要打扰。

    【讨论】:

    • 但我也认为使用Visual Studio 编译Objective-C 应用程序对Apple 来说不是一件好事。使用llvm-gcc 的Apple 自定义版本可以让事情变得更好。谢谢你告诉我.s 文件是达尔文汇编代码。我会检查 gcc 源代码。非常感谢。
    • 是的,clang 对 Windows 的支持仍然有点粗糙,Apple 似乎没有在这方面做任何工作,不幸的是,很少有其他人也在做。
    【解决方案2】:

    我尝试和你最近做的完全一样,我发现了类似的结果。核心(技术而非法律)问题是 -fnext-runtime 在 Windows 上不受支持,并且可能永远不会受到支持。我马上就到-fgnu-runtime。

    无论您在 Windows 上编写的 Objective-C 程序多么基本,您最终都会得到未解析的引用。查看.dll 文件,您会发现它们根本不包含在Windows 上链接使用Clang 编译的Objective-C 程序所需的一些核心方法。 (如果没记错的话,我能够编译一个至少只有 2 个未解析引用的程序。

    所以在不支持-fnext-runtime的基础上,可以试试-fgnu-runtime配合GCC。当然,您会失去与所有 Apple 库的兼容性,但您确实可以在 Windows 上运行 Objective-C 程序。 GCC 最近升级了他们的 Objective-C 运行时,使其与 Apple 的 Objective-C 运行时几乎相同,因此兼容性现在已不再是问题。

    同样,您没有获得 Apple 的库,您必须自己编写它们(任何接受者?)但运行时以相同的方式工作。 make your own NSObject(尽管查看 Apple's implementation 有帮助)和 Constant String @"..." object 需要一些工作,但是一旦拥有它们,您就可以构建自己的 Windows 兼容的 Objective-C 框架。根据经验,我可以告诉你,这绝对是可能的。

    【讨论】:

      猜你喜欢
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      • 1970-01-01
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      相关资源
      最近更新 更多