Mingw x64 – building a windows x64 program

Here is a little tutorial how to setup a x64 mingw toolchain under Eclipse CDT/Windows XP and above…

Requirements

For this tutorial, you will need :

  • Java SE (for Eclipse)
  • A zip of eclipse downloaded from Eclipse website (I use a basic Juno EE version, without CDT support).
  • A exe installer of TDM-gcc x64 (a mingw x64 version) from here (take the tdm64-gcc installer, at the time of writing this article, the version was tdm64-gcc-4.7.1-3)
  • Some hours… May be little bit long…

Configure environment

Eclipse installation

For eclipse, the installation is pretty basic one, just unzip, and here we go ! That’s all for basic installation, but we do want CDT (C++ support).
We will from that place, also add the CDT plugin to it :

  1. Go to Help (on top) -> Install new software…
  2. On the Work with select box, choose Juno
  3. On the type filter text enter C++
  4. On the list behind you should see Programming Languages And inside choose (some of them are not stricly needed but can be helpful) :
    • C/C++ Development Tools
    • C/C++ Development Tools SDK
    • CDT Visual C++ Support

Choose the CDT Plugin

Then you can click on next (many) to start installation.

MinGw x64

I use here the TDD gcc x64, a well done installer for MinGW64.
To install it, start the installer downloaded. Choose the Create button to start a fresh installation.

TDM GCC Create Installation

Then the system will download some data, and ask you for what you want to install… Choose here the MinGW-w64/TDM64 Experimental (32-bit and 64-bit) :

Choose MinGW-w64

Then you will have 3 pages before installing :

  • The first page let you install the mingw location (take what you want), we will refer to TDM_PATH in the rest of article to refer that path
  • The second page let you choose a download mirror, sourceforge may be already selected and good…
  • The last one allow you to select the installation process, the default Recommanded is already good too

Now the Mingw64 is installed and near ready to build ! We only miss a single step : include mingw in path. Go on the system path variable, and add at the end ;TDM_PATH\bin This will register all program in bin directory, available as if it was a default Windows program on cmd line.
If you have any trouble, or don’t know what i’m speaking about, there is a lot of tutorial everywhere, like this one.

Building test

Now we do have Eclipse CDT and Mingw64, we can make a try. Restart Eclipse, and go into File -> New -> Other… :
In the page, you should see C/C++ -> C++ Project

Create new project in Eclipse

Now we can go next, put a project name and choose Empty Project and MinGW GCC. If you don’t see MinGW GCC, the path is probably not set correctly. In this case, close Eclipse and resolve problem…
You can click finish directly.

Create new project in Eclipse - Choose MinGW

Now Eclipse should ask you to switch to C++ perspective, hit yes. And here we go, the projet appear in project list.

Let’s add some data into this :

  • Right click on project name -> New -> Folder and name it resource
  • Right click on project name -> New -> Source Folder and name it src
  • Right click on src folder created -> New -> Source File and name it main.cpp

Now we got a really basic structure : a resource folder (to store image, windows style, …), a src folder, and a file waiting for code.

Into main.cpp, enter the given code :

#include <iostream>

using namespace std;

int main() {
	std::cout << "hello";
	return 0;
}

Then you can right click on project name again, and choose Build Project. After compiling (everything should went fine…) you should see « hello » on console when running. If you arrive here with success, then we can start to make things little bit more complicated.

Build test

Building Windows Application

After this short tutorial to setup everything, we can start to create a lot more complicated one : we will show here both Win32 API usage on MinGW x64.

First lets change a little our main.cpp program (from this article) :


#include <windows.h>
#include <commctrl.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

int WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nCmdShow) {
	LPCTSTR MainWndClass = TEXT("MinGW Win32 Application");
	WNDCLASS wc;
	HWND hwnd;
	MSG msg;

	INITCOMMONCONTROLSEX icc;

	// Initialise common controls.
	icc.dwSize = sizeof(icc);
	icc.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&icc);

	wc.style=0;
	//wc.style=CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc=WindowProc;
	wc.cbClsExtra=0;
	wc.cbWndExtra=0;
	wc.hInstance=hInst;
	wc.hIcon=LoadIcon(NULL,IDI_WINLOGO);
	wc.hCursor=LoadCursor(NULL,IDC_ARROW);
	wc.hbrBackground=(HBRUSH)COLOR_WINDOWFRAME;
	wc.lpszMenuName=NULL;
	wc.lpszClassName=MainWndClass;

	MessageBox(0,"Hello, Windows","MinGW Test Program",MB_OK);

	if (!RegisterClass(&wc)) {
		return -1;
	}

	hwnd = CreateWindow(MainWndClass, MainWndClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, hInst, NULL);

	if (!hwnd) {
		return -1;
	}

	ShowWindow(hwnd,nCmdShow);
	UpdateWindow(hwnd);

	while(GetMessage(&msg,NULL,0,0) > 0) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
	switch (msg) {
		case WM_PAINT: {
			PAINTSTRUCT ps;
			HDC dc;
			RECT r;
			GetClientRect(hwnd,&r);
			dc=BeginPaint(hwnd,&ps);
			DrawText(dc,"Hello World",-1,&r,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
			EndPaint(hwnd,&ps);
			break;
		}

		case WM_DESTROY: {
			PostQuitMessage(0);
			break;
		}

		default:
			return DefWindowProc(hwnd, msg, wparam, lparam);
	}

	return 0;
}

This code is a kind of example, quite lite. We do want to add the XP/Vista/Seven looking style. But if you follow the article you will have trouble : the application will build, but not run. This is because this article is based on MinGW32 and not MinGW64.

Let’s continue so. For adding the Look & Feel from windows, we have to setup the manifest file. In resource folder we need thoose file (create them each time) :

  • resource.h
  • resource.rc
  • manifest_x86.xml
  • manifest_x64.xml

The result will looks like that :

Create manifest

Then you have of course to complete each file as follow :

Resource.h

//Create not existing value if needed (which is the case in MinGW)

#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID
    #define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#endif
#ifndef RT_MANIFEST
    #define RT_MANIFEST 24
#endif

Resource.rc

#include "resource.h"

//Allow to switch manifest between x86 and x64
#if defined(_M_X64) || defined(__amd64__)
	CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "manifest_x64.xml"
#else
	CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "manifest_x86.xml"
#endif

manifest_x86.xml and manifest_x64.xml

Both manifest are quite the same, only the build target change :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="Win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0"
                        processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*" />
    </dependentAssembly>
  </dependency>
</assembly>

For the x64, copy paste the same, and then change the processorArchitecture= »x86″ by processorArchitecture= »Amd64″ that’s all !
This little difference makes the application crash on x64 build if you use the x86 manifest…
You can found the list of available processorArchitecture here.

Building the application

Now lets go back to some configuration : if you start to build it like this, it will fail. Let’s configure build options so !

Right click on your project name -> Properties (at bottom), in the new panel, go into C/C++ Build and select Settings

Configure Build options

On the first tab (Tool Settings – the current one) :

  • On the MinGW C++ Linker, select Miscellaneous. On Top (Linker flags text), add -mwindows. This will say to gcc to use windows build options (for comctl…).
  • On miscellaneous too (same one). On other objets add (using « + » button) « Debug/res/resource.o ». This will link resource with program link.
  • In library (just above Miscellaneous, same category). Click on « + » button and add comctl32.

Thoose are used to help MinGW to search what it need…

building options Eclipse Linker

building options Eclipse Linker second

On the second tab (Build Steps) :

  • On Pre-builds steps -> command put : windres -D WX_CPU_AMD64 -i ../resource/resource.rc -o ../Debug/res/resource.o
  • On Post-build steps -> command put (change the program name) : strip –strip-all ../Debug/MyProgramName.exe

Thoose help resource to be taken in consideration, and also the strip allow to cut the program size…

building pre post configuration Eclipse

Now you can build (right click on project name -> build) and check everything works fine. Don’t forget to copy thooses lasts steps for « Release » also, to not be surprise when switching from « Debug » to « Release »… You will get this (take care of the button look & feel) :

Final words

Final words

MinGW64 is a great platform for building C++ under x64 or x86. Here we show a basic start for beeing able to do both with same code, just by using different manifest file regarding the compile options. You can go deeper by looking how to use and build QT or wxWidgets, they will help you threw the process of making realiable multi-platform C++ programs.

Publicités

14 Commentaires

  1. Boneve

    I have set up all paths in Eclipse Luna, but MinGW GCC didn’t show up. So I chose « Cross GCC » and ponted the path to TDM_PATH/bin. To use the 64 bit compiler, I had to manually set them in Project -> Properties -> Settings, using the ones with prefix x86_64-w64-mingw32-. It seems to be working 😀

  2. Martin

    Great tutorial for getting things running… I’m trying to set up Eclipse Kepler with mingw-64 for some hours, and this brought me a big step closer to my final goal. Everything works as it should. Do you have some tipps or links to other pages where I can read about setting up wxWidgets for the provided environment. Thanks very much!

    • deisss

      Actually I failed myself to setup wxWidget so I switch to QT instead…

      • Martin

        Sounds interesting, did you compile Qt from sources by yourself using the same 64 Bit compiler or did you find some binaries? Which Qt version did you take and did you use mysys and configure or make? I’m really interested in your solution, I spent too much time with annoying tries of compiling wxWidget and linking it into my projects. So, any help for setting up a platform independant GUI framework is appreciated… Thank you.

      • deisss

        Actually I use a prebuild QT x64 like this one:

        http://qtx64.sourceforge.net/

        But I cannot help you that much that’s really long time I did that, I’m not sure to find any more helps… (I don’t even know if I still have original project 😦 )

  3. Martin

    No worries, thanks very much anyways.

  4. TQQ

    16:01:35 **** Incremental Build of configuration Release for project hello ****
    Info: Internal Builder is used for build
    windres -D WX_CPU_AMD64 -i ../resource/resource.rc -o ../Debug/res/resource.o
    g++ -mwindows -Xlinker Debug/res/resource.o -o hello.exe « src\\main.o » -lcomctl32
    c:/tdm-gcc-64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find Debug/res/resource.o: No such file or directory
    collect2.exe: error: ld returned 1 exit status

    16:01:35 Build Finished (took 254ms)

    • TQQ

      Just in case anyone run in same problem, I replaced
      Debug/res/resource.o
      with
      « ${workspace_loc:/${ProjName}/Debug/res/resource.o} »
      and it found the file!

      • TQQ’s solution, above, didn’t quite work for me but was near.
        The string that did work:
        Enter the following in Settings / MinGW C++ Linker / Miscellaneous, the box « Other options », as a replacement for the old entry Debug/res/resource.o:

        « ${workspace_loc:/${ProjName}}/Debug/res/resource.o »

        INCLUDE THE QUOTES when entering the string.

  5. TQQ

    Ah, yeah, first it was this:

    16:18:48 **** Incremental Build of configuration Release for project hello ****
    Info: Internal Builder is used for build
    windres -D WX_CPU_AMD64 -i ../resource/resource.rc -o ../Debug/res/resource.o
    windres: ../Debug/res/resource.o: No such file or directory

    16:18:48 Build Finished (took 80ms)

    But then I manually created Debug/res folder, and it then stopped on error above, which Im unable to solve since I dont understand the message. Yes, technically I know that it cant find the specified file, but I cant understand what is looking for that file, and where do I specifiy where to look for that file…

    • deisss

      He is looking for that folder because it’s simply where it will find the resources files to activate windows new looking ! Simple !

      • TQQ

        Yeah but that file Debug/res/resource.o physically exists (if I delete it, windres creates it again), and yet linker cannot find it. Thats why I cannot understand the problem 😦

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :