Use `make` to save time
medium.freecodecamp.org
medium.freecodecamp.org
Don't get me started on Makefiles that invoke Docker.
Some practical advice: don't write a rule like "./script < input > output"; instead write "./script < input > output.new && mv output.new output". That way if the script fails it doesn't leave things in a broken state with "output" appearing to be up-to-date. Perhaps a replacement for "make" would incorporate this mechanism?
A replacement for "make" would also have a proper way of handling the situation in which a file is regenerated and found not to have changed, to replace all those half-working "stamps" and "move-if-change" hacks.
Edit: See also: https://www.gnu.org/software/automake/manual/html_node/Multi... Presumably a decent build system would make this fairly normal situation somewhat easier to handle.
GNU make has ".DELETE_ON_ERROR" for this.
But yes, make is quite horrible if you want reliable incremental builds. For example, $OLD_VERSION of your software generates a file $output/plugins/stuff.so, and $NEW_VERSION no longer does so, the file will stick around and the new version of the software will load an outdated plugin. This type of stuff causes weird issues that disappear on the next fresh checkout (especially during development, where the plugin ABI may be unstable). If a rule disappears, so should its output file(s) on the next build.
Why are there so many build systems that don't even attempt to handle this stuff? Surely we aren't the only project that uses glob patterns like plugins/*.so? You can't fix these fundamental design problems by using meta-build-tools that end up generating makefiles...
Nobody would use make instead of maven [1] with Java for example. Ruby uses Rakefile instead of Makefiles. You will probably confuse lots of developers that work on your project if you do that.
On top of that Makefiles are known to be generated these days ( CMake ).
1 : https://stackoverflow.com/questions/2209827/why-is-no-one-us...
Apparently, most people......
The idea that "nobody" uses make for Java when Java itself does, is a little bit a stretch ;)
Even the ergonomics of the tool are poor - it spams log output with all sorts of information other than what you actually need (like the output of a failed compilation). Getting information from a failed test is painful. If you change one module that another depends on, the latter will not be rebuilt - letting you find issues via NoSuchMethodError at runtime. Annotation processors require special care to enable, and don't always run when they should.
I would rather use make and javac than Maven. Gradle, Bazel (and its diaspora of non-google imitations) would be much better choices.
\ifx\ispreambleloaded%
\relax%
\else%
\def\isstandalone{}%
\input{preamble}%
\fi
% ... content ...
\ifx\isstandalone\end{document}\fi%
and the preamble.tex would look like: \documentclass{scrbook}
% ... all the other stuff that goes in the preamble ...
\begin{document}
\def\ispreambleloaded{}%
(Note: Recounting this all from memory, so I may have gotten some stuff wrong.)However, I don’t see much value in using make as intended in the article. The author uses it as some sort of “shared bash history” for developers, where it is used to store the most relevant commands for a project.
Make is good for keeping track of what changed in your environment and, when it does change, to do the least amount of work necessary to build your asset. For the problem that the author is trying to solve, I would recommend something like Ansible, which feels simple and its playbooks often serve as documentation.
That said, I am really impressed with Google’s meta tool called GN which generates scripts for a build system called Ninja. This tool chain is based on performance, and the scripting is much easy/less ugly than cmake.
Perhaps Snakemake? I've been using it recently in Bioinformatics and I love it. It works perfectly on our Torque/qsub cluster but can also easily switch to a set of dockers in the background.
Something like ./cofigure --prefix=/usr/local/foo
Another thing I miss is the ability to easily pass in custom compilation options, like: CFLAGS="-O0 -ggdb3" LDFLAGS="-L/usr/local/foo/include" ./configure
I know these are features of autotools I'm talking about, not of make per se. Still, a lot of tools that are supposed to be way better than make and autotools just seem to assume every user's going to install in the same location and offer no obvious way to give different compilation options and as a user it's really frustrating because I need both all the time.
For programs with a single file, I might add something like this at the top:
#if 0
gcc -o ~/bin/program program.c
exit
#endif
For programs with multiple files, I will write a shell script to figure out and compile everything (but use stuff like the above to compile each individual file). Although, I should probably make a better way, later.Yeah, you should probably `make` a better way... ;)
To be fair, there are other dependency tools around, but make is a really good starting place to learn what it's about and why you want to use something quite robust. Many people dislike make, but personally I haven't used anything that was substantially better.
Martin Fowler put together a nice article about rake:
https://martinfowler.com/articles/rake.html
If you deal a lot with artifacts you need to download from random places (ala maven, but with a lot more flexibility), or produce artifacts to various repos, buildr is very nice.