<sect1 id="gcc"><title>Using GCC with Cygwin</title> <sect2 id="gcc-cons"><title>Console Mode Applications</title> <para>Use gcc to compile, just like under UNIX. Refer to the GCC User's Guide for information on standard usage and options. Here's a simple example:</para> <example> <title>Building Hello World with GCC</title> <screen> <prompt>C:\></prompt> <userinput>gcc hello.c -o hello.exe</userinput> <prompt>C:\></prompt> <userinput>hello.exe</userinput> Hello, World <prompt>C:\></prompt> </screen> </example> </sect2> <sect2 id="gcc-gui"><title>GUI Mode Applications</title> <para>Cygwin allows you to build programs with full access to the standard Windows 32-bit API, including the GUI functions as defined in any Microsoft or off-the-shelf publication. However, the process of building those applications is slightly different, as you'll be using the GNU tools instead of the Microsoft tools.</para> <para>For the most part, your sources won't need to change at all. However, you should remove all __export attributes from functions and replace them like this:</para> <screen> int foo (int) __attribute__ ((__dllexport__)); int foo (int i) </screen> <para>The Makefile is similar to any other UNIX-like Makefile, and like any other Cygwin makefile. The only difference is that you use <command>gcc -mwindows</command> to link your program into a GUI application instead of a command-line application. Here's an example:</para> <screen> <![CDATA[ myapp.exe : myapp.o myapp.res gcc -mwindows myapp.o myapp.res -o $@ myapp.res : myapp.rc resource.h windres $< -O coff -o $@ ]]> </screen> <para>Note the use of <filename>windres</filename> to compile the Windows resources into a COFF-format <filename>.res</filename> file. That will include all the bitmaps, icons, and other resources you need, into one handy object file. Normally, if you omitted the "-O coff" it would create a Windows <filename>.res</filename> format file, but we can only link COFF objects. So, we tell <filename>windres</filename> to produce a COFF object, but for compatibility with the many examples that assume your linker can handle Windows resource files directly, we maintain the <filename>.res</filename> naming convention. For more information on <filename>windres</filename>, consult the Binutils manual. </para> <para> The following is a simple GUI-mode "Hello, World!" program to help get you started: <screen> /*-------------------------------------------------*/ /* hellogui.c - gui hello world */ /* build: gcc -mwindows hellogui.c -o hellogui.exe */ /*-------------------------------------------------*/ #include <windows.h> char glpszText[1024]; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { sprintf(glpszText, "Hello World\nGetCommandLine(): [%s]\n" "WinMain lpCmdLine: [%s]\n", lpCmdLine, GetCommandLine() ); WNDCLASSEX wcex; wcex.cbSize = sizeof(wcex); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = "HELLO"; wcex.hIconSm = NULL; if (!RegisterClassEx(&wcex)) return FALSE; HWND hWnd; hWnd = CreateWindow("HELLO", "Hello", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); RECT rt; GetClientRect(hWnd, &rt); DrawText(hdc, glpszText, strlen(glpszText), &rt, DT_TOP | DT_LEFT); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } </screen> </para> </sect2> </sect1>