GNU makeの前提条件としてHTTPファイルを使用する方法は?

GNU makeの前提条件としてHTTPファイルを使用する方法は?

以下で使いたいです。ワールドワイドウェブ私のmakefileの前提条件として:

local.dat: http://example.org/example.gz
    curl -s $< | gzip -d | transmogrify >$@

リモートファイルがローカルファイルよりも最新の場合は、「変換」したいと思います。作る通常の操作。

はいいいえキャッシュされたコピーを保存したいです。example.gz- ファイルが大きく、生データは不要です。可能であれば、すべてのファイルをダウンロードしないことをお勧めします。目的は、makeフラグを使用して一部を並列に処理することです-j

この問題を解決するためのきれいな方法は何ですか?いくつかの方法を考えることができます。

  • 空のダミーファイルを保持し、ターゲットが再生成されるたびに更新します。
  • GNU makeを使用するいくつかのプラグイン新しいプラグインシステム(私はこれについて何も知らない)
  • ローカルファイルシステムにHTTPサーバーをインストールするための不可知論的な方法

もっと学ぶ前に、いくつかのアドバイス、好ましくは具体的な例を聞きたいです!

ベストアンサー1

Makefileで次のようにしてみてください。

.PHONY: local.dat

local.dat:
    [ -e example.gz ] || touch -d '00:00' example.gz
    curl -z example.gz -s http://example.org/example.gz -o example.gz
    [ -e $@ ] || touch -d 'yesterday 00:00' $@
    if [     "$(shell stat --printf '%Y' example.gz)" \
         -gt "$(shell stat --printf '%Y' $@)"         ] ; then \
      zcat example.gz | transmogrify >$@ ; \
    fi
    truncate -s 0 example.gz
    touch -r $@ example.gz

(注:これはMakefileなので、インデントは空白ではなくタブです。もちろん、連続した行に末尾の空白がないか、\バックスラッシュエスケープを削除してほとんど読みにくい長い行にすることも重要です。)

このGNUmakeレシピは、最初に名前付きファイルがexample.gz存在することを確認し(で使用されるため)、-z存在しない場合はcurlファイルを生成します。touchタッチで生成されたタイムスタンプは00:00(当日午前12時)です。

次に、()curlオプションを使用して、最後のダウンロード以降に変更されたコンテンツのみをダウンロードします。実際の日付表現またはファイル名を指定できます。ファイル名が与えられると、ファイルの修正時間を時間条件として使用します。 -z--time-condexample.gz-z

後で存在しない場合は、保証されたタイムスタンプを使用local.datして生成されます。touch年をとるよりexample.gz。 mtimeタイムスタンプを取得local.datするには、次のコマンドが存在する必要があるため、これが必要ですstat

その後、example.gzタイムスタンプがlocal.datそれよりも最新の場合は、出力をパイプにexample.gzリダイレクトします。transmogrifylocal.dat

最後に、帳簿とクリーンアップを実行します。

  • 切り捨てますexample.gz(フルファイルではなくタイムスタンプだけを維持すればよいので)。
  • touchつまりexample.gz、同じタイムスタンプを持つことになります。local.dat

.PHONY ターゲットは、local.datその名前のファイルがすでに存在していても、ターゲットが常に実行されることを保証します。

元のバージョンが機能していないこと、そしてその理由をコメントで指摘してくれた@Toby Speightに感謝します。

transmogrifyまたは、まずファイルシステムにダウンロードせずにファイルを直接パイプする場合:

.PHONY: local.dat

local.dat:
    [ -e example.gz ] || touch -d '00:00' example.gz
    [ -e $@ ] || touch -d 'yesterday 00:00' $@
    if [     "$(shell stat --printf '%Y' example.gz)" \
         -gt "$(shell stat --printf '%Y' $@)"         ] ; then \
      curl -z example.gz -s http://example.org/example.gz | transmogrify >$@ ; \
    fi
    touch -r $@ example.gz

メモ:これはほとんどテストされていないため、構文を完全に変更するには若干の変更が必要な場合があります。ここで重要なのは、コピー貼り付けカーゴカルトソリューションではなくアプローチです。

私は何十年もの間、このアプローチの変形(touchタイムスタンプファイルなど)を使用してきました。makeそれはうまくいき、通常はshで私の依存関係解決コードを書くのを避けることができます(stat --printf %Yここでも同様のことをする必要がありましたが)。

makeこれがソフトウェアコンパイルのための素晴らしいツールであることは誰もが知っています。私の考えでは、システム管理とスクリプト作業のためのツールとして、深刻に過小評価されたツールでもあります。

おすすめ記事