D.gnu - Win32 example/tutorial with GC?
- Johnny (10/10) May 01 2007 Hello
- David Friedman (23/39) May 01 2007 If you are linking with other libraries, you may need to explicitly link...
- Johnny (64/111) May 01 2007 David,
- Frits van Bommel (9/11) May 01 2007 "_Dmain" is how the "main" of your program normally gets renamed
- Johnny (61/74) May 01 2007 Hi Frits
- David Friedman (11/295) May 01 2007 Johnny,
- Johnny (33/343) May 04 2007 Hello David
- Dejan Lekic (2/2) May 08 2007 Johnny, have you tried the last compile/link command David 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
May 01 2007
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 johnIf 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
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 johnIf 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
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
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
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:------------------------------------------------------------------------ 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()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 johnIf 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
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:------------------------------------------------------------------------ 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()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 johnIf 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 04 2007
Johnny, have you tried the last compile/link command David wrote? I think it will successfully compile/link your application.
May 08 2007