According to the Wikipedia, Hard coding (also, hard-coding or hardcoding) refers to the software development practice of embedding what may, perhaps only in retrospect, be regarded as input or configuration data directly into the source code of a program or other executable object, or fixed formatting of the data, instead of obtaining that data from external sources or generating data or formatting in the program itself with the given input.
Considered an anti-pattern, i.e. a pattern that may be commonly used but is ineffective and/or counterproductive in practice, hard coding requires the program's source code to be changed any time the input data or desired format changes, when it might be more convenient to the end user to change the detail by some means outside the program.
So, hardcoding is a bad programming habit. Hard coding can be especially problematic at the big computer centers where the software is usually compiled in the temporary directory and then executables and configuration files are moved to the other location.
Several source and configuration files of AmberTools 1.5 have the hardcoded data (file and directory names, link options).
We developed a patch file which should be applied before compilation of AmberTools to fix hardcoded data in several files.
patch -p0 -N <ambertools-1.5-fix-hardcoded.all
After this patch nab and reduce programs will use the AMBERHOME environment variable to build the full paths to the $AMBERHOME/bin, $AMBERHOME/lib and $AMBERHOME/dat directories instead of their hardcoded values at the time of compilation.
To give more control to the experienced user the configure script in the $AMBERHOME/AmberTools/src directory was modified so that now it generate a file, nab.ini, in the $AMBERHOME/bin directory with the list of necessary libraries and linker options. The sample nab.ini file contains data like this:
# Amber NAB configuration file
FLIBS= -L$(LIBDIR) -lsff -lpbsa -lrism -ldrfftw -ldfftw $(LIBDIR)/arpack.a $(LIBDIR)/libnetcdf.a -Wl,--start-group /opt/intel-mkl/10.0.1.014/lib/em64t/libmkl_intel_lp64.a /opt/intel-mkl/10.0.1.014/lib/em64t/libmkl_sequential.a /opt/intel-mkl/10.0.1.014/lib/em64t/libmkl_core.a -Wl,--end-group -lpthread -L/opt/intel-fc/10.1.017/lib/ -lifport -lifcore -lsvml
So, now when a nab program starts it uses the AMBERHOME environment variable to load the nab.ini file from the $AMBERHOME/bin directory, reads in a string with the list of necessary libraries and linker options, and substitute all occurrences of the substring $(LIBDIR) to the current value of the $AMBERHOME/lib.
To give a user an additional flexibility (especially if he/she does not have the priviledges to edit the nab.ini file), he/she can overwrite the data from the nab.ini file using the FLIBS environment variable.
Now by default a program uses C preprocessor bundled with the Amber, ucpp, and uses the AMBERHOME environment variable to build the full path to the ucpp, i.e. $AMBERHOME/bin/ucpp. To give a user the possibility to use other C preprocessor without recompiling a program, we added an option to use an environment variable CPP which contains the full path to the custom C preprocessor, i.e. by defining the variable CPP
setenv CPP /usr/bin/cpp
we can overwrite the default behaviour and program will use /usr/bin/cpp as a C preprocessor.
All of them have the hardcoded location of the pyhton interpreter on the first line, for example
After considering several possible options we decided to choose the simplest and, at the same time, flexible solution: we created a script file, run-after-moving-amber, which should be run each time only when the compiled Amber distribution is moved to other location. It should be run AFTER the compilation of AmberTools and it changes the first line in all files with the hardcoded python location either to the $AMBERHOME/bin/python value or to the custom python location. For example, if running without the argument, i.e.
script assumes that we want to use the python bundled with the Amber, so it takes the current value of the $AMBERHOME environment variable, adds path to the python, /bin/python, and puts the resulted value in the first line of all harcoded scripts after #!.
If we want to use the python installed on the system (preferable solution) a script should be run with the path to the python as an argument, i.e.