bashスクリプトを使用して、さまざまな殺菌剤用に複数のcppUtes lib.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'
どんな助けでも大変感謝します。
答え1
オプションを格納するために配列を使用することを検討してください。これにより、cmake
シェルが空白に分割し、ファイル名のグロービングを実行する単一の文字列ではなく、別々の引数として正しく提供できます。
シェルはsh
通常配列をサポートしていないため、#!
以下を呼び出すように-lineを変更しました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
文字列に減らすことなく、シェルを使用して正しく分割し、グローブ化せずに複数の引数を渡すことができます。これにより、スペースを含む文字列で構成できる引数を正しく渡すことができます。
関連:
答え2
ここでの問題は、エスケープされた引用符のためにASAN_C_FLAGS
CMakeがその変数を引用符で囲んだ値として扱うので、変数全体CMAKE_C_FLAGS
を単一の引数としてコンパイラに渡すことです。これらのエスケープされた引用符を削除した後、CMakeは渡された引数をコンパイラに渡す前にスペースに適切に分割する必要があります。