Include ROOT 6.22 in Visual Studio 2019

Dear ROOTers,


(brief, skippable introduction)

I’m currently trying to combine Visual Studio (C++ CLR Empty Project (.NET Framework)) and ROOT: I need to create an analysis tool with some customizable GUI and I would like to compile it and to generate a .exe file.

It is my first time using VS, so I manage to build my first GUI, which can run with VS debugger and then I try to add as header #include <TROOT.h> and I get several errors of the following type:

  • error LNK2028: unresolved token
  • error LNK2001: unresolved external symbol
  • error LNK2019: unresolved external symbol

Long story short, in the end I tried to generate a really basic code, just to figure out if I am able to include a generic ROOT header

#include <iostream>
#include <TROOT.h>

using namespace std;

int main() {
	std::cout << "Bears. Beets. Battlestar Galactica." << std::endl;
	return 0;
}

As soon as I add the line “#include <TROOT.h>” I’m getting the following outputs:

1>------ Build started: Project: TryToLoadROOT, Configuration: Debug Win32 ------
1>Source.cpp
1>C:\root_v6.22.02\include\ROOT\RWrap_libcpp_string_view.h(428,31): error C2039: ‘__find_end’: is not a member of ‘std’
1>C:\root_v6.22.02\include\ROOT\RWrap_libcpp_string_view.h(125): message : see declaration of ‘std’
1>Done building project “TryToLoadROOT.vcxproj” – FAILED.

I tried to google a bit and I found this thread. I tried to apply what’s suggested there and I get other errors:

1>------ Build started: Project: TryToLoadROOT, Configuration: Debug Win32 ------
1>Source.cpp
1>Source.obj : error LNK2019: unresolved external symbol “public: __thiscall TVersionCheck::TVersionCheck(int)” (??0TVersionCheck@@QAE@H@Z) referenced in function “void __cdecl ROOT::Internal::`dynamic initializer for ‘gVersionCheck’'(void)” (??__EgVersionCheck@Internal@ROOT@@YAXXZ)
1>C:\Users\manaigof\source\repos\TryToLoadROOT\Debug\TryToLoadROOT.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project “TryToLoadROOT.vcxproj” – FAILED.

I also made sure that “C:\root_v6.22.02\include” is properly included in the “Additional Include Directories” of the project and that, on cmd.exe “echo %path%” gives me "C:\root_v6.22.02\bin" as one of the arguments.
This unfortunately was not enough, so I restored “RWrap_libcpp_string_view.h” as it was originally and here I am asking if anyone could, please, help me out.

Thank you so much for any feedback!
Filippo


Please read tips for efficient and successful posting and posting code

ROOT Version: v6.22.02
Platform: Windows 10
Compiler: Microsoft Visual Studio Community 2019 (Version 16.7.4)


Hi,

Welcome to the ROOT Forum!

If it’s the first time you are using Visual Studio, you’re going to have some troubles, especially if you want to try mixing MFC code and ROOT. You should make sure to use the same compilation flags than ROOT itself, at least those ones: -Zc:__cplusplus -MD -GR. I could also suggest to use CMake to generate a small project…

Cheers, Bertrand.

Hi and thank you so much for your reply!

As you suggested I tried to add the flags you wrote on project → properties → C/C++ → Command Line → Additional Options (correct?). The result was pretty much the same as the first one I posted plus a warning

1>------ Build started: Project: TryToLoadROOT, Configuration: Debug Win32 ------
1>cl : command line warning D9025: overriding ‘/MDd’ with ‘/MD’
1>Source.cpp
1>C:\root_v6.22.02\include\ROOT\RWrap_libcpp_string_view.h(428,34): error C2039: ‘__find_end’: is not a member of ‘std’
1>C:\root_v6.22.02\include\ROOT\RWrap_libcpp_string_view.h(125): message : see declaration of ‘std’
1>Done building project “TryToLoadROOT.vcxproj” – FAILED.

I kept looking on the internet and I saw that on g++ compiler the options

root-config --cflags --libs

are usually added.
So I tried something similar, adding

"C:\root_v6.22.02\bin\root-config"

as “additional option”. The output says of course that I’m missing “preprocessor directives”.
Would this be a viable thing to try? If so, which options should I add and how?

In the meanwhile I’ll look into CMake.

No, you have to change the options corresponding to those flags: see how for /MD, for /GR, and for /Zc:__cplusplus . I also forgot the c++ standard /std:c++14

No, don’t, it cannot work. This is a shell script for Linux and MacOS.

Unfortunately, no luck in changing the flags you mentioned. I still get the same output errors.
Do you know where I can find a list of what computation flags ROOT uses? If it makes sense I can try and modify more of them like I just did for for /MD, /GR, /ZC:_cplusplus and /std:c++14

If not, any idea on what else can I try?

You can check in C:\root_v6.22.02\cmake\ROOTConfig.cmake. But BTW, did you link your project with (at least) C:\root_v6.22.02\lib\libCore.lib ?

Saw them, thank you. Tomorrow I’ll have more time I’ll try to add some of them on my VS project properties

I did not, now I fixed that (linker → general → additional library directories) but I still get the same error.
Should I add other libraries?

That’s not enough. You should add C:\root_v6.22.02\lib\ in linker -> general -> additional library directories, but you must also add the libraries you want/need to link with. You can add them all, the linker will pick the ones really needed.

Ok, for now I added “libCore.lib” in linker → Input → additional dependencies. Still the same error for now:

1>------ Build started: Project: TryToLoadROOT, Configuration: Debug Win32 ------
1>Source.cpp
1>C:\root_v6.22.02\include\ROOT\RWrap_libcpp_string_view.h(428,34): error C2039: ‘__find_end’: is not a member of ‘std’
1>C:\root_v6.22.02\include\ROOT\RWrap_libcpp_string_view.h(125): message : see declaration of ‘std’
1>Done building project “TryToLoadROOT.vcxproj” – FAILED.

Tomorrow I’ll try and add all ROOT libraries there and I’ll let you know. Thank you so much for all the tips you gave me so far :grin:

Here I am again, I tried to add all the library files and check for more flags. Unfirtunately it did not work, The output of my really basic program has not changed.
Do you know if there’s something else I could try?

If it can be helpful, I took some screenshots of the options of my project:

C/C++ Options


Linker Options

The complete argument of “Additional Dependencies” is:

kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);libASImage.lib;libASImageGui.lib;libCling.lib;libcomplexDict.lib;libCore.lib;libdequeDict.lib;libEG.lib;libEve.lib;libFFTW.lib;libFitPanel.lib;libFITSIO.lib;libFoam.lib;libforward_listDict.lib;libFTGL.lib;libFumili.lib;libGdml.lib;libGed.lib;libGenetic.lib;libGenVector.lib;libGeom.lib;libGeomBuilder.lib;libGeomPainter.lib;libGLEW.lib;libGpad.lib;libGraf.lib;libGraf3d.lib;libGui.lib;libGuiBld.lib;libGuiHtml.lib;libGviz3d.lib;libHist.lib;libHistPainter.lib;libHtml.lib;libImt.lib;libJupyROOT.lib;liblistDict.lib;libmap2Dict.lib;libmapDict.lib;libMathCore.lib;libMatrix.lib;libMinuit.lib;libMinuit2.lib;libMLP.lib;libmultimap2Dict.lib;libmultimapDict.lib;libmultisetDict.lib;libNet.lib;libPhysics.lib;libPostscript.lib;libProof.lib;libProofDraw.lib;libProofPlayer.lib;libPyROOT.lib;libQuadp.lib;libRCsg.lib;libRecorder.lib;libRGL.lib;libRHTTP.lib;libRHTTPSniff.lib;libRint.lib;libRIO.lib;libRooFit.lib;libRooFitCore.lib;libRooStats.lib;libRootAuth.lib;libROOTDataFrame.lib;libROOTVecOps.lib;libRSQLite.lib;libSessionViewer.lib;libsetDict.lib;libSmatrix.lib;libSpectrum.lib;libSpectrumPainter.lib;libSPlot.lib;libSQLIO.lib;libThread.lib;libTMVA.lib;libTMVAGui.lib;libTree.lib;libTreePlayer.lib;libTreeViewer.lib;libunordered_mapDict.lib;libunordered_multimapDict.lib;libunordered_multisetDict.lib;libunordered_setDict.lib;libUnuran.lib;libvectorDict.lib;libVMC.lib;libWin32gdk.lib;libXMLIO.lib;tbb.lib;tbbmalloc.lib;tbbmalloc_proxy.lib



Please, let me know if additional information could be useful.

Can you try a very simple test?
Open a x86 Native Tools Command Prompt for VS 2019, go (cd) to the directory containing the Source.cpp file, type C:\root_v6.22.02\bin\thisroot.bat and then cl -nologo -O2 -MD -GR -EHsc Source.cpp -I %ROOTSYS%\include /link -LIBPATH:%ROOTSYS%\lib libCore.lib
Then post the result here

Sure, here’s to you:

C:\Users\manaigof\source\repos\TryToLoadROOT>C:\root_v6.22.02\bin\thisroot.bat
C:\Users\manaigof\source\repos\TryToLoadROOT>cl -nologo -O2 -MD -GR -EHsc Source.cpp -I %ROOTSYS%\include /link -LIBPATH:%ROOTSYS%\lib libCore.lib
Source.cpp

So now you have a Source.exe in that directory, right?

Yes, I do

So that shows that you can perfectly compile your source with ROOT headers without any error. Then the errors you see are coming from a misconfiguration in your project… Not sure how to solve that, I always use either the command line (like we just did), or CMake to properly generate a working solution for Visual Studio…

I guess that’s a good start. Thank you! :grin:

So, your advise would now be not to use the virtual studio Local Windows Debugger to test the code or generate the .exe (at least until I figure out what’s the configuration problem) and to use either command line or CMake instead?

As you prefer, but you have to learn Visual Studio in order to understand the different flags and find the one causing the issue. And CMake generates a proper solution (.sln) file for Visual Studio. Note also you can perfectly debug your code with Visual Studio without creating a complete solution…

Would that still give me a preview of my code with a GUI?

You can debug your code within the Visual Studio IDE, if it’s what you mean…

But note you need the Debug Version of ROOT and you also need to build your code in Debug mode