| Thread overview | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
May 01, 2007 Win32 example/tutorial with GC? | ||||
|---|---|---|---|---|
| ||||
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 Re: Win32 example/tutorial with GC? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Johnny | 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 Re: Win32 example/tutorial with GC? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to David Friedman Attachments: | 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 Re: Win32 example/tutorial with GC? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Johnny | 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 Re: Win32 example/tutorial with GC? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Frits van Bommel | 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__anonymous6__initZ]+0x0): undefined reference to `_D13TypeInfo_Enum6__vtblZ'
WinMenu.o:WinMenu.d:(.data$_D31TypeInfo_E7WinMenu11__anonymous6__initZ[__D31TypeInfo_E7WinMenu11__anonymous6__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 02, 2007 Re: Win32 example/tutorial with GC? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Johnny | 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 Re: Win32 example/tutorial with GC? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to David Friedman | 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()
>>
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply