$(CC) と $CC の違いは何ですか?

$(CC) と $CC の違いは何ですか?

私は yocto poky 環境を使用しようとしています。次の操作を実行しました:

#source environment-setup-cortexa9hf-neon-poky-linux-gnueabi 

ここで、次のコマンドを使用してプログラムをコンパイルしてみます。

#$(CC) hello.c -o hello.elf 

定義されていないため、エラーが発生します$(CC)

ただし、そうすると$CC動作します。$(CC) と の根本的な違いが何なのかわかりません$CC

答え1

Makefile で、通常は C コンパイラの名前を保持する$(CC)変数 の展開として機能する を見たことがあると思います。Makefileでの変数展開の構文は、複数文字の名前を持つ変数が展開されるたびに使用されます。そうでない場合、変数の値にリテラル(は実際には Makefileと同じになります) が続きます。CC$(...)$CCCC$CC$(C)C

ただし、シェルでは、構文が異なるため、$(CC)コマンドを実行した出力に置き換えられるコマンド置換が行わCCれます。システムにそのようなコマンドがない場合は、「コマンドが見つかりません」というエラーが表示されます。

シェルでは、ほとんどの場合、 と同等である を$(CC)間違えている可能性もあります。 中括弧は、変数の展開が次のようになる場合にのみ必要です。${CC}$CCすぐに変数名の一部として解釈される他の文字列で置き換えられます。違いの例としては、"$CC_hello"( という変数を展開しますCC_hello)と"${CC}_hello"(変数を展開しCC、その値に文字列を追加します_hello)が挙げられます。その他の状況では、${CC}は と同等です$CC。中括弧の使用はない展開を引用すると、${CC}すなわちないと同じ"$CC"

C コードのコンパイルに使用しているコンパイラの名前を保持するシェルまたは環境変数があり、その変数をコマンド ラインで使用する場合は、 を使用する"$CC"か、$CC変数の値にスペースやシェル グロブ文字が含まれていない場合は のみを使用します。

$CC -o hello.elf hello.c

答え2

これら 2 つは同等ではありません。 を含む行では$(foo)、 は$(foo)コマンド の出力に置き換えられますfoo。 例:

$ echo "hello $(echo world)"
hello world

を含む行では$foo、 は$fooという名前の変数の値に置き換えられますfoo。例:


$ foo=world
$ echo "hello $foo"
hello world

答え3

この回答では、makefile 構文は考慮されていません。

"$(CC)"はコマンドの出力ですCC

"$CC"変数の値ですCC

これにより違いが明確になります:

$ CC=ls
$ echo $(CC)
CC: command not found
$ echo $CC
ls

そして

$ echo $($CC)
bin   cdrom  dev  home        initrd.img.old  lost+found  mnt  proc  run ...

関連情報