Live data from Hacker News

A Tutorial on Portable Makefiles

nullprogram.com

81–90 of 114 posts

Re: A Tutorial on Portable Makefiles

#81
post #76

Honestly, just use Cmake. It is far easier to make it work cross playform and better yet cross compile. There's no good reason to write a Makefile by hand and no large projects do it anyway

CMake is rather crufty itself. There are many better options these days.

I would love for this to be true, but I'm afraid I don't have any evidence that it is. What are the better options you'd recommend?

More specifically, Google's Bazel [0] is the most serious attempt I know of to replace CMake/autotools, but it only just began to support Windows [1] and requires the JDK. Say what you will about CMake, but it's a quick-and-easy MSI to install on Windows and has supported Windows for probably longer than I've been alive. Google's other open source build system, GYP [1a], supports Windows because it builds Chromium, but GYP might as well be undocumented. Unless you like spelunking into the Chromium source, GYP is a non-starter. (Props to the Node folks for actually doing this for Node and Node extensions.)

I haven't used Gradle [2], but I've heard more than a few times it's slow (warning: might be FUD)... and it also requires a JRE.

Ninja [3] is blazing fast, but it's specifically designed not to be used directly, but rather through a build system generator like CMake.

I'll be the first person to ditch CMake if a feasible alternative presents itself, but if you want to build a cross-platform, moderately-complicated C++ project today, especially one with dependencies on other libraries that use arbitrary build systems, I don't know of any such alternative.

[0]: https://bazel.build

[0a]: https://gyp.gsrc.io

[1]: https://docs.bazel.build/versions/master/windows.html

[2]: https://gradle.org

[3]: https://ninja-build.org

Re: A Tutorial on Portable Makefiles

#82
post #37

where, except for Windows, is requiring GNU Make a problem?

It's not really a problem on Windows, to be honest. MSYS2 gives you that, gcc, and a bunch of POSIX utilities to boot. It also gives you packages for libraries, and a Unix-like filesystem structure where they are deployed (/usr etc). Yet you end up building clean Win32 binaries, with no emulation layers.

Re: A Tutorial on Portable Makefiles

#83
post #31

Earlier quoted context omitted.

I personally use scons instead of Makefiles. Its dependency analysis is amazing, I haven't seen it fail a single time.

Did scons finally get a little less opinionated? It used to be that scons really forced you to use subsidiary SConscript child files for anything more complicated than a couple files in a single directory instead of being able to lump it all into a single SConstruct.

I think that was quite long ago. Yes, `SCons` can fit into a single file if you so choose. But its behavior under recursive builds (with nested directory structure) is far more predictable than most build systems I have seen.

Re: A Tutorial on Portable Makefiles

#84
post #14

An issue I have with make is that it can not handle non-existence dependencies. DJB noted this in 2003 [1]. To quote myself on this [2]: > Especially when using C or C++, often target files depend on nonexistent files as well, meaning that a target file should be rebuilt when a previosly nonexistent file is created: If the preprocessor includes /usr/include/stdio.h because it could not find /usr/local/include/stdio.h…

I'm missing something. Are you saying you want to be able to compile either way /usr/include/stdio.h and /usr/local/include/stdio.h, but remember what the last compilation used and know what header would be used in the next compilation, and if it's different, mark the target as stale and perform the action? I guess you'd need to keep a log of the build and test cpp invocations for diffs. I've never run into this scen…

An obvious case would be a developer supporting multiple versions of a 3rd party library.

Re: A Tutorial on Portable Makefiles

#86

An issue I have with make is that it can not handle non-existence dependencies. DJB noted this in 2003 [1]. To quote myself on this [2]: > Especially when using C or C++, often target files depend on nonexistent files as well, meaning that a target file should be rebuilt when a previosly nonexistent file is created: If the preprocessor includes /usr/include/stdio.h because it could not find /usr/local/include/stdio.h…

Could you summarize how you handle this in redo? Also what about the case where a header file does exist but is out-of-date and because of that triggers an error (e.g., version compatibility check with #error) -- how do you handle that?

Re: A Tutorial on Portable Makefiles

#88

An issue I have with make is that it can not handle non-existence dependencies. DJB noted this in 2003 [1]. To quote myself on this [2]: > Especially when using C or C++, often target files depend on nonexistent files as well, meaning that a target file should be rebuilt when a previosly nonexistent file is created: If the preprocessor includes /usr/include/stdio.h because it could not find /usr/local/include/stdio.h…

Make has no memory so it can't remember things. It simply compares the dates of files. If a dependency is newer than a target the target is rebuilt. If you want to keep some kind of memory you have to build and keep track of it yourself. But the problem you point at is simply poor design. It is not a normal occurrence for system header files to move around like you state. If they do, a full rebuild is indeed required…

If an apt-get upgrade fixed an issue in a system header or a library, but the date of the fix predates the last build (quite common; last build from yesterday, fix from two days ago but downloaded today) then make will do nothing (or any subset of the right things but not all) and make clean; make will do the right thing.

Relying on time stamps is a design decision that was good for its time, but it is no longer robust (or sane) an a constantly connected, constantly updated, everything networked world.

djb redo takes it to one logical conclusion (use cryptographic hashes to verify freshness)

There are other ways in which make is lacking: operations are non atomic (redo fixes that too), dependency granularity is file level (so dependency on compiler flags is very hard, dependency on makefile is too broad; redo fixes this too); dependency is manual (redo doesn't fix this; AFAIK the only one that properly does is tup)

Re: A Tutorial on Portable Makefiles

#89
post #46

> Microsoft has an implementation of make called Nmake, which comes with Visual Studio. It’s nearly a POSIX-compatible make, but necessarily breaks [...] Windows also lacks a Bourne shell and the standard unix tools, so all of the commands will necessarily be different. What I've been mulling over is an implementation of make that accepts only a restricted subset of the make syntax, eliding the extensions found in ei…

What you're mulling over is the precept for the autotools toolchain.. spare the next generation the same pain we bore :)

carussell is suggesting the opposite of autotools in the sense of making a very restricted tool that only allows portable code (at least within the domain of that tool). By contrast, autotools tries to be expansive in many ways (1) it provides all kinds of bits and pieces of the toolchain, (2) it tries to support all systems by auto-generating build scripts using sniffed the system properties.

Re: A Tutorial on Portable Makefiles

#90
post #81
post #76

Earlier quoted context omitted.

CMake is rather crufty itself. There are many better options these days.

I would love for this to be true, but I'm afraid I don't have any evidence that it is. What are the better options you'd recommend? More specifically, Google's Bazel [0] is the most serious attempt I know of to replace CMake/autotools, but it only just began to support Windows [1] and requires the JDK. Say what you will about CMake, but it's a quick-and-easy MSI to install on Windows and has supported Windows for pro…

Meson (https://www.mesonbuild.com/) seems to have a lot of momentum; GNOME has just adopted it. It is designed around a non-Turing complete, object-oriented DSL, plus extension modules written in Python.
Post reply on HN