TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Show HN: Making GNU Make a better Task Runner

98 点作者 mitjafelicijan大约 1 年前
I know this could be considered blasphemous, but I constantly find myself using Make as a task runner. I have written my own task runner in the past, but somehow I always end up using make.<p>I went, and I put together 3 quality of life snippets I use all the time and put it in a single makext.mk file that can be included in other Makefiles and wrote a basic readme for it.<p>This is not meant to be a replacement for other task runners, but I do think it can be useful to some of you.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;mitjafelicijan&#x2F;makext">https:&#x2F;&#x2F;github.com&#x2F;mitjafelicijan&#x2F;makext</a><p>Check it out and see if it makes sense to you.<p>Thanks for any feedback or comments.<p>Cheers

14 条评论

tpoacher大约 1 年前
Very nice.<p>Whenever I see comments about people trying to reinvent make, my conclusion is that make &quot;as a tool&quot; is inevitably far superior, but people are mostly familiar with a small subset of its functionality, which makes it appear clunky. That, and the syntax is very flexible, which means it can easily be abused to write ugly&#x2F;convoluted makefiles.<p>If I had one thing I&#x27;d want to improve about make, it wouldn&#x27;t be the tool itself, but its documentation, and a set of reasonable defaults&#x2F;templates, like you have here.<p>The documentation is amazing in one sense, in that it&#x27;s very comprehensive, but very clunky and hard to master in another, in that it&#x27;s organised in a very high-level manner that doesn&#x27;t allow it to be used as a quick reference &#x2F; point of truth, if you don&#x27;t know what you&#x27;re looking for. I found myself making anki notes for it, as it&#x27;s not organised in the kind of way that would simply allow me to refer to the docs for your usecase and get things done. You really either know some functionality exists and can look it up or you don&#x27;t, and unless you&#x27;re someone who uses make in expert mode on a daily basis, it&#x27;s hard to know all the specialised components and be able to combine them all together seamlessly. Hence my anki notes, hahah.<p>But make really is an amazing tool. I wish people focused on improving make workflows instead of reinventing the wheel all the time with other tools (which are then forced on the user).
评论 #40342200 未加载
评论 #40344653 未加载
woodrowbarlow大约 1 年前
people often turn to make as a taskrunner, but i&#x27;ve never understood why. i&#x27;ve heard people say &quot;i don&#x27;t want to add another tool&#x2F;language&#x2F;dependency to my project, so i&#x27;ll just use make&quot; but, usually, `make` <i>is</i> a new dependency for the project. `make` (realistically) excludes Windows users, most Linux distros don&#x27;t ship it by default, it is a unique syntax (no, it&#x27;s not shell). even in a C project, it&#x27;s not a given that Make is already a dependency. in languages like python or javascript, with rich package ecosystem, `make` makes even less sense; why limit your users to one OS, and why not write your tasks in your project&#x27;s native language? as a taskrunner, `make` has so many limitations -- because that&#x27;s not what it&#x27;s designed for. `make` is good for tracking dependencies between files that are generated from other files, and that&#x27;s about it.<p>a good taskrunner makes it easy to run a task while still exposing the tool&#x27;s underlying flexibility. a good taskrunner lets me invoke the entire test suite with a short command, but also allows me to add custom options and arguments to, say, run a specific test case in an alternate environment.<p>`make` fails to expose the tools&#x27; underlying flexibility. sure, you can write a .PHONY target to run the full test suite, but `make` can&#x27;t handle passing options or arguments (besides cumbersome Makefile variables).<p>a makefile tends to obscure the underlying tool, enshrining its launch arguments. anyone who has tried to cross-compile a makefile codebase authored by someone who didn&#x27;t consider cross-compilation understands what i mean (you&#x27;ll end up re-writing the Makefile 90% of the time).
评论 #40343275 未加载
评论 #40343350 未加载
评论 #40351256 未加载
评论 #40343056 未加载
smartmic大约 1 年前
Thanks, that is a good idea. I also prefer GNU Make for automatization if the number, diversity or dependencies of the tasks would exceed the benefits of a simple bash script.<p>I stumbled over this statement in your README:<p>&gt; It is recommended to use .PHONY for targets that are not actual files. In the example below I am not doing that though, but it is wise to follow that rule.<p>Please also give the example as you think it would be correct. Or write the understandable reason why you don&#x27;t do it here. I think many people don&#x27;t read the text between the code snippets but only scan the code examples. It would be helpful to find the ‘best practices’ right there.
评论 #40351155 未加载
Galanwe大约 1 年前
&gt; I know this could be considered blasphemous, but I constantly find myself using Make as a task runner<p>It&#x27;s not, don&#x27;t apologize, reusing battle tested tech is the way.<p>I have a quite close &quot;template Makefile&quot;, though I prefer to store it as a cookiecutter (or more recently &quot;copier&quot;) template for easier per-project bootstrap.<p>You could add a timestamped log function. I use that in mine so that targets have timestamped messages pre&#x2F;post.
评论 #40351120 未加载
keypusher大约 1 年前
May want to look at Just. It is heavily inspired by Make and shares much of the same syntax, but removes a lot of the workarounds necessary to use Make as a task runner and adds a few other features.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;casey&#x2F;just">https:&#x2F;&#x2F;github.com&#x2F;casey&#x2F;just</a>
评论 #40342656 未加载
评论 #40351135 未加载
crabique大约 1 年前
Biggest showstopper for me personally is Make&#x27;s inability to properly pass through arguments from `make run &lt;arbitrary number and type of arguments&gt;` to the underlying program.<p>Some of the issues could be avoided by requiring a -- and using the .SILENT modifier, but some are extremely difficult: e.g. it word-splits strings and you can&#x27;t just pass &quot;some string&quot; as a single argument, everything will be separated by spaces.<p>In case the underlying program is a script-language wrapper that you also control, it is possible to hack around and let Make pass through its own $$PPID so that the underlying script could read the nul-terminated &#x2F;proc&#x2F;&lt;Make&#x27;s pid&gt;&#x2F;cmdline and pass it on to the actual program.<p>This, of course, only works where procfs is a thing, so e.g. on macOS (if it&#x27;s among your target platforms) you&#x27;d have to reinvent the wheel and learn a whole lot of Darwin sysctl dark magic to read arbitrary process&#x27; arguments, at which point you&#x27;d ask yourself if this is even something a sane person would ever do...
0xbadcafebee大约 1 年前
I&#x27;ve never found the need for a task runner since learning shell scripting.<p>A lot of people recommend <i>just</i>; here&#x27;s their sample file:<p><pre><code> alias b := build host := `uname -a` build: cc *.c -o main test-all: build .&#x2F;test --all test TEST: build .&#x2F;test --test {{TEST}} </code></pre> Here&#x27;s how I would do that with shell:<p><pre><code> #!&#x2F;usr&#x2F;bin&#x2F;env sh set -eu b=&quot;build&quot; host=`uname -a` _cmd_build () { # build: Build main program cc *.c -o main } _cmd_test_all () { # test_all: Run all tests _cmd_build .&#x2F;test --all } _cmd_test () { # test TEST: Run a test TEST _cmd_build .&#x2F;test --test &quot;$1&quot; } _cmd_help () { echo &quot;Available targets:&quot; grep -E &quot;^_cmd_[^[:space:]]+ \(\) {.+&quot; &quot;$0&quot; | sed -E &#x27;s&#x2F;.*#&#x2F; &#x2F;&#x27; } [ $# -gt 0 ] || _cmd_help set -x &quot;_cmd_$1&quot; &quot;$@&quot; $ chmod 0755 run.sh $ .&#x2F;run.sh Available targets: build: Build main program test_all: Run all tests test TEST: Run a test TEST .&#x2F;foo.sh: line 23: $1: unbound variable $ .&#x2F;run.sh build $ .&#x2F;run.sh test_all $ .&#x2F;run.sh test foo.t </code></pre> But this example (from <i>just</i>&#x27;s homepage) is clearly a build process, so I would use Make for it instead. When I need to be able to run individual sets of commands with arguments and options, I make a shell script. Many more features available, more flexibility, I can tailor it to my use case.
评论 #40346326 未加载
fmajid大约 1 年前
remake is a more powerful tool, a fork of GNU Make that adds a debugger and profiler, among other extensions.<p><a href="https:&#x2F;&#x2F;remake.readthedocs.io&#x2F;en&#x2F;latest&#x2F;" rel="nofollow">https:&#x2F;&#x2F;remake.readthedocs.io&#x2F;en&#x2F;latest&#x2F;</a>
simonmic大约 1 年前
I used make as a task runner for probably 30 years; using all the tricks to do most of the things you want in that use case (arguments, help, portability, reliability..). I worked around all the idiosyncracies continually. That&#x27;s enough time sunk into wasteful friction for me. Now just is here, and the people pushing it are right. For this job (task&#x2F;script manager for more than trivial commands) it&#x27;s better enough and reduces cognitive load enough that it&#x27;s very often worth the install requirement and new learning curve. In time it will be more installed-by-default and I&#x27;m certain it&#x27;ll acquire some form of make-like dependent building as well.<p>[Apologies for contributing to the slightly off topic discussion. makext sounds great for people still using make for this and I totally would have used it in the past.]
评论 #40351168 未加载
blacklion大约 1 年前
I wonder, why GNU make is much more popular than BSD make&#x2F;pmake.<p>Both are extensions to classic make (makefiles without advanced features works with both implementations), but, to my eye, pmake extensions is much more simpler and nicer to use, than GNU make extensions.<p>Simple &quot;.if&#x2F;.else&#x2F;.endif&quot; and true &quot;.for&quot; loop, like in sh is much more comprehensible than GNU make functional extensions to me.<p>Is it only me?<p>And BSD systems have extensive library for pmake already, which allows to build programs, libraries (both shared and static) and more in declarative way, without any custom rules. It is like these extensions, but battle-tested for 20+ years. With nice license, too.
barries11大约 1 年前
Nice, I will definitely use these techniques.<p>Here are a few settings that make GNU make a bit faster, and enable multi-line, strict-mode bash scripts as recipes (make recipes are normally sequences of single-line sh invocations)--and enable quietude &amp; tracing: <a href="https:&#x2F;&#x2F;github.com&#x2F;barries&#x2F;polling_state_machine_cpp&#x2F;blob&#x2F;main&#x2F;make_config.mak">https:&#x2F;&#x2F;github.com&#x2F;barries&#x2F;polling_state_machine_cpp&#x2F;blob&#x2F;ma...</a>
评论 #40351310 未加载
wodenokoto大约 1 年前
A while back someone linked to this relevant comment on HN, about using make as orchestration: <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=32441602">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=32441602</a><p>I also believe I&#x27;ve seen someone setup tools that can draw the dependency graph for you, so you can view (not edit) it airflow style.
pama大约 1 年前
Thanks! Typically I don’t like solutions that involve extra environment variables as things inevitably get messy over time, but your use cases are clean, simple, and common enough that it’s nice to have them documented in one place in this extra makefile.
jjgreen大约 1 年前
I saw MEX_LICENSE and thought: <i>What, this requires a Matlab licence?!?</i>
评论 #40351105 未加载