Some Modification to Make G4 Complied Successfully on Windows

As we all know, G4 is run unstablely on windows 2 years ago. On version 4.10 or later, mutithread problem has been solved and the stablity has been proved; more and more ones want to run G4 on Windows. But there are some little bugs especillay build/complie with Qt may had not been tested by Geant4 offical. These bugs may cause some compile errors (CE) which makes new ones install G4 on a virtual machine. Virtulization is a serious a waste of performance. Thus, I will show the modify which can fix these problems.

When I touch Geant4 2 years ago, there is a bug will cause G4interfaces module CE with a LNK2019 error. The reason is not clame a static variable again outside. You can change the empty line 90 in source/interfaces/basic/src/G4UIQt.cc to

#ifdef G4MULTITHREADED
G4coutDestination * G4coutDestination::masterG4coutDestination;
#endif

to fix the problem.

And there is another problem I have not prepared to fix it. Just disable it.

Modify line 1220-1273 in source/visualization/management/src/G4VisCommandsViewer.cc to

G4cerr<<"G4VisCommandViewerInterpolate::SetNewValue is not supported in Windows."<<G4endl;
return;

These below are wrong:

This year (2019), a new bug appeared on version 4.10.5 which will cause G4vis_management throw some CEs. I think the easiest way to fix it (I have not test if it will cause new bugs on run time.) is modify line 1190-1275 in `source/visualization/management/src/G4VisCommandsViewer.cc` to
  // Execute pattern and get resulting list of files
  G4String shellCommand = "echo " + pattern;
#ifndef WIN32
  FILE *filelist = popen(shellCommand.c_str(), "r");
#else
  FILE* filelist = _popen(shellCommand.c_str(), "r");
#endif
  if (!filelist) {
    if (verbosity >= G4VisManager::errors) {
      G4cerr
      << "ERROR: G4VisCommandViewerInterpolate::SetNewValue:"
      << "\n  Error obtaining pipe."
	     << G4endl;
    }
    return;
  }

  // Build view vector of way points
  const size_t BUFLENGTH = 999999;
  char buf[BUFLENGTH];
  char* result = std::fgets(buf, BUFLENGTH, filelist);
  if (result) {
    std::istringstream fileliststream(result);
    while (fileliststream >> pathname
           && safetyCount++ < safety) {  // Loop checking, 16.02.2016, J.Allison
      uiManager->ApplyCommand("/control/execute " + pathname);
      viewVector.push_back(currentViewer->GetViewParameters());
    }
  }
#ifndef WIN32
  pclose(filelist);
#else
  _pclose(filelist);
#endif
Run it on Windows native instead virtual machines and have fun. :slight_smile:

I have moved this to the Visualization forum as this should be more appropriate. If this is a true bug, then it should be raised on the Bugzilla System.

Hi. I disagree to have the “popen” logic on Windows (or _popen if compiling with VisualC++) found in G4VisCommandViewerInterpolate::SetNewValue().

The problem is that the popen logic here uses also the “echo <wildcard>” UNIX shell trick to get file names matching a pattern on one single string. And be sure that if running this from a Windows DOS prompt, it will just not work. There is an “echo” command under DOS, but something as “DOS> echo *” will not return you the list of files in the current directory, it will just print *. This should be ok if running from a CYGWIN prompt, and from a DOS prompt it may be ok if the popen does a “echo.exe <wildcard>” and that your PATH is so that it includes the C:\cygwin64\bin (in order to find the echo.exe found here). But well, I would avoid at all attempting to rely on that.

The code using the std::experimental::filesystem looks better, if it compiles. It compiles with the cl.exe of my VisualStudio 2017. (But I did not check if it does what it is expected to do). If it does not compile with more recent versions, then it is this code that should be improved… (I did not write this, perhaps the author may help here). (But if it does not compile for you, then give us the version of Visual you use and a dump of the errors, someone may help).

Anyway, at term, when/if the std::filesystem be standardised and available, I think it would be better to have that on all platforms. (I just tried to compile some similar code on my Linuxes and my Mac and it does not pass at all; it is definitely too… experimental !).

(In my things I banned the usage of system() and popen() for long, it induced too much portability problems).

Cheers. Guy

Yes, the code is protected by #ifdef WIN32 statements, and yes, the Unix version (that uses popen) was always somewhat experimental, and is part if just one little-used vis command. But…definitely…the code compiles on all supported platforms and compilers (of course we never release code that does not compile on supported platforms). And I agree, Guy, we should replace popen when the C++ standard allows.

What I suspect is that the user is using a compiler that insists on the C++17 standard. The release manager may correct me, but I believe the next release will support VisualStudio 2017. Also, as soon as Geant4 migrates to C++17 we will use on all platforms.

The current release 10.5 supports Visual Studio 2017 (see the release notes) and there are no compilation issues with it.
Next release will support Visual Studio 2019 with c++17 enabled, where std::filesystem will be used.

Yes. You are right. I have not considered the difference between DOS and Unix shell. Sorry about that.

The code is uncomplished about the Pattern class. I think we have to complish it with C++ 17 std::filesystem.