www.digitalmars.com         C & C++   DMDScript  

D.gnu - Win32 example/tutorial with GC?

reply "Johnny" <johnkirollos yahoo.com> writes:
Hello

I'm trying to make a simple windows GUI application using D.
First, I used DMD, and I suffered a lot due to it's OMF format. So I decided
to switch to GDC (with MinGW). But I still receive linking errors related to
Phobos :-(

Are there any examples or tutorials that can help in this area? I.e. ones
that show how to set the GC correctly... There are such examples for DMD,
but I couldn't find similar examples for GDC... So any help?

Thanks
john
May 01 2007
parent reply David Friedman <dvdfrdmn users.ess-eff.net> writes:
Johnny wrote:
 Hello
 
 I'm trying to make a simple windows GUI application using D.
 First, I used DMD, and I suffered a lot due to it's OMF format. So I decided
 to switch to GDC (with MinGW). But I still receive linking errors related to
 Phobos :-(
 
 Are there any examples or tutorials that can help in this area? I.e. ones
 that show how to set the GC correctly... There are such examples for DMD,
 but I couldn't find similar examples for GDC... So any help?
 
 Thanks
 john
 
 
 
If you are linking with other libraries, you may need to explicitly link against -lgphobos with that library early on the command line: gdc a.o b.o -lgphobos -lwsock32 If you do not need a custom WinMain, just write the normal D main(). Otherwise, the easiest thing to do is call _d_run_Dmain: --- import std.c.windows.windows; extern (C) int _d_run_Dmain(int argc, char **argv); extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char * fake_argv ="x"; return _d_run_Dmain(1, & fake_argv); } int main(char[][] args) { return 0; } --- David
May 01 2007
parent reply Johnny <johnnykiro gmail.com> writes:
David,

It's still not working with me; I must have something wrong in my code 
or in my MinGW/GDC installation.

Here is a simple example that I tried to compile with GDC 0.23. I really 
wish not only to correct the problem, but to understand exactly what's 
going wrong:


Compilation Steps:
-----------------
1- $ gdc -c -v WinMenu.d  (OK)

	Reading specs from c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/specs
	Configured with: ../gcc-3.4.5-20060117-1/configure --prefix=/gdc 
--disable-shared --enable-languages=c,d --host=mingw32 --target=mingw32 
--with-gnu-ld --with-gnu-as --enable-threads --disable-nls 
--disable-win32-registry --disable-shared --enable-sjlj-exceptions
	Thread model: win32
	gcc version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007)
	 c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/cc1d.exe WinMenu.d -quiet 
-dumpbase WinMenu.d -auxbase WinMenu -version -iprefix 
c:\MinGW\bin\../lib/gcc/mingw32/3.4.5/ -o 
g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccoDaaaa.s
	GNU D version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007) (mingw32)
			compiled by GNU C version 3.4.2 (mingw-special).
	GGC heuristics: --param ggc-min-expand=46 --param ggc-min-heapsize=31678
	 c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/bin/as.exe 
-o WinMenu.o g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccoDaaaa.s


2- $ gdc -v -Wall -o  WinMenu-gdc.exe WinMenu.d -lgphobos  (Link errors)

	Reading specs from c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/specs
	Configured with: ../gcc-3.4.5-20060117-1/configure --prefix=/gdc 
--disable-shared --enable-languages=c,d --host=mingw32 --target=mingw32 
--with-gnu-ld --with-gnu-as --enable-threads --disable-nls 
--disable-win32-registry --disable-shared --enable-sjlj-exceptions
	Thread model: win32
	gcc version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007)
	 c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/cc1d.exe WinMenu.d -quiet 
-dumpbase WinMenu.d -auxbase WinMenu -Wall -version -iprefix 
c:\MinGW\bin\../lib/gcc/mingw32/3.4.5/ -o 
g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccQJaaaa.s
	GNU D version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007) (mingw32)
			compiled by GNU C version 3.4.2 (mingw-special).
	GGC heuristics: --param ggc-min-expand=46 --param ggc-min-heapsize=31678
	 c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/bin/as.exe 
-o g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccwjbaaa.o 
g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccQJaaaa.s
	 c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe -Bdynamic -o 
WinMenu-gdc.exe /mingw/lib/crt2.o 
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o 
-Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5 -Lc:/MinGW/bin/../lib/gcc 
-L/gdc/lib/gcc/mingw32/3.4.5 
-Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/lib 
-L/mingw/lib -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../.. 
-L/gdc/lib/gcc/mingw32/3.4.5/../../.. 
g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccwjbaaa.o -lgphobos -lgphobos 
-lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 
-ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt 
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtend.o
	/mingw/lib/libgphobos.a(cmain.o):(.text+0x19): undefined reference to 
`_Dmain'
	collect2: ld returned 1 exit status


It seems that the Phobos library itself refers to _Dmain and linker 
can't find it, so where is _Dmain, and why isn't it found?


The source code file is attached.

Thanks
john



David Friedman wrote:
 Johnny wrote:
 Hello

 I'm trying to make a simple windows GUI application using D.
 First, I used DMD, and I suffered a lot due to it's OMF format. So I 
 decided
 to switch to GDC (with MinGW). But I still receive linking errors 
 related to
 Phobos :-(

 Are there any examples or tutorials that can help in this area? I.e. ones
 that show how to set the GC correctly... There are such examples for DMD,
 but I couldn't find similar examples for GDC... So any help?

 Thanks
 john
If you are linking with other libraries, you may need to explicitly link against -lgphobos with that library early on the command line: gdc a.o b.o -lgphobos -lwsock32 If you do not need a custom WinMain, just write the normal D main(). Otherwise, the easiest thing to do is call _d_run_Dmain: --- import std.c.windows.windows; extern (C) int _d_run_Dmain(int argc, char **argv); extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char * fake_argv ="x"; return _d_run_Dmain(1, & fake_argv); } int main(char[][] args) { return 0; } --- David
May 01 2007
next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Johnny wrote:
 It seems that the Phobos library itself refers to _Dmain and linker 
 can't find it, so where is _Dmain, and why isn't it found?
"_Dmain" is how the "main" of your program normally gets renamed ("mangled") by the D compiler. It's not found because you didn't write one :). What happens if you add an empty "void main() {}" ? I'm pretty sure the Windows version of DMD (or perhaps optlink) will automatically use WinMain instead of main if it sees it, but I'm not sure about GDC/MinGW. Maybe some special command-line option needs to be passed?
May 01 2007
parent Johnny <johnnykiro gmail.com> writes:
Hi Frits

I added the empty main() and the linking succeeds, however, the program 
does nothing since the entry point (main() )  returns immediately (which 
is expected.
So may be the good question is how to make GDC accept WinMain as an 
entry point for Windows GUI programs.

Strangely, I have another simpler GUI program that links correctly with 
WinMain:

import win32.winbase;
import win32.windef;
import win32.winuser;

extern(Windows) int WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         PSTR szCmdLine,
                         int iCmdShow)
{
       MessageBoxA(null, "Hello", "Hello Demo", MB_OK);
       return (0);
}


- Here is how I compile it:

	Administrator home /cygdrive/c/D-Projects/gdc-test
	$ gdc -c gdctestwin.d -I"C:\dmd"


- Attempting to link with GDC fails:

	Administrator home /cygdrive/c/D-Projects/gdc-test
	$ gdc -o gdctestwin.exe  gdctestwin.o
	/mingw/lib/libgphobos.a(cmain.o):(.text+0x19): undefined 	reference to 
`_Dmain'
	collect2: ld returned 1 exit status


- Linking with GCC sycceeds:

	Administrator home /cygdrive/c/D-Projects/gdc-test
	$ gcc -o gdctestwin.exe  gdctestwin.o


- I tried to use GCC for linking my 1st example, but I get other errors:

	$ gcc -Wall -o WinMenu-gdc.exe WinMenu.o
	WinMenu.o:WinMenu.d:(.text+0xe7): undefined reference to 
`_D3std6string9toStringzFAaZPa'
	WinMenu.o:WinMenu.d:(.text+0xfb): undefined reference to 
`_D3std6string9toStringzFAaZPa'
	WinMenu.o:WinMenu.d:(.text+0x152): undefined reference to 
`CreateWindowA 44'
	WinMenu.o:WinMenu.d:(.text+0x17e): undefined reference to `_d_assert'
	WinMenu.o:WinMenu.d:(.text+0x269): undefined reference to `LOWORD 4'
	WinMenu.o:WinMenu.d:(.text+0x35a): undefined reference to 	`_Dmodule_ref'
	WinMenu.o:WinMenu.d:(.text+0x365): undefined reference to `_Dmodule_ref'
	WinMenu.o:WinMenu.d:(.data+0x48): undefined reference to 
`_D3std6string12__ModuleInfoZ'
	 
WinMenu.o:WinMenu.d:(.data$_D31TypeInfo_E7WinMenu11__anonymous6__initZ[__D31TypeInfo_E7WinMenu11__anon
mous6__initZ]+0x0): 
	undefined reference to `_D13TypeInfo_Enum6__vtblZ'
WinMenu.o:WinMenu.d:(.data$_D31TypeInfo_E7WinMenu11__anonymous6__initZ[__D31TypeInfo_E7WinMenu11__anon
mous6__initZ]+0x8): 
	undefined reference to `_D10TypeInfo_i6__initZ'
	collect2: ld returned 1 exit status

- And here I added Phobos, but I get 1st error:

	$ gcc -Wall -o WinMenu-gdc.exe WinMenu.o -lgphobos
	/mingw/lib/libgphobos.a(cmain.o):(.text+0x19): undefined reference to 
`_Dmain'
	collect2: ld returned 1 exit status

So I'm confused :-( .. what are the definitive steps to compile and link 
a Windows GUI program using GDC/MinGW?

Regards,
john


Frits van Bommel wrote:
 Johnny wrote:
 It seems that the Phobos library itself refers to _Dmain and linker 
 can't find it, so where is _Dmain, and why isn't it found?
"_Dmain" is how the "main" of your program normally gets renamed ("mangled") by the D compiler. It's not found because you didn't write one :). What happens if you add an empty "void main() {}" ? I'm pretty sure the Windows version of DMD (or perhaps optlink) will automatically use WinMain instead of main if it sees it, but I'm not sure about GDC/MinGW. Maybe some special command-line option needs to be passed?
May 01 2007
prev sibling parent reply David Friedman <dvdfrdmn users.ess-eff.net> writes:
Johnny,

I had the main/WinMain call order backwards.  So, with the current 
distribution, I do not think it is possible to get the linker to 
automatically use whichever of main or WinMain is defined (like DMD does(?))

There is a simple workaround, however:  Use the following command to link.

gdc -o WinMenu-gdc.exe WinMenu.d -lmingw32

This will pull in MinGW's C main() that calls WinMain.  The

Also, you probably want to add -mwindows to the link command line so the 
.exe will not open a console when run.

David

Johnny wrote:
 David,
 
 It's still not working with me; I must have something wrong in my code 
 or in my MinGW/GDC installation.
 
 Here is a simple example that I tried to compile with GDC 0.23. I really 
 wish not only to correct the problem, but to understand exactly what's 
 going wrong:
 
 
 Compilation Steps:
 -----------------
 1- $ gdc -c -v WinMenu.d  (OK)
 
     Reading specs from c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/specs
     Configured with: ../gcc-3.4.5-20060117-1/configure --prefix=/gdc 
 --disable-shared --enable-languages=c,d --host=mingw32 --target=mingw32 
 --with-gnu-ld --with-gnu-as --enable-threads --disable-nls 
 --disable-win32-registry --disable-shared --enable-sjlj-exceptions
     Thread model: win32
     gcc version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007)
      c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/cc1d.exe WinMenu.d -quiet 
 -dumpbase WinMenu.d -auxbase WinMenu -version -iprefix 
 c:\MinGW\bin\../lib/gcc/mingw32/3.4.5/ -o 
 g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccoDaaaa.s
     GNU D version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007) 
 (mingw32)
             compiled by GNU C version 3.4.2 (mingw-special).
     GGC heuristics: --param ggc-min-expand=46 --param 
 ggc-min-heapsize=31678
      
 c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/bin/as.exe -o 
 WinMenu.o g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccoDaaaa.s
 
 
 2- $ gdc -v -Wall -o  WinMenu-gdc.exe WinMenu.d -lgphobos  (Link errors)
 
     Reading specs from c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/specs
     Configured with: ../gcc-3.4.5-20060117-1/configure --prefix=/gdc 
 --disable-shared --enable-languages=c,d --host=mingw32 --target=mingw32 
 --with-gnu-ld --with-gnu-as --enable-threads --disable-nls 
 --disable-win32-registry --disable-shared --enable-sjlj-exceptions
     Thread model: win32
     gcc version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007)
      c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/cc1d.exe WinMenu.d -quiet 
 -dumpbase WinMenu.d -auxbase WinMenu -Wall -version -iprefix 
 c:\MinGW\bin\../lib/gcc/mingw32/3.4.5/ -o 
 g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccQJaaaa.s
     GNU D version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007) 
 (mingw32)
             compiled by GNU C version 3.4.2 (mingw-special).
     GGC heuristics: --param ggc-min-expand=46 --param 
 ggc-min-heapsize=31678
      
 c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/bin/as.exe -o 
 g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccwjbaaa.o 
 g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccQJaaaa.s
      c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe -Bdynamic -o 
 WinMenu-gdc.exe /mingw/lib/crt2.o 
 c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o 
 -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5 -Lc:/MinGW/bin/../lib/gcc 
 -L/gdc/lib/gcc/mingw32/3.4.5 
 -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/lib 
 -L/mingw/lib -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../.. 
 -L/gdc/lib/gcc/mingw32/3.4.5/../../.. 
 g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccwjbaaa.o -lgphobos -lgphobos 
 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 
 -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt 
 c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtend.o
     /mingw/lib/libgphobos.a(cmain.o):(.text+0x19): undefined reference 
 to `_Dmain'
     collect2: ld returned 1 exit status
 
 
 It seems that the Phobos library itself refers to _Dmain and linker 
 can't find it, so where is _Dmain, and why isn't it found?
 
 
 The source code file is attached.
 
 Thanks
 john
 
 
 
 David Friedman wrote:
 Johnny wrote:
 Hello

 I'm trying to make a simple windows GUI application using D.
 First, I used DMD, and I suffered a lot due to it's OMF format. So I 
 decided
 to switch to GDC (with MinGW). But I still receive linking errors 
 related to
 Phobos :-(

 Are there any examples or tutorials that can help in this area? I.e. 
 ones
 that show how to set the GC correctly... There are such examples for 
 DMD,
 but I couldn't find similar examples for GDC... So any help?

 Thanks
 john
If you are linking with other libraries, you may need to explicitly link against -lgphobos with that library early on the command line: gdc a.o b.o -lgphobos -lwsock32 If you do not need a custom WinMain, just write the normal D main(). Otherwise, the easiest thing to do is call _d_run_Dmain: --- import std.c.windows.windows; extern (C) int _d_run_Dmain(int argc, char **argv); extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char * fake_argv ="x"; return _d_run_Dmain(1, & fake_argv); } int main(char[][] args) { return 0; } --- David
------------------------------------------------------------------------ import std.c.windows.windows; import std.c.stdio; import std.string; char[] Test_string="You selected Test menu item"; char[] Hello_string="Hello, my friend"; char[] Goodbye_string="See you again, bye"; HINSTANCE hInstance; enum { IDM_TEST=1, IDM_HELLO, IDM_GOODBYE, IDM_EXIT } int doit() { hInstance = GetModuleHandleA(null); WNDCLASS wc; wc.lpszClassName = "DWndClass"; wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = &WndProc; wc.hInstance = hInstance; wc.hIcon = LoadIconA(cast(HINSTANCE) null, IDI_APPLICATION); wc.hCursor = LoadCursorA(cast(HINSTANCE) null, IDC_CROSS); wc.hbrBackground = cast(HBRUSH) (COLOR_WINDOW + 1); wc.lpszMenuName = "TestMenu"; wc.cbClsExtra = wc.cbWndExtra = 0; RegisterClassA(&wc); HWND hWnd; char[] sClass="My class 0"; char[] sApp="My Application 0"; /+++++ hWnd = CreateWindowA("DWndClass", "Just a window", WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, HWND_DESKTOP, cast(HMENU) null, hInstance, null); +++++/ hWnd = CreateWindowA(toStringz(sClass), toStringz(sApp), WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, HWND_DESKTOP, cast(HMENU) null, hInstance, null); assert(hWnd); ShowWindow(hWnd,SW_SHOWNORMAL); UpdateWindow(hWnd); MSG msg; while (GetMessageA(&msg, cast(HWND) null, 0, 0)) { TranslateMessage(&msg); DispatchMessageA(&msg); } return 1; }//doit() /**********************************************************/ /* Note the similarity of this code to the console D startup * code in \dmd\src\phobos\dmain2.d * You'll also need a .def file with at least the following in it: * EXETYPE NT * SUBSYSTEM WINDOWS */ extern (C) void gc_init(); extern (C) void gc_term(); extern (C) void _minit(); extern (C) void _moduleCtor(); extern (C) void _moduleUnitTests(); extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int result; // gc_init(); // initialize garbage collector // _minit(); // initialize module constructor table /* try { _moduleCtor(); // call module constructors _moduleUnitTests(); // run unit tests (optional) result = doit(); // insert user code here } */ /* catch (Object o) // catch any uncaught exceptions { MessageBoxA(null, cast(char *)o.toString(), "Error", MB_OK | MB_ICONEXCLAMATION); result = 0; // failed } */ // gc_term(); // run finalizers; terminate garbage collector return result; } extern(Windows) { void DestroyWindow(HANDLE); } extern(Windows) int WndProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_DESTROY: PostQuitMessage(cast(int) null); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_TEST: MessageBoxA(cast(HANDLE) null,"Test string","Menu test",MB_OK); case IDM_HELLO: MessageBoxA(cast(HANDLE) null,"Hello in D","Menu test",MB_OK); break; case IDM_GOODBYE: MessageBoxA(cast(HANDLE) null,"Goodbye in D","Menu test", MB_OK); break; default: DestroyWindow(hWnd); }//switch menu selection break; default: return DefWindowProcA(hWnd,uMsg,wParam,lParam); }//switch msg return 0; }//WndProc()
May 01 2007
parent reply Johnny <johnnykiro gmail.com> writes:
Hello David

I didn't know how exactly to change the code in order to add the mingw32 
lib (-lmingw32), so I tried a different way:

	void main()
	{
	        int 
exit_code=WinMain(GetModuleHandle(null),null,GetCommandLineA(),SW_SHOWDEFAULT);
	        ExitProcess(exit_code);
	}

	extern (Windows) int WinMain(HINSTANCE hInstance,
	        HINSTANCE hPrevInstance,
	        LPSTR lpCmdLine,
	        int nCmdShow)
	{
	    uint result;
	    result = CMDIApp.MdiWinMain(hInstance, hPrevInstance, lpCmdLine, 
nCmdShow);
	    return result;
	}


Now I have these errors:

$ ./build-gdc.sh
Compiling resources file (mdiapp.rc)..
Compiling main.d..
Linking to libraries..
main.o:main.d:(.text+0x80): undefined reference to 
`_D6mdiapp7CMDIApp10MdiWinMainWT5win325winnt6HANDLET5win325winnt6HANDLEPaiZk 16'
main.o:main.d:(.data+0x30): undefined reference to 
`_D6mdiapp12__ModuleInfoZ'
collect2: ld returned 1 exit status

I'll try to figure out the reason of these errors (any hint?).

Thanks
John



David Friedman wrote:
 Johnny,
 
 I had the main/WinMain call order backwards.  So, with the current 
 distribution, I do not think it is possible to get the linker to 
 automatically use whichever of main or WinMain is defined (like DMD 
 does(?))
 
 There is a simple workaround, however:  Use the following command to link.
 
 gdc -o WinMenu-gdc.exe WinMenu.d -lmingw32
 
 This will pull in MinGW's C main() that calls WinMain.  The
 
 Also, you probably want to add -mwindows to the link command line so the 
 .exe will not open a console when run.
 
 David
 
 Johnny wrote:
 David,

 It's still not working with me; I must have something wrong in my code 
 or in my MinGW/GDC installation.

 Here is a simple example that I tried to compile with GDC 0.23. I 
 really wish not only to correct the problem, but to understand exactly 
 what's going wrong:


 Compilation Steps:
 -----------------
 1- $ gdc -c -v WinMenu.d  (OK)

     Reading specs from c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/specs
     Configured with: ../gcc-3.4.5-20060117-1/configure --prefix=/gdc 
 --disable-shared --enable-languages=c,d --host=mingw32 
 --target=mingw32 --with-gnu-ld --with-gnu-as --enable-threads 
 --disable-nls --disable-win32-registry --disable-shared 
 --enable-sjlj-exceptions
     Thread model: win32
     gcc version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007)
      c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/cc1d.exe WinMenu.d 
 -quiet -dumpbase WinMenu.d -auxbase WinMenu -version -iprefix 
 c:\MinGW\bin\../lib/gcc/mingw32/3.4.5/ -o 
 g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccoDaaaa.s
     GNU D version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007) 
 (mingw32)
             compiled by GNU C version 3.4.2 (mingw-special).
     GGC heuristics: --param ggc-min-expand=46 --param 
 ggc-min-heapsize=31678
      
 c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/bin/as.exe 
 -o WinMenu.o g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccoDaaaa.s


 2- $ gdc -v -Wall -o  WinMenu-gdc.exe WinMenu.d -lgphobos  (Link errors)

     Reading specs from c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/specs
     Configured with: ../gcc-3.4.5-20060117-1/configure --prefix=/gdc 
 --disable-shared --enable-languages=c,d --host=mingw32 
 --target=mingw32 --with-gnu-ld --with-gnu-as --enable-threads 
 --disable-nls --disable-win32-registry --disable-shared 
 --enable-sjlj-exceptions
     Thread model: win32
     gcc version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007)
      c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/cc1d.exe WinMenu.d 
 -quiet -dumpbase WinMenu.d -auxbase WinMenu -Wall -version -iprefix 
 c:\MinGW\bin\../lib/gcc/mingw32/3.4.5/ -o 
 g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccQJaaaa.s
     GNU D version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007) 
 (mingw32)
             compiled by GNU C version 3.4.2 (mingw-special).
     GGC heuristics: --param ggc-min-expand=46 --param 
 ggc-min-heapsize=31678
      
 c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/bin/as.exe 
 -o g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccwjbaaa.o 
 g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccQJaaaa.s
      c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe -Bdynamic 
 -o WinMenu-gdc.exe /mingw/lib/crt2.o 
 c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o 
 -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5 -Lc:/MinGW/bin/../lib/gcc 
 -L/gdc/lib/gcc/mingw32/3.4.5 
 -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/lib 
 -L/mingw/lib -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../.. 
 -L/gdc/lib/gcc/mingw32/3.4.5/../../.. 
 g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccwjbaaa.o -lgphobos -lgphobos 
 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 
 -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt 
 c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtend.o
     /mingw/lib/libgphobos.a(cmain.o):(.text+0x19): undefined reference 
 to `_Dmain'
     collect2: ld returned 1 exit status


 It seems that the Phobos library itself refers to _Dmain and linker 
 can't find it, so where is _Dmain, and why isn't it found?


 The source code file is attached.

 Thanks
 john



 David Friedman wrote:
 Johnny wrote:
 Hello

 I'm trying to make a simple windows GUI application using D.
 First, I used DMD, and I suffered a lot due to it's OMF format. So I 
 decided
 to switch to GDC (with MinGW). But I still receive linking errors 
 related to
 Phobos :-(

 Are there any examples or tutorials that can help in this area? I.e. 
 ones
 that show how to set the GC correctly... There are such examples for 
 DMD,
 but I couldn't find similar examples for GDC... So any help?

 Thanks
 john
If you are linking with other libraries, you may need to explicitly link against -lgphobos with that library early on the command line: gdc a.o b.o -lgphobos -lwsock32 If you do not need a custom WinMain, just write the normal D main(). Otherwise, the easiest thing to do is call _d_run_Dmain: --- import std.c.windows.windows; extern (C) int _d_run_Dmain(int argc, char **argv); extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char * fake_argv ="x"; return _d_run_Dmain(1, & fake_argv); } int main(char[][] args) { return 0; } --- David
------------------------------------------------------------------------ import std.c.windows.windows; import std.c.stdio; import std.string; char[] Test_string="You selected Test menu item"; char[] Hello_string="Hello, my friend"; char[] Goodbye_string="See you again, bye"; HINSTANCE hInstance; enum { IDM_TEST=1, IDM_HELLO, IDM_GOODBYE, IDM_EXIT } int doit() { hInstance = GetModuleHandleA(null); WNDCLASS wc; wc.lpszClassName = "DWndClass"; wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = &WndProc; wc.hInstance = hInstance; wc.hIcon = LoadIconA(cast(HINSTANCE) null, IDI_APPLICATION); wc.hCursor = LoadCursorA(cast(HINSTANCE) null, IDC_CROSS); wc.hbrBackground = cast(HBRUSH) (COLOR_WINDOW + 1); wc.lpszMenuName = "TestMenu"; wc.cbClsExtra = wc.cbWndExtra = 0; RegisterClassA(&wc); HWND hWnd; char[] sClass="My class 0"; char[] sApp="My Application 0"; /+++++ hWnd = CreateWindowA("DWndClass", "Just a window", WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, HWND_DESKTOP, cast(HMENU) null, hInstance, null); +++++/ hWnd = CreateWindowA(toStringz(sClass), toStringz(sApp), WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, HWND_DESKTOP, cast(HMENU) null, hInstance, null); assert(hWnd); ShowWindow(hWnd,SW_SHOWNORMAL); UpdateWindow(hWnd); MSG msg; while (GetMessageA(&msg, cast(HWND) null, 0, 0)) { TranslateMessage(&msg); DispatchMessageA(&msg); } return 1; }//doit() /**********************************************************/ /* Note the similarity of this code to the console D startup * code in \dmd\src\phobos\dmain2.d * You'll also need a .def file with at least the following in it: * EXETYPE NT * SUBSYSTEM WINDOWS */ extern (C) void gc_init(); extern (C) void gc_term(); extern (C) void _minit(); extern (C) void _moduleCtor(); extern (C) void _moduleUnitTests(); extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int result; // gc_init(); // initialize garbage collector // _minit(); // initialize module constructor table /* try { _moduleCtor(); // call module constructors _moduleUnitTests(); // run unit tests (optional) result = doit(); // insert user code here } */ /* catch (Object o) // catch any uncaught exceptions { MessageBoxA(null, cast(char *)o.toString(), "Error", MB_OK | MB_ICONEXCLAMATION); result = 0; // failed } */ // gc_term(); // run finalizers; terminate garbage collector return result; } extern(Windows) { void DestroyWindow(HANDLE); } extern(Windows) int WndProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_DESTROY: PostQuitMessage(cast(int) null); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_TEST: MessageBoxA(cast(HANDLE) null,"Test string","Menu test",MB_OK); case IDM_HELLO: MessageBoxA(cast(HANDLE) null,"Hello in D","Menu test",MB_OK); break; case IDM_GOODBYE: MessageBoxA(cast(HANDLE) null,"Goodbye in D","Menu test", MB_OK); break; default: DestroyWindow(hWnd); }//switch menu selection break; default: return DefWindowProcA(hWnd,uMsg,wParam,lParam); }//switch msg return 0; }//WndProc()
May 04 2007
parent Dejan Lekic <dejan.lekic gmail.com> writes:
Johnny, have you tried the last compile/link command David wrote?
I think it will successfully compile/link your application.
May 08 2007