Every time I read about posts written by C++ programmers praising CMake, I feel a bit sad.<p>> in CMake, typically when you Find(MyLib), the variables ${MyLib_INCLUDE_DIRS} and ${MyLib_LIBRARIES} get defined<p>> In CMake, an undefined variable (e.g., foo_INCLUDEDIRS instead of foo_INCLUDE_DIRS) becomes an empty string.<p>In C++ land, this can be translated as: there is a global, std::map<std::string, std::string> g_globals. A function Find(std::string libname) returns the result by updating keys in g_globals corresponding to name + magic strings. Oh, and people usually don’t call .exists On that dict, they just use the variables and hope there are no typos.<p>In any C++ library, this kind of interface would be called: “this is completely wrong design, let’s avoid it like a plague. It should be all typed functions, with classes and optional results. But then the same people just accept it in CMake!<p>The sad part, there are no clearly better alternatives. I used SCons before, and I am using Bazel now. They have nice type systems, avoid globals and generally much cleaner. But SCons is slow and underdocumented, and Bazel lacks automatic dependencies and reliable distributed caching. As a result, I cannot honestly say, “drop CMake, use XXXX, it is so much better”<p>IMHO, C++ badly needs a better build system based on sane principles.