0

I am building a Windows .bat script to automatically compile and install the Geant4 toolkit from CERN (but my following questions are independent of which of software I want to deal with). What I managed to do so far seems to work OK-ish, but I am not satisfied with how the environment variables are set at the end of the script.

To complete the installation, I have to set up environment variables to indicate the path to required data-sets, and C++ include and library directories (I choose to modify the "PATH" variable for these lasts). I want to set them up for the current script (using set command) and for the next executions (using setx command)

The script I am using now to do that is the following:

REM to get the path to directory where this bat file is executed from.
set G4_bat_file_dir=%~dp0

REM set the environement variables for next cmd runs

REM adding to local (temporary) PATH
set G4dataset_RootDir="%G4_bat_file_dir%\install\share\Geant4-10.4.3\data\"

REM adding environment variables for current and next cmd executions
setx G4dataset_RootDir "%G4_bat_file_dir%\install\share\Geant4-10.4.3\data\"

setx G4ABLADATA %G4dataset_RootDir%\G4ABLA3.1
setx G4ENSDFSTATEDATA %G4dataset_RootDir%\G4ENSDFSTATE2.2
setx G4LEDATA %G4dataset_RootDir%\G4EMLOW7.3
setx G4LEVELGAMMADATA %G4dataset_RootDir%\PhotonEvaporation5.2
setx G4NEUTRONHPDATA %G4dataset_RootDir%\G4NDL4.5
setx G4NEUTRONXSDATA %G4dataset_RootDir%\G4NEUTRONXS1.4
setx G4PIIDATA %G4dataset_RootDir%\G4PII1.3
setx G4RADIOACTIVEDATA %G4dataset_RootDir%\RadioactiveDecay5.2
setx G4REALSURFACEDATA %G4dataset_RootDir%\RealSurface2.1.1
setx G4SAIDXSDATA %G4dataset_RootDir%\G4SAIDDATA1.1

set G4ABLADATA=%G4dataset_RootDir%\G4ABLA3.1
set G4ENSDFSTATEDATA=%G4dataset_RootDir%\G4ENSDFSTATE2.2
set G4LEDATA=%G4dataset_RootDir%\G4EMLOW7.3
set G4LEVELGAMMADATA=%G4dataset_RootDir%\PhotonEvaporation5.2
set G4NEUTRONHPDATA=%G4dataset_RootDir%\G4NDL4.5
set G4NEUTRONXSDATA=%G4dataset_RootDir%\G4NEUTRONXS1.4
set G4PIIDATA=%G4dataset_RootDir%\G4PII1.3
set G4RADIOACTIVEDATA=%G4dataset_RootDir%\RadioactiveDecay5.2
set G4REALSURFACEDATA=%G4dataset_RootDir%\RealSurface2.1.1
set G4SAIDXSDATA=%G4dataset_RootDir%\G4SAIDDATA1.1

setx Geant4_DIR %G4_bat_file_dir%\install\lib\Geant4-10.4.3\

REM adding to PATH the paths to libraries and includes for Qt4 and Geant4.

setx PATH "%G4_bat_file_dir%\install\lib;%G4_bat_file_dir%\install\bin;%G4_bat_file_dir%\xerces-c\instal\bin;%G4_bat_file_dir%\xerces-c\instal\lib;%G4_bat_file_dir%Qt4\install\bin;%G4_bat_file_dir%Qt4\install\lib;%PATH%"

The paths %G4_bat_file_dir%\install\lib;%G4_bat_file_dir%\install\bin;%G4_bat_file_dir%\xerces-c\instal\bin;%G4_bat_file_dir%\xerces-c\instal\lib;%G4_bat_file_dir%Qt4\install\bin;%G4_bat_file_dir%Qt4\install\lib being the ones I want to append.

This is a screenshot of the environment variables set-up I get after running the script 2 times :

http://djienne.free.fr/env.png

This is far from ideal, there several things that I am not happy with:

  • all the paths in the variables get fully expended, and then also the PATH variable gets too long and I get the error "WARNING: The data being saved is truncated to 1024 characters."

  • If I run the script twice in a row, it produces duplicates in the PATH entries (and everything above the 1024 characters limit is truncated)

  • also, if I put this code at the end of my main compilation/installation script it gives the error 'setx' is not recognized as an internal or external command, operable program or batch file. and so the environment variables are not created/modified. But if I run this script as a separate .bat file, it works. So there is something I don't understand. (I specify that I always do "run as administrator" to run the scripts.)

Thanks in advance for the help.

Dji enne
  • 1
  • 2
  • 1
    The first thing you should note is that some of the locations in your path value have a **`\\ `** because `%~dp0` already ends with a trailing backslash. You therefore don't need to follow `%G4_bat_file_dir%` with **`\ `**. – Compo Apr 20 '19 at 14:50
  • If you have an environment variable already set to `%G4dataset_RootDir%`, then to prevent all of your variables which include it from expanding the variable, you could try doubling up the **`%`**'s. e.g. `Set "G4LEDATA=%%G4dataset_RootDir%%\G4EMLOW7.3"`. – Compo Apr 20 '19 at 15:01
  • 1
    __No__, __no__ and sorry, once again, __no__. __NEVER__ set __user__ `PATH` with `setx` using __local__ environment variable `PATH`. Please read [What is the reason for "X is not recognized as an internal or external command, operable program or batch file"?](https://stackoverflow.com/a/41461002/3074564) and my answer on [Adding the current directory to Windows path permanently](https://stackoverflow.com/a/47080452/3074564) as well as all answers referenced in this answer. Then you should understand why your batch script with `setx` as used __corrupts__ the user's environment running it. – Mofi Apr 20 '19 at 15:18
  • 1
    It is always a very bad design if for compilation of something lots of folder paths must be added to either __user__ or __system__ `PATH` which are both used by Windows all the times, really, you can see that with free Sysinternals (Microsoft) tool [Process Monitor](https://learn.microsoft.com/en-us/sysinternals/downloads/procmon). So it is really not good adding lots of folder paths to `PATH`, especially not at beginning of __system__ `PATH`. – Mofi Apr 20 '19 at 15:27
  • 1
    Microsoft delivers with Visual Studio a batch file which every user who wants to use any compiler of Visual Studio can execute from command line or __call__ from within a batch file to setup the environment necessary to use the compilers. This batch file defines all the environment variables in __local__ environment to use the compilers. Other compilers and also IDEs do exactly the same. I strongly recommend to write a batch file which does the same, setup the environment for usage by the users in __local__ environment without modifying predefined and persistent stored Windows environment. – Mofi Apr 20 '19 at 15:31
  • Thanks for the help. I agree that modifying the system global PATH variable is a bad idea (though it is advocated in the geant4 install doc http://geant4-userdoc.web.cern.ch/geant4-userdoc/UsersGuides/InstallationGuide/html/postinstall.html). I think I have now enough information to find a fix to my problem. I will post it when I come up with something satisfying. – Dji enne Apr 22 '19 at 09:41

1 Answers1

0

Following the advice from the comments, I built a batch script launch_visual_studio.bat at the top level of my project, to launch Visual Studio with an updated local PATH. The file contains the code:

@echo off

REM Set the environment

set G4_bat_file_dir=%~dp0

set QTDIR=%G4_bat_file_dir%Qt5\qt-5.6.3\

set QMAKESPEC=win32-msvc2015

set Geant4_DIR=%G4_bat_file_dir%install\lib\Geant4-10.4.3\

REM split into two parts for readability
set PATH=%PATH%;%G4_bat_file_dir%install\bin;%G4_bat_file_dir%install\lib;%G4_bat_file_dir%install\include\Geant4
set PATH=%PATH%;%QTDIR%lib;%QTDIR%bin;%QTDIR%include

REM launch visual studio

"%vs140comntools%..\IDE\devenv.exe"

This works for visual studio 2015, but will be different for other versions.

For the environment variables other than PATH, QTDIR and Geant4_DIR, since they have very specific names (G4ABLADATA, G4ENSDFSTATEDATA, ...), it seems fine to set them permanently using setx, as shown previously.

Dji enne
  • 1
  • 2