Cross compile root on Linux for windows

Dear root community,

I am trying to compile a program, which I have written and used on Linux, into a windows executable. It is meant to be used on a lab PC which runs windows for quick data analysis. My approach until now was using mingw and the helloworld example without root works perfectly, I can simply copy the resulting .exe to windows and click on it:

/*
 *  * Hello, World for Win64
 *   * compile with x86_64-w64-mingw32-g++  winhello.c -o winhello.exe
 *    */
#include <windows.h>
int main(int argc, char *argv[])
{
	MessageBox(NULL, "Hello, world!", "Hello, world!", MB_OK);
	return 0;
}

When I try to include root libraries however (in this case just TRandom.h and a simple double rndm=gRandom->Rndm()), it becomes tricky for me, since I have to include libraries:

x86_64-w64-mingw32-g++  winhello.c -o winhello.exe
winhello.c:6:21: fatal error: TRandom.h: No such file or directory
 #include "TRandom.h"
                     ^
compilation terminated.

I tried to include the root-config --libs, but this results in

x86_64-w64-mingw32-g++ -L/cvmfs/clicdp.cern.ch/software/ROOT/6.06.04/x86_64-slc6-gcc48-dbg/lib -lCore -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lMultiProc -pthread -lm -ldl -rdynamic winhello.c -o winhello.exe
x86_64-w64-mingw32-g++: error: unrecognized command line option '-rdynamic'

What can I do to make that work?

Cheers and thanks in advance,
Andreas

Some technical info:
I use root6 on a standard CERN PC with SL6

Hi,

It will most probably not work (just try with any other Linux libraries), or I would be very surprised!
And BTW, why don’t you compile your code directly on Windows?

Cheers, Bertrand.

Hi Bertrand,

thanks for your reply. I thought if there is an easy way within my Linux setup I would prefer not having to install root on my windows machine. But I am open for recommendations of course! So what would be the general way of achieving this? Which software on windows do you recommend and do I have to change my code for that (it’s just c++ and root)?

Cheers,
Andreas

Hi Andreas,

If you don’t want to install ROOT on Windows, use a virtual machine. It’s the only alternative I can think of…

Cheers, Bertrand.

Hi Bertrand,

I probably did not express myself clearly. If you recommend to install it on windows, I will do so! I am just interested in your recommendations, which software to use for compilation, how to do the linking etc., such that I don’t end up in a dead end. I am not that experienced in compiling under windows, so any advice would be very much appreciated!

Cheers,
Andreas

Hi Andreas,

Oh, OK, sorry for the misunderstanding…
So you can download a pre-built binary distribution of ROOT 5.34.36 on Windows (Visual Studio 2013), or compile it yourself from source (see those instructions). Don’t forget to take ROOT 5, ROOT 6 doesn’t work yet on Windows. Then you need the free version of Visual Studio Express 2013, Don’t take newer versions, it will not work.

Cheers, Bertrand.

Thank you! :smiley:

I’ve also been asked by someone if ROOT can be built with MinGW (or maybe MinGW-w64, I don’t remember now). They have their own C / python / matlab “client” libraries for Linux / MacOS X and Windows (Windows “client” libraries are built with MinGW or MinGW-w64) and could potentially be interested in using ROOT.

Hi again,
I did as you suggest and I have managed to successfully build a small testproject including root. When I execute it, however, it says “The program can’t start because libCore.dll is missing from your computer. Try reinstalling the program to fix this problem”. It says the same about libGpad.dll. Do you have a suggestion what to do? The google results don’t help me much!
Cheers,
Andreas

Hi Andreas,

you should call the thisroot.bat script (located in wherever_you_installed_root/bin directory) before starting your app, or manually set the ROOTSYS environment variable (pointing to wherever_you_installed_root) and add %ROOTSYS%\bin to your PATH

Cheers, Bertrand.

Hi Bertrand,

I have done so and at first I ran into an error, because I had added the %ROOTSYS% to the system Path variable instead of the user path variable. As soon as I corrected that, everything works just fine :slight_smile: . I have one follow-up question though: Canvasses do not show up (but that’s fine, I can live with just a print) but TCanvas::Print() also does not work. It says:

Error in TApplication::ExecuteFile: C:\Program Files no such file

I start my program from within Visual Studio (Local Windows Debugger) but clicking on it works as well.

Do you have a similarly quick and efficient answer to that?

Hi Andreas,

Don’t install root in a location with white spaces in the path (i.e. no C:\Program Files\root)
See the Important installation notes on the bottom of this page

Cheers, Bertrand.

Great, thanks a lot! Now I can start developing!

Have a nice day, Andreas

Hello Bertrand,

I have been importing now my program which consists of some files (I give generic names here) into a new project. The compilation works, but the linking does not. I have tried to linkit and I get over 140 times errors like this:

Regarding this error, IsInArray is a cpp function in the file CppUtils.C, which is included in HexPlot.C.There are also two other errors in the end:

Error 168 error LNK2019: unresolved external symbol _wWinMain@16 referenced in function ___tmainCRTStartup C:\Users\Andreas Maier\Documents\Visual Studio 2013\Projects\HexPlot\HexPlot\LIBCMTD.lib(wwincrt0.obj) Error 169 error LNK1120: 1 unresolved externals C:\Users\Andreas Maier\Documents\Visual Studio 2013\Projects\HexPlot\HexPlot\Debug\HexPlot.exe
I have searched the internet for solutions and they say it’s a matter of order in which windows MFC and my own libraries are linked. I tried adding things like "//#include “stdafx.h” to all my files or played with the precompiler options, but I don’t succeed. Do you know what might be wrong?

Cheers,
Andreas

Hi Andreas,

As the errors say, you have the same symbols defined multiple times (in different object files). And BTW, do you really need a MFC based application inside a Visual Studio solution? Couldn’t you simply build from the command prompt? (like on Linux)

So in this case, make sure to remove CppUtils.C from the list of source files in the solution. If a source file (first.cxx) is included by another one (second.cxx), remove first.cxx from the list of source in the solution (this is the source of the problem…)

Cheers, Bertrand.

Hi Bertrand,
thanks for the hint! I had just included everything, because I didn’t expect it to find the includes otherwise! I also had to set the linker sub system to console instead of windows. Now it compiles and links correctly.

The program now gets stuck unfortunately, even though when compiling in Linux with g++, everything works and I get no error neither in comipling, linking or execution, not even a single warning. The execution with the option “-h”, which just prints out input parameters, works fine. But if I want to do real analysis, it gets stuck. I have added some printouts and found, that it gets stuck when calling a certain function. With print statements I saw, that in the example code snippets I pasted below, the line marked with “THIS IS THE LINE” produces the problem. When it is in, not even test1 is printed. When it is commented out, everything works.

Global:

const int MAXCELLS=5000;
const int MAXVOLTAGES=200;

in my main:

TH1F *h_fill=0;
printf("test");
h_fill = (TH1F*)LoadValues(inputfile, inputformat, mapfile, yscale, verbose, selector);
printf("test3");

with

TObject* LoadValues(string inputfile,string inputformat,string mapfile,double yscale,int verbose,double selector,int singlechan=-1){
	printf("test1 \n");
	double valarr[MAXCELLS][MAXVOLTAGES]; //THIS IS THE LINE
	printf("test2 \n");
	return 0;	
}

Do you have a clue what could go wrong here?

Cheers,
Andreas

Hi Andreas,

This is weird… Could you try to allocate the arrays (or matrix) on the heap instead of on the stack (which is limited)?

Cheers, Bertrand.