渡された位置引数を次のように変換するシェルスクリプトを作成しようとしています。
シェルスクリプトはこれらのパラメータをフロントエンド()ffigen
から派生したバイナリ実行可能ファイルに渡すため、後続のコマンドラインパラメータもパラメータであり、同じ意味を持ちます。gcc 4.0
gcc
gcc
次のコマンドラインを検討してください。
./htest.sh -I/usr/include/gtk-2.0 -I /usr/include/glib-2.0 -include \
/usr/include/gtk-2.0/gtk/gtk.h -include/usr/include/bar.h /usr/include/myheader.h
これには本質的に2つの異なるオプションがあります。 1つ-I
はインクルードファイルを検索するためのディレクトリを渡しgcc
、もう1つ-include
はヘッダファイルを#include "file"
デフォルトのソースファイルの最初の行に表示されるように処理することです。
ここで提供される2つの異なるバージョンは、オプションフラグと引数の間にスペースがあるかどうかが異なります。どちらも許可されているようです。
現在のアップストリームで利用可能な唯一のバージョンは次のとおりです。
-I/usr/include/gtk-2.0 and -include /usr/include/gtk-2.0/gtk/gtk.h
しかし、後で誰かがこれらの他のフォームを追加する場合に備えて、このコードを将来使用することを試みることは悪い考えではないようです。
ほとんどの場合、アップストリームスクリプトが実行する作業は、にパラメータを追加してからCFLAGS
最終パラメータをに渡すことですffigen
。ここに何があるかは重要ではありませんffigen
。私の質問はの戻り値に関するものです
CFLAGS
。これはアップストリームスクリプトです。
while [ $# -gt 1 ]
do
echo $CFLAGS
case ${1} in
-pthread*)
CFLAGS="${CFLAGS} -D_REENTRANT"
shift
;;
-x)
shift
shift
;;
*)
CFLAGS="${CFLAGS} ${1}"
shift
;;
esac
done
echo $CFLAGS
私が望むのは、上の行にヘッダーファイル名を指定することです。つまり、含まれているディレクトリに相対的な相対パス名に変換します。だから私が見たい戻り値は次CFLAGS
のようになります。
-I/usr/include/gtk-2.0 -I /usr/include/glib-2.0 -include gtk-2.0/gtk/gtk.h -includebar.h
アップストリームで生成されるのは変更されていないパラメータにすぎません。
-I/usr/include/gtk-2.0 -I /usr/include/glib-2.0 -include \
/usr/include/gtk-2.0/gtk/gtk.h -include/usr/include/bar.h
理由:Debianがmultilibに切り替えたため、ヘッダーファイルは既存の場所にありません。これでffigen
、親エントリと同様に、gcc
ヘッダーファイルのインクルードパスを検索できるようになりました。もし
相対パスのみを指定してください。絶対パスが指定された場合、当然そうではありません。
理想的には、複数のアーキテクチャで動作するように設計されたツールを使用したいが、迅速で汚い解決策は、単にヘッダー絶対パスを相対パス名で削除し、ffigenが正しいインクルードパスを提供する場合は、ヘッダーファイルを検索して発見することです.
現在私が持っているバージョンは以下の通りです。それは作り出す
-I/usr/include/gtk-2.0 -I glib-2.0 -include gtk-2.0/gtk/gtk.h bar.h
これは迷惑ですが、実際に上流で発生する2つのシナリオを正しく処理します。 4つのケースをすべて正しく処理するバージョンが最も人気があります。はい、私は怠惰です。私もシェルスクリプトにも苦手です。
while [ $# -gt 1 ]
do
echo $CFLAGS
case ${1} in
-pthread*)
CFLAGS="${CFLAGS} -D_REENTRANT"
shift
;;
-x)
shift
shift
;;
-I*)
CFLAGS="${CFLAGS} ${1}"
shift
;;
*)
RELPATH_AFTER_INCLUDE="${1##*include/}"
CFLAGS="${CFLAGS} ${RELPATH_AFTER_INCLUDE}"
shift
;;
esac
done
echo $CFLAGS
以下は、これをテストするために使用した小さなスクリプトです。
#!/bin/sh
PROGRAM=htest.sh
#PROGRAM=upstream.sh
./${PROGRAM} -I/usr/include/gtk-2.0 -I /usr/include/glib-2.0 -include \
/usr/include/gtk-2.0/gtk/gtk.h -include/usr/include/bar.h /usr/include/myheader.h
移植性の最後のポイントです。上記のスクリプトはダッシュの下で実行され、移植可能なようです。したがって、ポータブルバージョンがあればいいのですが、必ずしも必要ではありません。このコードの上流は見えないので...移植性がなければbashは大丈夫でしょう。
###################################################################
これの背景に興味がある人のために、これは包装の文脈にあります。クロージャーコモンリーフDebian の場合。
バラよりDebian パッケージング特に README.ソースファイル。
アップストリームパッチを見る
http://svn.clozure.com/publicsvn/ffigen4/trunk/ffigen4/source/h-to-ffi-common
そして
http://svn.clozure.com/publicsvn/ffigen4/trunk/ffigen4/source/linuxx8664-gcc-4.0.0-h-to-ffi.sh
、これは上流のスクリプトを作成するために結合され、h-to-ffi.sh
そのいくつかはここで議論されています。
ここで取り上げたい特定の問題については、スレッドを参照してください。 Debian マルチアーキテクチャにおけるインタフェースデータベースの構築に関する問題。
上記の根拠についての議論は、このスレッドの3番目のメッセージに記載されています。
答え1
-I
or の後にスペースがある場合もありない場合もあるため、オプションを保持-include
できません。$1
そして値。
「-pthread*」、「-x」、および「*」の大文字と小文字を選択する元のバージョンに固執します。次に、CFLAGS変数を累積してからsedを呼び出して、-includeオプションを持つパスの一部のみを削除します。
CFLAGS=$(echo "$CFLAGS" | sed 's#\(-include \?\)/usr/include/#\1#g')
答え2
以下はうまくいきますが、少し長いです。改善のための提案を歓迎します。
while [ $# -gt 1 ]
do
echo $CFLAGS
case ${1} in
-pthread*)
CFLAGS="${CFLAGS} -D_REENTRANT"
shift
;;
-x)
shift
shift
;;
-I)
CFLAGS="${CFLAGS} ${1}"
shift
CFLAGS="${CFLAGS} ${1}"
shift
;;
-include)
CFLAGS="${CFLAGS} ${1}"
shift
RELPATH_AFTER_INCLUDE="${1##*include/}"
CFLAGS="${CFLAGS} ${RELPATH_AFTER_INCLUDE}"
shift
;;
-I*)
CFLAGS="${CFLAGS} ${1}"
shift
;;
-include*)
# strip off leading -include
REMOVE_LEADING_INCLUDE="${1##-include}"
echo "REMOVE-LEADING-INCLUDE" ${REMOVE_LEADING_INCLUDE}
RELPATH_AFTER_INCLUDE="${REMOVE_LEADING_INCLUDE##*include/}"
CFLAGS="${CFLAGS} -include${RELPATH_AFTER_INCLUDE}"
shift
;;
*)
CFLAGS="${CFLAGS} ${1}"
shift
;;
esac
done
echo $CFLAGS