I was trying to install some software from source today. After dicking around for a full day last week trying to port it’s build chain to Bazel, I decided to just install the build toolchain it expects.
I install Cmake, and try to build my program. No dice! This source file requires cmake version 2.8.12, and CentOS 7 comes with 2.8.11. Ergh. So, I go back to source, and grab and make the latest cmake. A quick make, make install, and I go back to the original directory and… get the same error message?
/cmake . CMake Error at CMakeLists.txt:1 (cmake_minimum_required): CMake 2.8.12 or higher is required. You are running version 2.8.11
What can this be? Did it not install? I make clean, make install again, and this time I search for where it’s installing. /usr/local/bin/cmake ; It seems to work. It’s in path. I run ‘which cmake’ and it tells me ” /usr/local/bin/cmake”, as I expect. I run directly from that path, and check the version; 3.2.2, as I expected. What gives? Why does simply running it not give me the expected results? I throw strace at it; The top line of strace shows the correct path:
execve("/usr/local/bin/cmake", ["cmake"], [/* 26 vars */]) = 0
At this point, I’m fairly stumped. Clearly, the old executable still exists, so I search my path for it; The old version of cmake is in /usr/bin. I then wonder at what could be causing the redirection, so I launch a new terminal, type cmake –version… and I get the correct result! Launching bash as a subshell also gives me what I want. So, what’s wrong with my initial shell?
At this point, I was fairly stumped, so I asked my dad, an old unix hand, and he pointed me to the ‘hash’ builtin. Bash keeps a dictionary of commands to their full pathnames; Presumably for speed, as doing several directory listings for each command would be wasteful, even with all of the PATH directories in ram.
The solution is simply to call ‘hash cname’ or ‘hash -r’ to cause bash to redo the dictionary entry for cname, or for everything, respectively.