有没有比“手表制造”更聪明的替代方案?

问题描述 投票:0回答:13

我遇到了这个有用的提示,如果您经常处理文件并且希望它们自动构建,则可以运行:

手表品牌

每隔几秒它就会重新运行一次,一切都会构建完成。

然而……它似乎一直在吞噬所有的输出。我认为它可能更聪明 - 也许显示输出流,但抑制“全部”不执行任何操作,这样如果没有构建任何内容,则输出不会滚动。

我想到了一些使用循环和 grep 的 shell 脚本方法……但也许有更优雅的东西?有人看到什么了吗?

makefile watch
13个回答
65
投票

使用经典的 gnu

make
inotifywait
,没有基于间隔的轮询:

watch:
    while true; do \
        $(MAKE) $(WATCHMAKE); \
        inotifywait -qre close_write .; \
    done

这样,在当前目录树中写入每个文件时都会触发 make。您可以通过运行来指定目标

make watch WATCHMAKE=foo

14
投票

这里有一句台词:

while true; do make -q || make; sleep 0.5; done

使用

make -q || make
而不是仅仅使用
make
只会在有事情要做时运行构建,否则不会输出任何消息。

您可以将其作为规则添加到项目的 Makefile 中:

watch:
    while true; do $(MAKE) -q || $(MAKE); sleep 0.5; done

然后使用

make watch
来调用它。

此技术将阻止 Make 向终端填充“make: Nothing to be do for TARGET”消息。

它也不会像某些文件观察器解决方案那样保留一堆打开的文件描述符,这可能会导致 ulimit 错误。


13
投票

这句话应该可以做到:

while true; do make --silent; sleep 1; done

它每秒运行一次

make
,并且只有在实际执行某些操作时才会打印输出。


7
投票

怎么样

# In the makefile:
.PHONY: continuously
continuously:
    while true; do make 1>/dev/null; sleep 3; done  

这样你就可以跑了

持续制作

并且仅在出现问题时才获得输出。


6
投票

Twitter Bootstrap 为此使用

watchr
ruby gem。

https://github.com/twbs/bootstrap/blob/v2.3.2/Makefile

https://github.com/mynyml/watchr

编辑:

两年后,

watchr
项目似乎不再维护了。请在答案中寻找其他解决方案。就个人而言,如果目标只是获得更好的输出,我会推荐
wch
这里的答案


3
投票

此 shell 脚本使用

make
本身来检测带有
-q
标志的更改,然后当且仅当有更改时才进行完全重建。

#!/bin/sh

while true;
do
  if ! make -q "$@";
  then
    echo "#-> Starting build: `date`"
    make "$@";
    echo "#-> Build complete."
  fi
  sleep 0.5;
done
  • 除了

    make
    之外,它没有任何依赖项。

  • 您可以将普通的

    make
    参数(例如
    -C mydir
    )传递给它,就像它们传递到
    make
    命令一样。

  • 按照问题中的要求,如果没有任何可构建的内容,它会保持沉默,但在有输出时不会吞咽输出。

  • 您可以将此脚本放在手边,例如

    ~/bin/watch-make
    可跨多个项目使用。


2
投票

我在 Makefile 中这样做:

watch:
    (while true; do make build.log; sleep 1; done) | grep -v 'make\[1\]'

build.log: ./src/*
    thecompiler | tee build.log

因此,只有当我的源代码比我的 build.log 更新时,它才会构建,并且“grep -v”内容会删除一些不必要的 make 输出。


1
投票

有几个自动构建系统可以执行此操作以及更多操作 - 基本上,当您检查版本控制的更改时,它们将进行/构建 - 寻找持续集成

简单的是 TeamCityHudson


1
投票

@Dobes Vandermeer——我有一个名为“mkall”的脚本,它在每个子目录中运行 make 。我可以将该脚本分配为 cron 作业,每五分钟、一分钟或三十秒运行一次。然后,为了查看输出,我将 gcc 结果(在每个单独的 makefile 中)重定向到每个子目录中的日志。

类似的东西对你有用吗?

它可以非常复杂,以避免不执行任何操作。例如,该脚本可以保存每个源文件的修改时间,并在该人更改时执行 make。


1
投票

您可以尝试使用 inotify-tools 之类的东西。它可以让您监视目录并在文件更改或保存或 inotify 可以监视的任何其他事件时运行命令。一个简单的脚本可以监视保存并在保存文件时启动 make 可能会很有用。


0
投票

您可以更改 make 文件以输出 growl (OS X) 或 notify-send (Linux) 通知。对于使用 Ubuntu 的我来说,这会在屏幕右上角显示一个通知气泡。

那么您只会在构建失败时才会注意到它。

您可能希望将

watch
设置为仅以这些通知显示的速度循环(这样它们就不会堆积起来)。


0
投票

有点考古学的味道,但我仍然发现这个问题很有用。这是 @otto 答案的修改版本,使用 fswatch (适用于 Mac):

TARGET ?= foo

all:
    @fswatch -1 . | read i && make $(TARGET)
    @make -ski TARGET=$(TARGET)

%: %.go
    @go build $<
    @./$@

0
投票

这是我编写的一个快速脚本,可以完成所要求的操作:watchmake。它基于

inotify
(因此只能在 Linux 上运行),通过它监听给定文件的更改。

usage: watchmake [-h] [-e EXTENSIONS] [-q] [-i IGNORE] [-m MAKE_CMD]
                 [files ...]

Watch files and make on changes

positional arguments:
  files                 Files or directories to watch. Defaults to current
                        directory

options:
  -h, --help            show this help message and exit
  -e EXTENSIONS, --ext EXTENSIONS
                        Only watch files with this extension
  -q, --quiet           Run quietly
  -i IGNORE, --ignore IGNORE
                        Ignore files or folders. Use a leading "/" to denote
                        files at the top level. Globs not supported
  -m MAKE_CMD, --make-cmd MAKE_CMD
                        Define command to run upon modification of files.
                        Defaults to `make`. You may use {} in the command and
                        it will be replace by the changed file
© www.soinside.com 2019 - 2024. All rights reserved.