Installation Problem, JSON requirements | Windows

I’ve not encountered this issue myself (yet), which unfortunately makes diagnosis difficult. But getting a subsequent runtime error at the Qt step also makes me suspicious of the compiler. Are you able to try with g++ version 5 or 6? (Set the CXX environment variable when running the configure script to force it to use a particular compiler)

Another thing you can try for the sake of it is locally replacing the contents of file core/file/json.h with the most up-to-date version of that library. It’s possible that fixes to the JSON for Modern C++ code have been required to prevent issues with more recent compilers; but the fact that you get a similar runtime issue with Qt suggests that this is not the underlying issue.

Ok a few more things I tried:

  • Downgrading to mingw-w64-x86_64-gcc-5.1.0-1 (including gcc-libs) -> same result, json runtime error, if I omit the test, runtime error in qt application. Downgrading to 6.1.0-1 was somehow not possible due to dependencies of other libraries UPDATE: I managed to install mingw gcc 6.3.0, but I also get the json runtime error and if I skip that test, I run into the qt runtime error

  • swapping json.h -> json test also fails (even if I rename json.h and keep json.hpp without renaming to json.h, same behaviour)

  • Uninstalling msys2 64bit completely and reinstalling the current version, following all the instructions in the installation guide -> same result

  • Another fresh installation of msys2 64bit, reinstalling only mingw-gcc-5.1.0.1 with libs and mingw-w64-x86_64-eigen3 -> JSON runtime error

  • trying g++ (currently 5.1.0) in the same installation -> json error

  • if I try /usr/bin/gcc or g++ (5.3.0) the config fails at C++11 compliance

  • uninstalling all gcc-libs and gcc versions, trying to install gcc instead of mingw-gcc => installs gcc 6.4.0 and ./configure stops at zlib step. Installing mingw-w64-x86_64-zlib fixes that issue, now even the json-test passes for the first time (with g++ (6.4.0), gcc (6.4.0) fails at detecting pointer size) but qt stuff is missing

  • install mingw_w64-x86_64-qt5 and -> ./configure throws an error linking Qt application (/usr/lib/gcc/x86_64-pc-msys/6.4.0/../../../../x86_64-pc-msys/bin/ld: cannot find -lmingw32 collect2: error: ld returned 1 exit status)

  • ./configure -nogui runs through, however, if I try to build, I get lots of errors:

    ERROR: ( 9/366) [CC] tmp/core/file/ofstream.o
    ERROR: ( 5/366) [CC] tmp/core/formats/nifti1_gz.o
    ERROR: ( 8/366) [CC] tmp/core/formats/nifti2.o
    ERROR: ( 12/366) [CC] tmp/core/image_io/sparse.o
    ERROR: ( 19/366) [CC] tmp/core/formats/mri.o
    ERROR: ( 3/366) [CC] tmp/src/dwi/tractography/seeding/list.o
    ERROR: ( 2/366) [CC] tmp/cmd/5tt2gmwmi.o
    ERROR: ( 1/366) [CC] tmp/src/dwi/tractography/roi.o
    ERROR: ( 21/366) [CC] tmp/core/formats/mrtrix_sparse_legacy.o

    ERROR: ( 9/366) [CC] tmp/core/file/ofstream.o`

    /usr/bin/g++ -c -std=c++11 -pthread -DMRTRIX_WINDOWS -mms-bitfields -Wa,-mbig-obj - D_FILE_OFFSET_BITS=64 -DMRTRIX_WORD64 -isystem /mingw64/include -DMRTRIX_TIFF_SUPPORT -isystem /mingw64/include -DEIGEN_FFTW_DEFAULT -isystem /mingw64/include -Wall -O3 -DNDEBUG -Isrc -I./core -Icmd -isystem /mingw64/include/eigen3 -DEIGEN_DONT_PARALLELIZE core/file/ofstream.cpp -o tmp/core/file/ofstream.o

    failed with output

    In file included from core/file/ofstream.cpp:17:0:
    ./core/file/utils.h: In function ‘void MR::File::mkdir(const string&)’:
    ./core/file/utils.h:200:13: error: too few arguments to function ‘int mkdir(const char*, mode_t)’
    ))
    ^
    In file included from ./core/file/utils.h:20:0,
    from core/file/ofstream.cpp:17:
    /usr/include/sys/stat.h:150:5: note: declared here
    int mkdir (const char *_path, mode_t __mode );
    ^~~~~

Not sure what else I could try…

Well I just upgraded my own Windows installation, which included MSYS2 base upgrades, and GCC 7.3.0 However I was able to configure and build just fine. My concern was that a MSYS2 update had broken things, in which case I’d need to get the word out as quickly as possible for people to avoid updating MSYS2.

Can you confirm that you have definitely used the correct version of the MSYS2 shell, as described in the documentation? It’s maybe conceivable that using the wrong shell could lead to issues like this. Also did you definitely close the current shell & all other shells after having performed MSYS2 updates via pacman, as pacman instructs when doing such updates?

One other thing that could be indicative of an issue is the specific line at which your attempted compilation fails:

./core/file/utils.h:200:13: error: too few arguments to function ‘int mkdir(const char*, mode_t)’
...
/usr/include/sys/stat.h:150:5: note: declared here
int mkdir (const char *_path, mode_t __mode );

The surrounding MRtrix3 code is:

if (::mkdir (folder.c_str()
#ifndef MRTRIX_WINDOWS
            , 0777
#endif
))

So the “mkdir()” function is called with 1 argument on Windows, 2 on other OS’s; but it looks as though your included libraries define this function with two arguments. Maybe that might give a hint as to what else you could look into. Have you installed any MSYS2 packages related to POSIX compliance or such? Also, which version of Windows are you on? (I’ve observed using the same MSYS2 installer on Windows 7 and 8.1 machines and getting different resulting installations)

I’m surprised that you were not able to reproduce this issue. The errors occur on a Windows 7 machine. I’m pretty sure I used the correct shell and followed all the steps including updating pacman, closing the shell in between and so on, I also did it a few times already.
I’ll try to reproduce it on another Windows machine (also Win7 I think) in the coming days and keep you updated…

If I list all the installed packages, I can find libpcreposix 8.40-2 which depends on pcre. If I remove it with all dependencies (pactoys-git, pkgfile, pcre and finally libpcreposix), I still get the json error if I try ./configure

Yeah, if you need to remove pkgfile that’s probably something that’s not out of the ordinary to have installed.

One other thing you can try (just got this more-or-less working myself for other nefarious purposes):

pacman -S mingw-w64-x86_64-clang
CXX=clang++ CFLAGS="-Wno-incompatible-ms-struct" ./configure

You’ll still get some compiler warnings if you do manage to build, but this will at least tell us whether it’s something specific to g++ or whether it’s something in the MSYS2 runtimes that’s giving you grief.

I’ll also try a fresh MSYS2 install on my Windows 7 machine when I can.

using clang, I still get the json error, if I skip that check, I’ll end up at a qt compilation error (clang++.exe: error: unknown argument: '-fno-keep-inline-dllexport') but if I run configure with the -nogui option, the build runs through (with some warnings, as you mentioned)
Another strange phenomenon I noticed after the compilation, If I try to run one of the compiled binaries (e.g. mrinfo), I get a blank output from the shell. If I run it from outside the shell (e.g. windows cmd), I get an error entry point XXX could not be located in the dynamic link library libstdc++-6.dll but this might be caused by the path-envorinment. Inside the mingw-shell I get /mingw64/bin/libstdc++-6.dll as path to the library which seems normal to me I guess.

I’m impressed with your tenacity with this! :fist:

I have to admit that I have no idea what’s going on with your install. But also that when issues occur on Windows, it’s often a fair bit more difficult to get to the bottom of it, given that many parts of Windows are fairly opaque – this is one of the main advantages of open-source systems… But that’s a different discussion.

I have my own issue on my install, which I haven’t seen anywhere else – but at least they’re not related to the build stage. One thing that hasn’t come up yet is the possibility that this might be due to interference from an anti-virus program. Do you have one installed? What happens if you disable it…? You’d probably need to remove MSYS2 and re-install with all anti-virus programs disabled to really get to the bottom of this…

Well I just wanted to “quickly” update an old mrtrix installation of one of the windows machines to the current version, but sometimes things just take much more time than expected…

I do have McAfee running but I now disabled all of its services, uninstalled msys2 and re-installed. A clean msys2 installation already contains the libpcreposix library by the way, I just checked (even prior to pacman -Syuu).

Unfortunately it did not help, same behaviour, json-error, if I skip, Qt runtime error.

But it was worth a try…

Total mystery…

Can I just check whether you’ve tried rebooting the system…? Seems obvious, I know, but just in case a Windows update got installed recently that may require a reboot to finalise or something…?

Otherwise I’m not sure I’ve got anything further to contribute…

Actually, one thing you could try is posting the whole of your configure.log here for us to have a look through. There may be clues in previous tests that may shed some light into what’s going on – long shot though.

I restarted the computer at least two times during all of the testing, but I’ll try to test / reproduce the errors on another win7 machine tomorrow, maybe that helps spotting the error… I’ll keep you updated!

It worked just fine on another win7 pc, so I’ll try to find a difference between the two computers. The installation was performed the same way, but without any bugs on the second pc. I’ll try to find the difference between the two machines, at least hardware and software should be pretty similar. The configure.log files look the same except the temp-filenames and that on the working PC, non-POD variable-length check is OK and on the other machine it is “not found” with EXIT: 127.
I figured that if I copy the libstdc++-6.dll from the msys64\mingw64\bin folder, the non-POD test and the json-test works fine. However, if I run which libstdc++-6.dll I get msys64\mingw64\bin as if during the linking, the correct dll is chosen but for the running, a wrong dll is picked. The same happens even if I add msys64\mingw64\bin to my path, it does not seem to matter.
At least I got rid of the JSON problem by copying the dll to the mrtrix3 folder. The next error is during Qt application test. I suspect it is also due to some dll Problem, I’ll try to find the relevant one as well. Finally making some progress…
Qt also fails because of libstdc++-6.dll, the fix did not work because the qt application is started from a separate folder in the tmp directory during the check and not from the mrtrix3-folder itself.
I found a copy (but probably slightly different version / compilation) of libstdc++-6.dll in one of my %SystemRoot% folders and that dll-file got prioritized over the one in the mingw64 independent of what was written in the path environment variable.
Renaiming that dll helped and now configure & build worked like a charm (I hope I did not break any other software with this hack)!
If somebody runs into a similar (dll-related) problem on windows, running the compiled test-routines in the native windows-shell sometimes opens a popup error message with some information regarding the corrupt/missing dll in comparison to the mingw64 shell.
Thanks everybody for the support, problem solved!

1 Like

Great detective work! So it looks like there’s a conflict in the linker search path, so that the runtime linker resolves the wrong version of the libstdc++-6.dll at application start-up. If you’ve managed to build any of the executables, try running ldd bin/mrinfo from the MRtrix3 folder. Mine looks like this:

$ ldd bin/mrconvert.exe
        ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffb47c60000)
        KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffb47a30000)
        KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffb44c90000)
        msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ffb45620000)
        libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x64940000)
        libgcc_s_seh-1.dll => /mingw64/bin/libgcc_s_seh-1.dll (0x61440000)
        mrtrix-3.0_RC2.dll => /home/donald/mrtrix3/bin/mrtrix-3.0_RC2.dll (0x65680000)
        zlib1.dll => /mingw64/bin/zlib1.dll (0x62e80000)
        libstdc++-6.dll => /mingw64/bin/libstdc++-6.dll (0x6fc40000)
        ??? => ??? (0x2de0000)
        USER32.dll => /c/WINDOWS/System32/USER32.dll (0x7ffb46450000)
        win32u.dll => /c/WINDOWS/System32/win32u.dll (0x7ffb44480000)
        GDI32.dll => /c/WINDOWS/System32/GDI32.dll (0x7ffb47bf0000)
        gdi32full.dll => /c/WINDOWS/System32/gdi32full.dll (0x7ffb440b0000)
        msvcp_win.dll => /c/WINDOWS/System32/msvcp_win.dll (0x7ffb44bf0000)
        ucrtbase.dll => /c/WINDOWS/System32/ucrtbase.dll (0x7ffb45030000)
        libtiff-5.dll => /mingw64/bin/libtiff-5.dll (0x68ec0000)
        liblzma-5.dll => /mingw64/bin/liblzma-5.dll (0x63cc0000)
        libjpeg-8.dll => /mingw64/bin/libjpeg-8.dll (0x6b800000)

That might give you a clue as to what it’s trying to do.

Might also be worth having a dig though how windows locates DLLs, that might allow you to figure out whether there is another version of this same DLL that happens to be in a location that Windows will search first, which could explain the conflict…

Interesting that this question comes along.

Actually I have the exact same problem on CentOs 7. ./configure fails with the message that JSON can’t be configured. And in error.log it says that /lib64/libstdc++.so.6: version ‘GLIBCXX_3.4.21’ is not found. Any ideas how to approach this?

Yes, so that sounds like a similar problem. I’m guessing you’re compiling MRtrix with a non-default compiler? What might be happening is that the MRtrix executables are compiled for a certain version of the c++ standard library (matching your compiler), but at runtime, the system’s default version is used. It’s a similar issue in that the fix is likely to be to somehow modify the linker search path to include the non-default version first. But you probably also want to avoid other non-MRtrix commands using the custom version, so it’s probably not a good idea to make that the system-wide default. So it’s a tricky one to handle…

Thankfully, I reckon there might be a relatively easy fix – assuming I’ve got this right. Normally you’d be adding an entry to the /etc/ld.so.conf file (or ld.so.conf.d/ folder) with the path to the folder containing your compiler’s libraries, but that’ll set it system-wide (all users). Another approach is to add that location to the LD_LIBRARY_PATH environment variable, which will set it for that session only – better, but other non-MRtrix commands in that session might be affected (and besides, that approach is generally frowned upon for security reasons). So still not ideal.

I think your best bet will be to create a symbolic link to the right library in the MRtrix3 lib/ folder – our executables are hard-coded to look there first, to make sure they find the right version of the MRtrix3 library (libmrtix-3.0_RC2.so or similar), which means that any libraries placed here will be used in preference to the system ones – but only for our executables, just what we want…

To do this, first check where your compiler is (it should say near the top of configure.log), and check what libraries are actually being used at runtime (e.g. ldd bin/mrinfo). I’m guessing you’ll find that it’s trying to use the libstdc++.so from the standard location (e.g. /usr/lib), when your compiler would have installed its version elsewhere (e.g. if the compiler used was /usr/local/bin/g++, I’d expect the library to be /usr/local/lib/libstdc++.so). If you figure out where it is exactly, you can try to create a symbolic link to it within the MRtrix3 lib/ folder like this:

cd lib
ln -s /usr/local/lib/libstdc++.so`
cd ..

At which point, check whether the command now works, and whether the linker finds the right version of the library this time (ldd bin/mrinfo once again).

Hope that at least points you in the right direction…

Hi JD,

Thank you for your detailed response. I guess my question was not entirely clear; this problem turns up right away when configuring.

[martijn@localhost mrtrix3]$ ./configure

MRtrix build type requested: release

Detecting OS: linux
Looking for compiler [clang++]: not found
Looking for compiler [g++]: g++ (GCC) 5.4.0
Checking for C++11 compliance: ok
Checking shared library generation: ok
Detecting pointer size: 64 bit
Detecting byte order: little-endian
Checking for variable-length array support: ok
Checking for non-POD variable-length array support: not found
Checking for ::max_align_t: 16 bytes
Checking for std::max_align_t: 16 bytes
Checking for Eigen3 library: 3.2.5
Checking for zlib compression library: 1.2.7
Checking for "JSON for Modern C++" requirements: 
ERROR: runtime error!
  
   Unable to configure JSON for modern C++

  See the file 'configure.log' for details. If this doesn't help and you need
  further assistance, please post on the MRtrix3 community forum
  (http://community.mrtrix.org/), and make sure to include the full contents of
  the 'configure.log' file.

The configure.log tells me that the configuration process fails because of the following error.

REPORT: Checking for "JSON for Modern C++" requirements:

COMPILE /tmp/tmpWYwJ_R.cpp:
---

#include "file/json.h"
int main (int argc, char* argv[])
{
  nlohmann::json json;
  json["key"] = "value";
}

---
EXEC <<
CMD: g++ -c -std=c++11 -pthread -fPIC -DMRTRIX_WORD64 -DMRTRIX_NO_NON_POD_VLA -I/home/martijn/apps/mrtrix3/core /tmp/tmpWYwJ_R.cpp -o /tmp/tmpWYwJ_R.o
EXIT: 0
>>

EXEC <<
CMD: g++ /tmp/tmpWYwJ_R.o -pthread -lz -o a.out
EXIT: 0
>>

EXEC <<
CMD: ./a.out
EXIT: 1
STDERR:
./a.out: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./a.out)
>>


ERROR: runtime error!
  
   Unable to configure JSON for modern C++

  See the file 'configure.log' for details. If this doesn't help and you need
  further assistance, please post on the MRtrix3 community forum
  (http://community.mrtrix.org/), and make sure to include the full contents of
  the 'configure.log' file.

It should be said that I updated the system GCC to 5.4.0 because the default 4.8 is too old for compiling Mrtrix (that’s what the documentation said).

I also tried to compile with devtoolset 7, but then the configure script fails even earlier.

Best,
Martijn

Okay, it turns out that the following command solved the issue:

LD_PRELOAD=/usr/local/lib64/libstdc++.so.6.0.21 MOC=/usr/bin/moc-qt5 QMAKE=/usr/bin/qmake-qt5 ./configure

Thanks for thinking with me.

Ok, good to hear. Bear in mind that this LD_PRELOAD will be needed for every MRtrix command invocation… I would still recommend placing a symbolic link to that library in the MRtrix lib/ folder, which would avoid that.

Also, just realised that this trick only works at runtime, once the executables have already been built – you would indeed have needed other strategies to configure and build… If that trick works, all the better!

Ok, good to hear. Bear in mind that this LD_PRELOAD will be needed for every MRtrix command invocation… I would still recommend placing a symbolic link to that library in the MRtrix lib/ folder, which would avoid that.

Yes, that’s what I just found out. Thanks!