Last Update: "2013/05/05 22:07:40 makoto"

ming-w64

2013/05 現在 は、wip に次のものがある。
modena@makoto 23:44:48/130504(..pkgsrc/wip)% ls -1d mingw-w64*
mingw-w64-binutils
mingw-w64-crt
mingw-w64-gcc
mingw-w64-headers
mingw-w64-libgcc
このうち gcc を入れると binutils は入るが、他のものは入らない。 まとめて全部入れてしまう
(cd /usr/pkgsrc/wip;
foreach i (mingw-w64*) 
(cd $i; make package-install)
end
modena@makoto 00:17:32/130505(~/c)% pkg_info |grep mingw |sort
で次のように見える。
mingw-w64-binutils-2.20.1 GNU binutils for win32/64 cross-development
mingw-w64-crt-2.0   C runtime for win32/64 cross-development
mingw-w64-gcc-4.5.1 GNU C/C++ Compiler for win32/64 cross-development
mingw-w64-headers-2.0 Headers for win32/64 cross-development
mingw-w64-libgcc-4.5.1 GCC target libraries for win32/64 cross-development
試しに使って見ると、まだうまく行かない。
modena@makoto 16:25:22/130505(~/c)% cat hello.c
#include <stdio.h>
main (){
 static char hello[] = "Hello World!";
 printf("%s\n", hello);
}
main は crt で puts は stdio.h (libc) かな。
modena@makoto 00:12:03/130505(~/c)% /usr/pkg/cross/bin/x86_64-w64-mingw32-gcc -c hello.c
modena@makoto 00:12:26/130505(~/c)% /usr/pkg/cross/bin/x86_64-w64-mingw32-ld  -o hello.exe hello.o
hello.o:hello.c:(.text+0x9): undefined reference to `_main'
hello.o:hello.c:(.text+0x15): undefined reference to `puts'
modena@makoto 00:21:22/130505(~/c)% foreach i  (/usr/pkg/cross/x86_64-w64-mingw32/lib/*.o )          
foreach> echo $i; /usr/pkg/cross/bin/x86_64-w64-mingw32-nm $i |grep 'T '
foreach> end
/usr/pkg/cross/x86_64-w64-mingw32/lib/CRT_fp10.o
0000000000000000 T _fpreset
0000000000000000 T fpreset
/usr/pkg/cross/x86_64-w64-mingw32/lib/CRT_fp8.o
0000000000000000 T _fpreset
0000000000000000 T fpreset
/usr/pkg/cross/x86_64-w64-mingw32/lib/CRT_glob.o
/usr/pkg/cross/x86_64-w64-mingw32/lib/CRT_noglob.o
/usr/pkg/cross/x86_64-w64-mingw32/lib/binmode.o
/usr/pkg/cross/x86_64-w64-mingw32/lib/crt1.o
00000000000004c0 T WinMainCRTStartup
00000000000004e0 T mainCRTStartup
/usr/pkg/cross/x86_64-w64-mingw32/lib/crt1u.o
00000000000004c0 T WinMainCRTStartup
00000000000004e0 T mainCRTStartup
/usr/pkg/cross/x86_64-w64-mingw32/lib/crt2.o
00000000000004c0 T WinMainCRTStartup
00000000000004e0 T mainCRTStartup
/usr/pkg/cross/x86_64-w64-mingw32/lib/crt2u.o
00000000000004c0 T WinMainCRTStartup
00000000000004e0 T mainCRTStartup
/usr/pkg/cross/x86_64-w64-mingw32/lib/crtbegin.o
/usr/pkg/cross/x86_64-w64-mingw32/lib/crtend.o
/usr/pkg/cross/x86_64-w64-mingw32/lib/dllcrt1.o
0000000000000420 T DllMainCRTStartup
0000000000000050 T _CRT_INIT
/usr/pkg/cross/x86_64-w64-mingw32/lib/dllcrt2.o
0000000000000420 T DllMainCRTStartup
0000000000000050 T _CRT_INIT
/usr/pkg/cross/x86_64-w64-mingw32/lib/gcrt0.o
0000000000000000 T _monstartup
/usr/pkg/cross/x86_64-w64-mingw32/lib/gcrt1.o
0000000000000000 T _monstartup
/usr/pkg/cross/x86_64-w64-mingw32/lib/gcrt2.o
0000000000000000 T _monstartup
/usr/pkg/cross/x86_64-w64-mingw32/lib/txtmode.o
modena@makoto 00:22:05/130505(~/c)%
次のようにすると、libmsvcrt あたりにあるらしい。
modena@makoto 16:56:08/130505(~/c)% foreach i (`pkg_info -qL mingw-w64-crt | grep crt`)
echo $i; /usr/pkg/cross/bin/x86_64-w64-mingw32-nm $i | grep puts 
end |less
modena@makoto 17:18:37/130505(~/c)% (cd /usr/pkg/cross/x86_64-w64-mingw32/; ls -l lib*/libmsvcrt*)
-rw-r--r--  1 root  wheel  842306 May  4 23:35 lib/libmsvcrt.a
-rw-r--r--  1 root  wheel  846524 May  4 23:34 lib32/libmsvcrt.a
-rw-r--r--  1 root  wheel  842306 May  4 23:35 lib64/libmsvcrt.a
まさにこれらしい
Adding leading underscores to assembly symbols with GCC on Win32?
puts の方はこれで解決する。main と puts が逆なんだな。
/usr/pkg/cross/bin/x86_64-w64-mingw32-gcc -fleading-underscore -c hello.c;
/usr/pkg/cross/bin/x86_64-w64-mingw32-ld hello.o \
             -L/usr/pkg/cross/x86_64-w64-mingw32/lib  -lmsvcrt -o hello.exe 
hello.o:hello.c:(.text+0x9): undefined reference to `__main'
-fno-leading-underscore の方が既定値のようだ。
ライブラリには _puts があるので _ を付ければ解決する。
main のあるライブラリを -fleading-underscore でコンパイルしておけば、いいのかな。さてどこでしょう。 crt の気がするが、_mainCRTstartup のような文字しかありません。
modena@makoto 17:32:21/130505(~/c)% foreach i (`pkg_info -qL mingw-w64-crt | grep crt`)       
echo $i; /usr/pkg/cross/bin/x86_64-w64-mingw32-nm $i | grep 'T _main'
end |less
の表示から拾うと:
/usr/pkg/cross/x86_64-w64-mingw32/lib32/crt1.o
000004d0 T _mainCRTStartup
/usr/pkg/cross/x86_64-w64-mingw32/lib32/crt1u.o
000004e0 T _mainCRTStartup
/usr/pkg/cross/x86_64-w64-mingw32/lib32/crt2.o
000004d0 T _mainCRTStartup
/usr/pkg/cross/x86_64-w64-mingw32/lib32/crt2u.o
000004e0 T _mainCRTStartup
mingw-w64-crt の中に、次のような部分がある
   201  static
   202  __declspec(noinline) int
   203  __tmainCRTStartup (void)
   204  {
...

   298      duplicate_ppstrings (argc, &argv);
   299      __main ();
「この __main の先がない」と言っている訳でしょう。 これを main に変更してしまえばいいと思う :-) そうでもなさそう
/usr/pkgsrc/wip/mingw-w64-crt/work/mingw-w64-v2.0/mingw-w64-crt/crt/crtexe.c
  :74:13: error: conflicting types for 'main'
/usr/pkgsrc/wip/mingw-w64-crt/work/mingw-w64-v2.0/mingw-w64-crt/include/internal.h
  :141:17: note: previous declaration of 'main' was here

二つの不思議

  1. -fleading-underscore を付けても付けなくても __main がないという (下線の数に変化がない) .. ここでコンパイルしているものではないようだ
  2. NetBSD/i386 や NetBSD/amd64 では call __main のような文はないが、 mingw-w64 では出て来る
NetBSD/i386
	.file	"hello.c"
	.data
	.type	hello.1590, @object
	.size	hello.1590, 13
hello.1590:
	.string	"Hello World!"
	.text
.globl main
	.type	main, @function
main:
	leal	4(%esp), %ecx
	andl	$-16, %esp
	pushl	-4(%ecx)
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ecx
	subl	$4, %esp
	subl	$12, %esp
	pushl	$hello.1590
	call	puts
	addl	$16, %esp
	movl	-4(%ebp), %ecx
	leave
	leal	-4(%ecx), %esp
	ret
	.size	main, .-main
	.ident	"GCC: (GNU) 4.1.3 20080704 prerelease (NetBSD nb3 20111107)"
NetBSD/amd64
	.file	"hello.c"
	.text
.globl main
	.type	main, @function
main:
.LFB1:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	movq	%rsp, %rbp
	.cfi_offset 6, -16
	.cfi_def_cfa_register 6
	movl	$hello.1937, %edi
	call	puts
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE1:
	.size	main, .-main
	.data
	.type	hello.1937, @object
	.size	hello.1937, 13
hello.1937:
	.string	"Hello World!"
	.ident	"GCC: (NetBSD nb2 20110806) 4.5.3"
mingw-w64-gcc に
-fleading-underscore を付けた時
	.file	"hello.c"
	.def	___main;	.scl	2;	.type	32;	.endef
	.text
.globl _main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
	pushq	%rbp
	movq	%rsp, %rbp
	subq	$32, %rsp
	call	___main
	leaq	_hello.2413(%rip), %rcx
	call	_puts
	leave
	ret
	.data
_hello.2413:
	.ascii "Hello World!\0"
	.def	_puts;	.scl	2;	.type	32;	.endef

次のようにしたら -lmingw32 を付ければ良いらしい
modena@makoto 21:27:33/130505(..cross/x86_64-w64-mingw32)%  \
  foreach i (`grep -r __main . | awk '{print $3}'`)
foreach> echo $i;  /usr/pkg/cross/bin/x86_64-w64-mingw32-nm  $i | grep __main
foreach> end
./lib/dllcrt1.o
                 U __main
./lib/dllcrt2.o
                 U __main
./lib/libmingw32.a
                 U __main
00000000000000a0 T __main
./lib64/dllcrt1.o
                 U __main
./lib64/dllcrt2.o
                 U __main
./lib64/libmingw32.a
                 U __main
00000000000000a0 T __main
./lib32/dllcrt1.o
         U ___main
./lib32/dllcrt2.o
         U ___main
./lib32/libmingw32.a
         U ___main
00000080 T ___main
消えませんね
/usr/pkg/cross/bin/x86_64-w64-mingw32-gcc -fleading-underscore -c hello.c ;
/usr/pkg/cross/bin/x86_64-w64-mingw32-ld  hello.o -lmsvcrt -lmingw32 \  
  -L/usr/pkg/cross/x86_64-w64-mingw32/lib  -o hello.exe
hello.o:hello.c:(.text+0x9): undefined reference to `__main'