3 ms·
Thanks for the detailed answer. I see where you are coming from, but it seems to me that some of your assumptions guaranteeing the need of autools or cmake in
by enriquto 6y ago
Thanks for the detailed answer. I see where you are coming from, but it seems to me that some of your assumptions guaranteeing the need of autools or cmake in unix systems are a bit outdated.
> Different distros (and different Unix-like OSs) install things (such as header files) in different places.
This doesn't matter. If the distro is somewhat decent, then once a library is installed they it is found by the compiler. This is certainly true of ubuntu, slackware, voidlinux, openbsd and macos. This means that if you want to use a dependency foo.h, then you can #include <foo.h> inside your code and add -lfoo to your compilation line (inside the makefile) and everything works smoothly, regardless of where the actual headers and libraries are installed. This is true for the clang, gcc and icc compilers. If libfoo is not installed, the compilation will fail, as it should do. Everything else is unnecessary complexity. The actual directories where the files are installed are irrelevant; they are supposed to be found by the compiler (for example, through the CPATH and LIBRARY_PATH environment variables, or by the default compiler specs installed in the distro).
This is perfectly scalable. If you need twelve libraries, foo1 to foo12, then of course you need to add -lfoo{1..12} once in your makefile, typically inside your LDFLAGS variable.
Cmake is the work of the devil, it does not solve any problem and it needs to die, just as autotools.
- rcxdude 6y agoa) this doesn't apply to all distros in practice b) this definitely doesn't apply to non-unix systems c) This ignores the fact that often a user may want/need to control which version of a library they link to, including one which isn't installed in the system (I personally frequently build stuff with intermediate dependencies which are not available in my distro: installing these on the system level is madness especially when you have multiple projects, so I make sure everything is isolated in a project directory). Being able to control where libraries are picked up from is very important in these cases (though of course cmake does have an impressive ability to get it wrong when trying to autodetect). You may wish for a situation where libraries can just be specified easily and consistently (and many languages have a package manager which does just that), but the reality for C++ is incredibly messy (because there's not one package manager but several, most lack a way to distinguish between project and system package or an easy way to add your own, and some platforms still don't have a package manager at all) and a build system which does not deal with that messy reality does not have a hope of adoption. Cmake sucks. autotools even more so. But denying that the problem they're trying to solve exists does not help.
- enriquto 6y agoI agree 100% with almost everything you say. Regarding "a)", can you point me to a distro where after installing a library "libfoo" from the standard packaging system, the C compiler fails to find "foo.h" and the linker fails to work with "-lfoo" ? I've never found such bizarre behavior. Regarding "b)", granted. Portability to microsoft compilers is a bitch, and may as well require cmake. Regarding "c)", this is an impossible problem. If you install a library on ~/my/particular/path/to/libfoo, and you want to compile against this, then of course you will have to specify that particular path manually inside the compilation system. This is possible with cmake, and there's even a beautiful user interface for that. It is just as easy with plain makefiles: you just add the particular path to the C_INCLUDE_PATH and LIBRARY_PATH variables (they work exactly as PATH). No need to mess with -I nor -L. Notice that here you are not using any of the cmake "detection" capabilities, you are just specifying the path manually. This is correct behavior, of course you would not like cmake to spy on its own inside your home dir to see if it can find a certain dependency. > You may wish for a situation where libraries can just be specified easily and consistently Yes I do. And I'm very happy that this is the case. > but the reality for C++ is incredibly messy thanks to autotools, cmake, and other tools written by people who do not understand the concept of PATH. The reality is easy, not messy, it's just people who make it messy intentionally; more out of ignorance, not of malice. Look for example at the imagemagick "detection" rules shown by the OP as a pinnacle of useful and complicated thing that cmake does. It is completely unnecessary bullshit! If imagemagick is installed, then these executables are already on your PATH, and they are found automatically by the shell (that's exactly its job!). If imagemagick is not installed, or if it is installed on a secret directory, then there's no reasonable hope for cmake to "detect" it (other than scanning the whole disk, which I hope it does not try to do...); and if you want to use this secret installation of imagemagick you will have to specify its path manually somewhere in the compilation system. For example, by setting a PATH variable inside your code. Everything that you say is right, and it reinforces my conviction that "detecting" installed libraries never needs to be done. Yet you have hordes of idiots writing detection rules for cmake. What a time to be alive.
- MaxBarraclough 6y agoAnother example: FindBLAS. [0] There are various different compatible BLAS libraries, and the elaborate CMake script accommodates this. To return to a point I made earlier, part of the value of having a configure step before the build step, is to handle all the platform-specific stuff early, failing early and with good error-messages if something is missing. I've seen builds fail several minutes in, it's very annoying, and the configure step should make all the checks necessary to prevent this happening. If the configure step succeeds, I should be able to rely on make succeeding. You make a good case that this step should really be very simple, and I agree, especially considering pkg-config exists, [1] but here we are. (True to form, CMake is able to leverage pkg-config, but makes it painful and confusing. [2] You have to be a master of CMake to figure it out, and the correct answer depends on the CMake version, despite that both pkg-config and CMake were first released in the year 2000.) Also, optional dependencies can be handled properly. I don't see how you could easily handle this with pure Make. [0] https://github.com/Kitware/CMake/blob/master/Modules/FindBLAS.cmake https://github.com/Kitware/CMake/blob/master/Modules/FindBLA... [1] https://en.wikipedia.org/wiki/Pkg-config https://en.wikipedia.org/wiki/Pkg-config [2] https://stackoverflow.com/q/29191855/ https://stackoverflow.com/q/29191855/