Every time I read about posts written by C++ programmers praising CMake, I feel a bit sad.
> in CMake, typically when you Find(MyLib), the variables ${MyLib_INCLUDE_DIRS} and ${MyLib_LIBRARIES} get defined
> In CMake, an undefined variable (e.g., foo_INCLUDEDIRS instead of foo_INCLUDE_DIRS) becomes an empty string.
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.
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!
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”
IMHO, C++ badly needs a better build system based on sane principles.
> in CMake, typically when you Find(MyLib), the variables ${MyLib_INCLUDE_DIRS} and ${MyLib_LIBRARIES} get defined
> In CMake, an undefined variable (e.g., foo_INCLUDEDIRS instead of foo_INCLUDE_DIRS) becomes an empty string.
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.
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!
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”
IMHO, C++ badly needs a better build system based on sane principles.