web-dev-qa-db-ja.com

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

Yocto poky環境を利用しようとしています。私は次のことをしました:

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

今、私が使用してプログラムをコンパイルしようとすると:

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

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

ただし、_$CC_を実行すると機能します。 $(CC)と_$CC_の根本的な違いは何ですか?

6
tannoy connect

Makefileで$(CC)が変数CCの拡張として機能し、通常はCコンパイラの名前を保持しているのを見たことがあると思います。 Makefileでの変数展開の$(...)構文は、_$CC_が変数Cの値に展開されるため、複数文字の名前を持つ変数が展開されるときは常に使用されます。リテラルC(_$CC_は、Makefileの$(C)Cと実質的に同じです)。

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

また、$(CC)を_${CC}_と間違えた可能性もあります。これは、シェルでは、ほとんどの状況で_$CC_と同等です。中括弧は、変数の展開の後にimmediatelyが指定されていないと、変数名の一部として解釈される他の文字列が続く場合にのみ必要です。違いの例は、_"$CC_hello"_(_CC_hello_と呼ばれる変数を展開する)と_"${CC}_hello"_(変数CCを展開し、文字列__hello_を追加するその値に)。他のすべての状況では、_${CC}_は_$CC_と同等です。中括弧の使用は展開を引用するnotです。つまり、_${CC}_はnotは_"$CC"_と同じです。

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

_$CC -o hello.elf hello.c
_
17
Kusalananda

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

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

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


$ foo=world
$ echo "hello $foo"
hello world
4
Andy Dalton

この回答では、メイクファイルの構文は考慮されていません。

"$(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 ...
1
Wastrel