Bashスクリプトを使用して、さまざまなサニタイザー用に複数のcppUteslib.aファイルを作成するスクリプトを作成しようとしています。
コンパイラフラグを変数としてcmakeに渡そうとすると、正しくフォーマットできません。以下の簡単な例をご覧ください。
#!/bin/sh
set -euo pipefail
COMMON_OPTS='-fno-common -g -fno-omit-frame-pointer'
ASAN_OPT='-fsanitize=address'
ASAN_C_FLAGS="-DCMAKE_C_FLAGS=\"$ASAN_OPT $COMMON_OPTS\""
echo "cmake ../ $ASAN_C_FLAGS"
cmake ../ $ASAN_C_FLAGS
make
Echoの出力は私が期待するものであり、bashスクリプトで実行されていないときにフラグを設定するために機能します。
cmake ../ -DCMAKE_C_FLAGS="-fsanitize=address -fno-common -g -fno-omit-frame-pointer"
ただし、スクリプトを実行すると、cmakeがフラグを正しく解釈しません。これらは、構成中に表示されるcmakeフラグには表示されません。
CppUTest CFLAGS: -include "/home/ubuntu/cpputest/include/CppUTest/MemoryLeakDetectorMallocMacros.h" -Wall -Wextra -pedantic -Wshadow -Wswitch-default -Wswitch-enum -Wconversion -Wsign-conversion -Wno-padded -Wno-long-long -Wstrict-prototypes
そして最後に、makeから次のコンパイルエラーが発生します。
c++: error: unrecognized argument to '-fsanitize=' option: 'address -g -fno-omit-frame-pointer'
どんな助けでも親切にいただければ幸いです。
オプションを保持するために配列を使用することを検討してください。そうすれば、シェルが空白で分割してファイル名のグロブを実行する単一の文字列としてではなく、個別の引数としてそれらをcmake
に適切に与えることができます。
sh
シェルは通常、配列をサポートしていないため、代わりにbash
を呼び出すように#!
行を変更しました。
#!/bin/bash
set -euo pipefail
common_opts=( -fno-common -g -fno-omit-frame-pointer )
asan_opt='-fsanitize=address'
asan_c_cflags=( -DCMAKE_C_FLAGS="$asan_opt" "${common_opts[@]}" )
echo "cmake ${asan_c_cflags[@]} ../"
cmake "${asan_c_cflags[@]}" ../
make
ここで、配列を使用すると、引用符で囲まれた複数の引数をcmake
に渡すことができます。これらを単一の文字列に降格したり、シェルに依存して正しく分割+グロブしたりする必要はありません。これにより、スペースを含む文字列で構成される可能性のある引数を適切に渡すこともできます。
関連:
ここでの問題は、ASAN_C_FLAGS
で引用符がエスケープされているため、CMakeはCMAKE_C_FLAGS
変数の引用符で囲まれた値を認識し、すべてを単一の引数としてコンパイラに渡すことです。これらのエスケープされた引用符を削除した後、CMakeは、渡された引数をコンパイラーに渡す前に、空白で正しく分割する必要があります。