2011-12-06 1 views
1

私は、1組のコードで共有ライブラリを構築しようとしていますが、私のMakefileでのこの問題を除いてすべて動作します。ここでは、これまでの私(簡体字)のMakefileです:あなたはmake libfoo.soを入力するとルールからOS変数を設定する

OBJS = bar.o 

libfoo.so: OS = LINUX  # These don't seem to happen 
libfoo.dll: OS = WINDOWS 

# Linux 
ifeq ($(OS), LINUX) 
CC = gcc 
... 

# Windows 
else ifeq ($(OS), WINDOWS) 
CC = i686-pc-mingw32-gcc 
... 
endif 


all: libfoo.so libfoo.dll 

libfoo.so: clean $(OBJS) 
    ... 

libfoo.dll: clean $(OBJS) 
    ... 


bar.o: bar_$(OS).c bar.h 
    ... 

ので、私はそれが最初OS = LINUXを設定することを期待します。そして、bar.o(libfooの依存関係)になると、どのbar_$(OS).cを使うべきか分かります。それはbar.oを作るしようとしたとき、$(OS)が設定されていないことを私に伝えます

make: *** No rule to make target `bar_.c', needed by bar.o. Stop. 

:しかし、私はエラーを取得します。しかし、libfoo.soを作成しようとすると、それが最初に起こるべきではないでしょう。そのルールは評価されますか?

答えて

0

することは、あなたは再帰的に変数をエクスポートした後、Makefileを呼び出すことができます。

OBJS ?= foo.o     # Use ? so it isn't blown away on recursive call 

libfoo.so: OS = LINUX 
libfoo.so: OBJS += linux_only.o 
libfoo.so: 
    $(MAKE) -s build_libfoo_linux 

build_libfoo_linux: $(OBJS) 
    @echo "OS = $(OS)"   # Should print "OS = LINUX" 

export OS      # Can be anywhere 

あなたがする必要があります再帰的なmakeコールの後に "永続化"したい変数をエクスポートすることを忘れないでください。また、上に示したように、コールの前に任意の変数に追加する場合は、最初の割り当てを?=にして、2回目に設定しないようにします。

-1

unameを使用してOSを検出し、条件付きでコンパイルすることができます。 This説明

+0

これはまったく役に立ちません。私は同じシステムから.soと.dllを構築しているので、私の開発ボックスが動作しているOSは無関係です。 –

2

ターゲット固有の変数は、ルールの本体で使用でき、前提条件では使用できません。しかし、これをうまく動かすことができたとしても、あなたは問題を抱えているでしょう:1つのライブラリを構築し、次に別のライブラリを構築する場合、最初に作られたbar.oが2番目と使用しないでください。

効果を得るにはいくつかの方法がありますが、どれも完璧ではありません。私はbar_unix.obar_windows.oのような2つの異なるオブジェクトファイル名を使用することをお勧めします。あなたはターゲット固有の変数を設定し、そのルールの体外その変数が使用可能にしたい場合は

+0

"ターゲット固有の変数"は、私が探していたが知らなかったフレーズでした。これは今や理にかなっています。あなたの個別に名前が付けられたoファイルの解決策は、私がこの作業を行うために使用したものです。私はそれに固執すると思います。ありがとう! –

+0

本当にこれを行う方法は、makeへの再帰呼び出し(これは私の状況ではよりエレガントですが、ツールチェーンの設定に多くの変数が必要です)です。 –

関連する問題