4 ms·
Raw makefiles aren't good enough. I want cross-platform package-detection and Visual Studio support. Autotools is the Unix-only solution to package-detection +
by MaxBarraclough 6y ago
Raw makefiles aren't good enough. I want cross-platform package-detection and Visual Studio support.
Autotools is the Unix-only solution to package-detection + environment-detection + build. The cross-platform solution is CMake (not counting its various obscure and immature competitors).
- enriquto 6y ago> Autotools is the Unix-only solution to package-detection I do not understand the concept of "package detection". I guess you mean about dealing with dependencies that are not copied into your code. In that case, either your dependency is correctly installed into your system (and then, by definition, it is automatically found by the compiler and the linker), or it is not. If your dependecy is not correctly installed, either the compilation will fail (which is correct behavior), or you will have to manually edit the configuration so that it can be found, by specifying its path (which is also correct behavior). Both of these things can be perfectly done with plain makefiles. No need for autotools (which is shit) nor cmake (which is shit squared). The alternative is to have your build system to search around your disk for possible versions of the required dependency. This is a completely untoward behavior and in very bad taste.
- MaxBarraclough 6y ago> I do not understand the concept of "package detection". The detection of software packages depended on by my code. Typically this means libraries, and perhaps also executables, either executables needed for the build process (such as code-generators) or executables that will be needed at runtime. If my code uses a Boost library, the Autotools configure script (or CMake) can check that Boost is installed on the machine, check that it has an acceptable version number, and configure the build to look in the right place to find Boost's header files. If Boost is not installed, the configure script (or CMake) will fail with an error. It will do this quickly, not part-way through a build, which is poor form and can be annoying for the user. Configure scripts can also handle optional dependencies. They can also detect platform-specific attributes and produce a header file of the values, helping the developer cope with the platform's quirks. (It might check for the availability of a compiler intrinsic, or something of that sort.) > In that case, either your dependency is correctly installed into your system (and then, by definition, it is automatically found by the compiler and the linker), or it is not. There is no canonical installation path for a Unix package. You're right that the linker can be expected to, well, handle the linking, but that's not the whole story. Different distros (and different Unix-like OSs) install things (such as header files) in different places. Even within a distro, installing a package from source (rather than through the package-manager) may result in it being placed in a different directory. On Ubuntu the convention is that /usr/include holds headers installed through the package-manager, and /usr/local/include holds headers for libraries installed from source. Of course, Windows isn't a Unix-like, and things have to be handled differently there. The configure script should figure out that stuff automatically, the user shouldn't be given a pile of errors to manually fix. They shouldn't have to make any source-code changes just to get things to build. Robustly portable scripts to find packages, can be surprisingly involved. [0] This is why CMake encourages us to write self-contained Find... scripts that be reused by other codebases. > Both of these things can be perfectly done with plain makefiles Doing so manually with raw Makefiles, isn't scalable. This is why systems like Autotools exist. The configure script handles this sort of machine-specific detail. Large programs may have dozens of dependencies. It may be a sizeable task for the user to fix them all. > The alternative is to have your build system to search around your disk for possible versions of the required dependency. This is a completely untoward behavior and in very bad taste. C and C++ are not like Java. There isn't a single idealised system that you can target. You are exposed to platform-specifics, and it's on you to cope with them. This is true both at the source level (good code doesn't rely on sizeof(long) giving any particular value), and at the build level. [0] https://github.com/Kitware/CMake/blob/master/Modules/FindImageMagick.cmake https://github.com/Kitware/CMake/blob/master/Modules/FindIma...
- enriquto 6y agoThanks 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.