Compiling aginst ROOT in C++ on Windows

This is only interesting for people that are writing their own C++ code and linking against ROOT. The packages discussed below aim to make the process of configuration compiler options, etc., for Windows and Visual Studio 2012, 2013, and (I believe) 2015 a “one-click process”. And they do their best to catch some common errors.

I didn’t realize that the distribution for ROOT had changed (the team moved to ZIP files from tar.gz for the Windows platform), and it broke some of my code. I’ve fixed it, and took the opportunity to add some new features.

[li] There are now ROOT and ROOT-Local nuget packages. ROOT-Local will build against whatever is already on your computer, ROOT will download and build against a specific version of ROOT (during the build).[/li]
[li] You can now use VS2012 and VS2013. Sadly, the new VS2015 can’t be used as there isn’t an official version of ROOT built against it yet. However, you can use the VS2015 IDE and install the 2013 compilers (all free).[/li][/ul]

Information, etc., can be found on the project in GitHub that builds the nuget packages:

Suggestions are welcome, as, (even more so) are pull requests. Questions too, and I will do my best to answer.

For those of you just stopping by and curious: nuget is a “package manager” - it is a way to automatically install libraries and header files, etc., into a build… sort of like distributing make file fragments and .a’s or .so’s on Linux. I think the Windows open source community stole the idea from the Ruby gem package manager. I think that based on the Linux rpm package manager, but made so that a single developer could use it.

Our windows expert is on holidays. He will look at it when back.

(to avoid possible misconceptions, I’m not the Windows expert couet refers to)
This looks interesting. While I’m not exactly in the target audience due to mostly using custom CMake-created ROOT builds on Windows, I checked whether this could offer some improvements to ROOT linking convenience. Looks promising but one of the biggest annoyances seems to remain: the hassle with debug/release libraries. There’s little to be done given the use of prebuild ROOT libs, but nevertheless many users may find it repulsive that the library will essentially dictate that using proper debug configuration, or in some cases even using debug config at all, is more or less impossible if linking with ROOT in this way.

Thanks! This is a good point. Currently, if the user selects a debug build, they will get an error with this package that helpfully (I hope) tries to point out what the issue is.

For those that aren’t aware, the stdlib is not binary compatible in debug and release builds for C++ (MS includes a number of debugging features in their debug build which, while helpful for catching memory overrun errors, etc., change the size and layout of some of the standard library objects).

ROOT provides debug builds, right? I could modify the package so that it pulled that library down during the build. However, if my memory is correct, this wouldn’t actually help. The debug build is built with the STL debugging features turned off. As a result, it is incompatible with every other debug build in the universe. I believe the ROOT team does this for a good reason: they depend on a number of libraries for which only release builds are available.

It is possible to turn off the debug features automatically in the user’s build. This is a matter of just defining a few macros. Pretty trivial operation as this package hooks into the build process. However, as soon as the user builds against another debug library for which that hasn’t been done… And I think the failure is silent (though I’ve not checked that is still the case; last tests I did were done for the 2010 toolset).


Sounds good for the user.

My conception is also that using the debug build won’t work, but I was mostly concerned about wrong runtime, but it indeed seems to have more than that. In CMake-build there’s flag “winrtdebug”, which defines whether the debug runtime is used (this implies definition of _DEBUG). I think I’ve tested setting the MDd-flag (linking with the debug runtime) for debug-config even without winrtdebug-flag only to find that some libraries, especially those in the “Builtins”-category, were not affected and I was earning some non-everyday debugging experience with mixed runtime libs :slight_smile: I don’t know how big a task it would be to fix those, but so far I’ve simply created separate cmake-projects for debug and release, and been able to use ROOT as proper debug lib in ordinary debug build. But that’s a sidetrack: the problem in the original matter is that some users apparently need the use of release runtime even in debug version and some would prefer debug runtime; with only one binary build there’s no way to satisfy both.

It is funny - debug builds and release builds are compatible as long as the API remains unchanged. This is the “rule” that the STL libraries violate.

So, for example, the debug build for ROOT is really a release build, but with full debug information. That does mean optimization is on, so stepping through the code is (obviously) flawed. But it is possible, and once you have your code working for a release build, you can drop in the debug build and it will continue to work and be debuggable.

In short: optimize/not optimize doesn’t affect linking against current ROOT libraries. Nor does generating a debug database. What does break things is the STL’s debug settings which change the binary API.

In VC++, the default Debug config can be used against ROOT when you define one or two #define’s (I don’t remember exactly what they are, but they are on the net), and you specify you are linking against the release runtime library.

I didn’t take this route in the ROOT package here simply because I was worried I was changing too much about a user’s config without them knowing (e.g. loss of transparency). This would be problematic if the user linked in another package that didn’t depend on ROOT - they would suddenly get some very weird link-time errors and it wouldn’t be at all obvious what was going on. I am not sure - perhaps this was not the right design choice?

The ROOT package, BTW, doesn’t look to see if your config is “Debug” or “Release” - it looks at the runtime library you are building against. I took that path because it seems more robust (and you can generate an infinite number of build configurations with all sorts of different and weird names). But that does mean that you could modify your Debug config and the ROOT package would be happy as a clam.

Based on a quick look at least in the Debug-config created by CMake optimization is disabled (/Od).

I think one can get into trouble even if not encountering STL’s debug settings: it can produce funny results if managing to use C-api with both release-crt and debug-crt. For example the mixed runtime debugging experience mentioned in my earlier post seemed to be caused by libafterimage first calling open() using release-crt and later read() with debug-crt.

Whether right or not-so-right, having only “pseudo-debug” build to use there’s no way to make it work for everyone, and without actually having used the ROOT package, your principles - not secretly fiddling with config, avoiding linker errors and using runtime library detail instead of config name - sound reasonable choices.