2

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

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

从 mac os x 10.6 开始。苹果将​​ macosx 系统移至 x86 平台(不再支持 ppc),并通过可可技术重写系统应用程序。包括 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源代码。代码在这里:file: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”的方法。google 再搜索一下。所以,apple 的 libojbc 与 gnustep 的 libobjc 不同。苹果的 libojbc 使用 NextStep 库 interface.gnustep 做了一个不同的。

man gcc

gcc 对此有两种选择。

-fgnu-runtime. 这是 gcc 的默认选项,使用 gnu 风格的运行时。
-fnext-runtime,这使用下一步(现在是苹果)风格运行。

所以我将下一步样式选项传递给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 更稳定和有用。

谢谢。

4

2 回答 2

1

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

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

如您所见,-fnext-runtime 在 Windows 上发出 Darwin 特定的汇编程序命令,例如 .lazy_reference,这不是一个好的开始。

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

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

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

于 2012-10-16T03:02:06.963 回答
1

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

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

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

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

于 2013-07-06T04:57:17.703 回答