14

最近のカーネル (2.16.24 以降?) はCFLAGS、外部モジュールの Kbuild ファイルで変更された場合を好まないことに気付きました。が変更された場合CFLAGS、Linux カーネル Kbuild システムによって次のエラーが発行されます。

scripts/Makefile.build:46: *** CFLAGS was changed in "/some/path". Fix it to use EXTRA_CFLAGS.  Stop.

ここから:

外部モジュールでは、CFLAGS を変更して gcc オプションを変更した場合がいくつかあります。これは文書化されておらず、悪い習慣でした。

emailLKML からの追加。

なぜそれは悪い考えですか?合理的とは何ですか?

4

2 に答える 2

10

まず第一に、それはEXTRA_CFLAGSしばらく前に非推奨になり、に置き換えられたことに言及する価値があるかもしれませんccflags-y。の意図についてccflags-yDocumentation/kbuild/makefiles.txt、セクション3.7で読むことができます。

基本的に、この変数を使用すると、割り当てられているファイルのスコープ内で、Cコンパイルフラグのセットに設定を追加できます。グローバルフラグを変更することは想定されていません。これは、自分のmakefileを超えてグローバルな影響を与える可能性があるためです。これは、悪い習慣と見なされます。あなたが言及するチェックは、実際に、グローバルフラグが含まれているmakefileによって変更されていないことを確認します。

ccflags-y以前はとして知られEXTRA_CFLAGSていたが、ビルドプロセスでどのように使用されるかを確認するのは興味深いことです。いくつかの関連するポイントをトレースすると(すべてではありませんが、それは読者の練習問題として残されているためです;-))、次のようになります。

EXTRA_CFLAGSによると、まだ使用することができますscripts/Makefile.lib

1 # Backward compatibility
2 asflags-y  += $(EXTRA_AFLAGS)
3 ccflags-y  += $(EXTRA_CFLAGS)

同じファイルはccflags-y、Cコンパイルフラグでどのように終了するかを示しています(また、と呼ばれる別の変数を自由に使用できることも示していますCFLAGS_<filename>.o)。

104 orig_c_flags   = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
105                  $(ccflags-y) $(CFLAGS_$(basetarget).o)
106 _c_flags       = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
...
133 __c_flags       = $(_c_flags)
...
147 c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
148                  $(__c_flags) $(modkern_cflags)                           \
149                  -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)

次に、scripts/Makefile.buildで、コンパイルルールが定義されます。

234 cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<

これらはすべて再帰的に展開される変数で=あり、ではなくを使用することに注意してください。つまり、独自のmakefileで定義すると:=、独自の値がccflags-yCフラグに挿入されます。

最後にKBUILD_NOPEDANTIC、あなたがタイトルで言及しているが実際の質問では言及していないについて。の変更された値のこのテストは、任意の値CFLAGSを指定することで無効にできます。を参照してください。KBUILD_NOPEDANTICscripts/Makefile.build

47 ifeq ($(KBUILD_NOPEDANTIC),)
48         ifneq ("$(save-cflags)","$(CFLAGS)")
49                 $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use ccflags-y)
50         endif
51 endif

この回答で参照されているファイルはすべて、本日取得されました。

さて...この分野の専門家ではなく、このストーリー全体を書き留めた後、makefileをさらに調べてみると、私にも理解できないことがあります。CFLAGSビルドシステムでは(暗黙的にも明示的にも)使用されていないように見えますが、使用されていKBUILD_CFLAGSます。CFLAGSしたがって、この変更のチェックは、実際にはKBUILD_CFLAGS代わりに変更のチェックである必要があるのではないかと思います。

于 2012-06-28T03:45:58.950 に答える
1

Linux の makefileCFLAGSは、カーネルに適した方法でビルドされます。
オーバーライドCFLAGSとは、いくつかのフラグを追加し、いくつかのフラグを削除することを意味します。削除されたフラグの一部は、正しいコンパイルにとって重要な場合があります。

于 2012-06-18T12:55:36.117 に答える