28

これはまったく可能ですか、そしてどのようにですか?

更新:動的データと静的データの両方からファイルを作成するため、これが必要です。

ユースケース:テストディレクトリがあります。各Cファイルはテスト実行可能ファイルを生成します。と

SRCS = $(wildcard [a-z]*.c)

必要に応じて新しいテストを追加できます。makeは新しいテストを見つけ、コンパイル、実行、valgrindします。私もgitを使っています。.gitignore実行可能ファイルを含めたいと思います。

だからそこに。.gitignore静的データ、つまり無視したいファイル(*.oおよび)と実行可能ファイルを動的に作成して含める方法はdepend

4

7 に答える 7

31

別のGNUMakeソリューション。

define次のように、およびexportコマンドを使用してこれを行うことができます。

define GITIGNOREDS
*.o
depend
endef

SRCS = $(wildcard [a-z]*.c)
EXES = $(SRCS:.c=)


export GITIGNOREDS
.gitignore: $(SRCS)
    echo $(EXES) | sed 's/ /\n/g' > $@
    echo "$$GITIGNOREDS" >> $@

$(x)ただし、defineブロック内での展開(つまり)には注意する必要があります。

于 2011-09-11T10:08:34.230 に答える
26

はい、できます。他の人が指摘しているように、おそらくそうすべきではありませんが、可能です。Ashの答えには、defineコマンドを含む1つの解決策がありますが、それは面倒であり、変数を適切な値に展開するのが難しい場合があります。もう1つのトリックは、.ONESHELL:特別なターゲットを使用することです。

レシピのすべての行をシェルの1回の呼び出しに渡すことをお勧めする場合があります。これが役立つ状況は一般に2つあります。1つは、余分なプロセスを回避することで、レシピが多くのコマンドラインで構成されるmakefileのパフォーマンスを向上させることができることです。次に、レシピコマンドに改行を含めたい場合があります(たとえば、SHELLとはまったく異なるインタープリターを使用している場合など)。.ONESHELL特殊ターゲットがmakefileのどこかにある場合、各ターゲットのすべてのレシピ行がシェルの1回の呼び出しに提供されます。レシピ行間の改行は保持されます。

警告のいくつかの言葉:

  • これは、Makefileのすべてのレシピがどのように機能するかに影響します。
  • 出力を抑制したりエラーを無視し-たりするなどの行プレフィックス演算子は、すべてのレシピの最初の行でのみ機能し、後続のすべての行で有効になります。@
  • 一部の古いバージョンまたはGNUMake(新しいコンテナーでもTravisのCIシステムでデフォルトで実行されているものなど)は、このディレクティブを無視して、奇妙なバグや落とし穴を引き起こす可能性があります。ターゲット環境を知っていることを確認してください。

これで、マークダウンファイルを生成する方法は次のようになります。

SHELL = bash
.ONESHELL:
MYVAR = "Some Title"

file.md:
    cat <<- EOF > $@
        $(MYVAR)
        ========

        This stuff will all be written to the target file. Be sure
        to escape dollar-signs and backslashes as Make will be scanning
        this text for variable replacements before bash scans it for its
        own strings.

        Otherwise formatting is just as in any other bash heredoc. Note
        I used the <<- operator which allows for indentation. This markdown
        file will not have whitespace at the start of lines.

        Here is a programmatic way to generate a markdwon list all PDF files
        in the current directory:

        `find -maxdepth 1 -name '*.pdf' -exec echo " + {}" \;`
    EOF

もう1つの落とし穴は、Makeが空白行をスキップすることです。ヒアドキュメントのコンテンツに空白行を含めることが重要な場合は、ヒアドキュメントと一致するように適切なレベルの空白でその行をインデントする必要があります。そうしないと、Makeはそれを食べて、猫に渡さないようにします。

于 2016-03-22T07:41:26.457 に答える
7

GNU Makefileは、次のようなことを行うことができます。それは醜いです、そして私はあなたがそれをするべきだとは言いませんが、私は特定の状況でそうします。

.profile = \
\#!/bin/sh.exe\n\
\#\n\
\# A MinGW equivalent for .bash_profile on Linux.  In MinGW/MSYS, the file\n\
\# is actually named .profile, not .bash_profile.\n\
\#\n\
\# Get the aliases and functions\n\
\#\n\
if [ -f \$${HOME}/.bashrc ]\n\
then\n\
  . \$${HOME}/.bashrc\n\
fi\n\
\n\
export CVS_RSH="ssh"\n  
#
.profile:
        echo -e "$($(@))" | sed -e 's/^[ ]//' >$(@)

make .profile.profileファイルが存在しない場合は作成します。

このソリューションは、アプリケーションがPOSIXシェル環境でのみGNUMakefileを使用する場合に使用されました。このプロジェクトは、プラットフォームの互換性が問題となるオープンソースプロジェクトではありません。

目標は、特定の種類のワークスペースのセットアップと使用の両方を容易にするMakefileを作成することでした。Makefileは、別の特別なアーカイブなどを必要とせずに、さまざまな単純なリソースを提供します。これは、ある意味でシェルアーカイブです。次に、プロシージャは、このMakefileをフォルダにドロップして作業するなどのことを言うことができます。ワークスペースを設定してEntermake workspaceキーを押し、次に、何とかして、Enterキーを押しますmake blah

トリッキーになる可能性があるのは、引用をシェル化するものを理解することです。上記はその役割を果たし、Makefileでヒアドキュメントを指定するという考えに近いものです。それが一般的な使用に適しているかどうかは、まったく別の問題です。

于 2011-07-21T20:28:41.543 に答える
5

それはあなたがどれだけ決心しているかによります。それが機能しないと想定するのが最善です。makefileのヒアドキュメントの代わりに起動するシェルスクリプトを記述します。

失敗1

heredoc:
    cat - <<!
    This is the heredoc.
    !

これにより、次のものが生成されます。

cat - <<!
This is the heredoc.
make: This: No such file or directory
make: *** [heredoc] Error 1

各行は別々に実行されます-おっと。

失敗2

heredoc:
    cat - <<! \
    This is the heredoc.\
    !

これにより生成されたもの:

cat: This: No such file or directory
cat: is: No such file or directory
cat: the: No such file or directory
cat: heredoc.!: No such file or directory
make: *** [heredoc] Error 1

makeの特定のバージョンを使用するメソッドがあるかもしれません(たとえば、GNU makeは、単一のサブシェルでアクションのすべてのコマンドを実行できます)が、その場合、移植性の要件を指定する必要があります。通常の(POSIX準拠など)make場合は、ここでドキュメントが機能しないと想定します。

于 2011-05-03T17:08:59.977 に答える
4

Gnu Makeを使用している場合は、「define」を使用して複数行のテキスト変数を作成し、ルールを使用してそれをファイルにエコーします。6.8https://www.gnu.org/software/make/manual/make.html#Appendingの複数行変数の定義を参照してください。

このような:

  define myvar
  # line 1\nline 2\nline 3\n#etc\n
  endef

  myfile.txt:
         /bin/echo -e "$(myvar)) >myfile.txt

これを作成するには、エディターを使用して、必要なファイルを作成し、すべての行の末尾に「\ n」を追加して、それらすべてを1つの文字列に結合すると便利です。それをmakefileに貼り付けます。

LinuxでGNUMake3.81を使用してテスト済み。

于 2014-11-10T18:41:28.937 に答える
0
SRCS = (wildcard [a-z]*.c)
EXES = $(SRCS:.c=)
GITIGNOREDS = *.o depend

.gitignore: $(SRCS)
        echo $(EXES) | sed 's/ /\n/g' > $@
        echo $(GITIGNOREDS) | sed 's/ /\n/g' > $@

重要なのはGITIGNOREDS線です。私は次のようなヒアドキュメントを好んだでしょう

GITIGNOREDS = <<EOT
*.o
depend
EOT

しかし、スペースで区切られたファイルリストと、スペースを改行に変換するsedスクリプトにも満足しています。

編集RyanV.Bissellの提案に従って:gitignoreに追加する別のテストサブディレクトリを使用します。そして、すべてが所定の位置に収まります。簡単だ。

于 2011-05-05T11:39:37.040 に答える
0

Makefileでヒアドキュメントを実行する方法はないようです。ただし、考えられる回避策があります。エコーを使用してヒアドキュメントデータを送信します。

all:
    echo "some text" | myScript.sh
于 2017-05-09T16:19:00.460 に答える