2016-11-23 6 views
0

Lua-i18nで作業しています。ユーザーが関心のある機能を持つプロジェクトをコンパイルできるようにMakefileを変更しようとしています。つまりMakefileは対応するコードを無効にするCマクロを定義しています。 Makefileでそれを定義することは簡単ですが、このように定義されたフィーチャにリンクされた不要なコンパイルの依存関係を取り除くことは、移植性を目標とする場合にはあまり意味がありません。実際、このプロジェクトでは、できるだけ元のコードを修正し、可能な限り少ない依存性を追加することを目指しています。Makefileに移植性のあるoptionnal依存性を持たせる移植可能な方法はありますか?

ので、ここでは、プロセス

GNUのメイクではFedora 24デスクトップ上で動作するようですソリューションです。しかし、私は、そのようなソリューションが、(合理的に現代的な)あらゆる実装でうまくいくかどうかを知りたいと思っています。

cflag= -D CODE_SWITCH 
resolved_conditional_cflag!= test -n "$(cflag)" && echo "$(cflag)" 
conditional_dep= additional_dep.c 
mandatory_dep= dep0.c dep1.c 
resolved_conditional_dep!= test -n "$(cflag)" && echo "$(conditional_dep)" 
all_dep= $(mandatory_dep) $(resolved_conditional_dep) 
all: target 
    @echo building code with flag $(resolved_conditional_cflag) 
    @echo ${SHELL} 
target: $(all_dep) 
    @echo building [email protected] which depends on $(all_dep) 
dep0.c: 
    @echo building dep0.c 
dep1.c: 
    @echo building dep1.c 
additional_dep.c: 
    @echo building [email protected] 

アイデアは、ユーザーが行cflag= -D CODE_SWITCHコメントということであり、それがすべてです、コンパイラは、関連する依存関係を処理しません。だから、そのようなソリューションは移植可能でしょうか?これは、シェル拡張!=testコマンドに依存しています。私は最後のものがPOSIXかもしれないと思うが、私は間違っているかもしれない。より一般的には、私がここで気づいていない移植性の問題かもしれません。

この特定の要求に対しては、「CMake、autotoolsなどを使用する」は望ましい回答ではありません。

答えて

1

!=は、GNU make 4.0以降でのみ使用できます。 POSIXではありません。 BSD makeとの移植性のためにGNU makeに追加されました。これはPOSIX仕様に含めることが提案されましたが、今のところ受け入れられていません。

純粋な移植性のあるmake(POSIX)のみを使って、makeマクロの内容に基づいてターゲットの前提条件を変更する方法はわかりません。

GNU makeを使用したい場合は、少なくとも今のところは、$(shell ...)!=よりも移植性があります。 GNU makeを想定している場合は、シェルをまったく必要としない、これを処理するためのより良い方法があります。 BSD makeで移植性を得るために!=を使用する場合は、GNU make 4.0以上が必要なドキュメントをドキュメントに追加してください。

N.B.では、makefileに変数名と代入演算子の間に空白を入れないことは、通常は本当に悪い考えです。例えばFOO!=barまたはFOO!= barの代わりにFOO != barと書くことをお勧めします。クロノきつねによって議論されるよう

EDIT

1つのオプションは、再帰のビットを使用することであろう。あなたは物事がcflag自体をコメントアウトに依存する必要はありません場合は、再帰的な変数の命名を使用することであろう、

cflag= -D CODE_SWITCH 

conditional_dep= additional_dep.c 
mandatory_dep= dep0.c dep1.c 

all_dep= $(mandatory_dep) 
all: target 
     @echo building code with flag $(cflag) 
     @echo ${SHELL} 
target: $(mandatory_dep) 
     @all_dep='$^'; if test -n "$(cflag)"; then \ 
      all_dep='$^ $(conditional_dep)'; \ 
      $(MAKE) $(conditional_dep); \ 
     fi; \ 
     echo building [email protected] which depends on $$all_dep 
dep0.c: 
     @echo building dep0.c 
dep1.c: 
     @echo building dep1.c 
additional_dep.c: 
     @echo building [email protected] 

別の代替;:それはこのようになりますそれはこのようになります:$($(SWITCH)_cflag)が存在しないを拡大していきますので、

SWITCH = enabled 

enabled_cflag = -D CODE_SWITCH 
enabled_dep = additional_dep.c 

mandatory_dep = dep0.c dep1.c 

cflag = $($(SWITCH)_cflag) 
all_dep = $(mandatory_dep) $($(SWITCH)_dep) 

all: target 
     @echo building code with flag $(cflag) 
     @echo ${SHELL} 
target: $(all_dep) 
     echo building [email protected] which depends on $(all_dep) 
dep0.c: 
     @echo building dep0.c 
dep1.c: 
     @echo building dep1.c 
additional_dep.c: 
     @echo building [email protected] 

を今、あなたはSWITCH設定をコメントアウト、またはmakeコマンドラインで空にし、それを設定した場合、それらの要素は(オフになります/空変数_cflagenabled_cflagではありません)。再帰的変数の命名は、ほとんどのバージョンのmakeでサポートされています(ただしすべてではありません)。

+0

必要なシステムで、いくつかのシェルコードと '$(MAKE)conditional-target'を手動で使用することもできますか?まだシェルコードを使用しているので理想的ではありませんが、少なくとも!= 'よりも移植性があります。 –

+0

私はあなたが何を示唆しているか分かりません。条件付きの前提条件を 'all_dep'変数から完全に残しておき、' target'をビルドするためのレシピで 'test -n" $(cflags) "&& $(MAKE)$(conditional_dep)'を実行すると、リンクコマンドを実際に実行する前にそれはあなたが念頭に置いたことですか?作者が 'cflags'ではなく全く異なる変数を使用することを喜んでいたら、それは再帰的マクロではかなり簡単に行うことができます。 – MadScientist

+0

はい、それは私の考えです。申し訳ありませんが私の意図ではっきりしていませんでした。そのような解決策に問題はありますか? 'test'はすでに使用されているので、このアイデアは潜在的なポータブルな解決策であると私は思っていますが、発生する可能性があるいくつかの問題については盲目的かもしれません。 –

関連する問題