2

Makefileを使用してライブラリのデバッグおよびリリースバージョンをビルドし、それらのライブラリを関連するビルドディレクトリにコピーしようとしています。

.PHONY: all clean distclean

all: $(program_NAME_DEBUG)
    $(CP) $(program_NAME_DEBUG) $(BUILD_DIR)/debug/$(program_NAME_DEBUG)
    $(RM) $(program_NAME_DEBUG)
    $(RM) $(program_OBJS)
    $(program_NAME_RELEASE)
    $(CP) $(program_NAME_RELEASE) $(BUILD_DIR)/release/$(program_NAME_RELEASE)
    $(RM) $(program_NAME_RELEASE)
    $(RM) $(program_OBJS)

$(program_NAME_DEBUG): $(program_OBJS)
    $(LINK_DEBUG.c) -shared -Wl,-soname,$(program_NAME_DEBUG) $(program_OBJS) -o $(program_NAME_DEBUG)

$(program_NAME_RELEASE): $(program_OBJS)
    $(LINK_RELEASE.c) -shared -Wl,-soname,$(program_NAME_RELEASE) $(program_OBJS) -o $(program_NAME_RELEASE)

すべての最初のターゲット(program_NAME_DEBUG)は正常にコンパイルされますが、2番目のターゲット(program_NAME_RELEASE)は次のエラーを生成します。

libGlam_rel.so
make: libGlam_rel.so: Command not found
make: *** [all] Error 127

libGlam_rel.soの値ですprogram_NAME_RELEASE

1番目のターゲットとは異なり、2番目のターゲットを認識していないようです。

編集

ついにこれが機能するようになりました。

1つの問題は、複数のディレクトリにsrcファイルがあり、VPATHを使用してこれを並べ替えることでした。

# specify dirs other then current dir to search for src files
VPATH = ../../pulse_IO/src ../../../g2/src

プラットフォームの条件付きのものに追加のライブラリターゲットを追加しました。

# Platform specific conditional compilation
UNAME := $(shell uname)

TARGET := Glam

ifeq ($(UNAME), Linux)
# LINUX version
program_NAME := lib$(TARGET).so
program_DEBUG_NAME := lib$(TARGET)_dbg.so
program_RELEASE_NAME := lib$(TARGET)_rel.so
BUILD_DIR = ../build/linux
endif

ifeq ($(UNAME), MINGW32_NT-6.1)
# WINDOWS version
program_NAME := lib$(TARGET).dll
program_DEBUG_NAME := lib$(TARGET)_dbg.dll
program_RELEASE_NAME := lib$(TARGET)_rel.dll
BUILD_DIR = ../build/windows
endif

新しいデバッグおよびリリースオブジェクトファイルを追加しました。

DEBUG_OBJS := $(addprefix $(BUILD_DIR)/debug/,${program_OBJS})
RELEASE_OBJS := $(addprefix $(BUILD_DIR)/release/,${program_OBJS})

デバッグを設定してCFLAGSをリリースします。

DEBUG_CFLAGS := -fPIC -g -Wall -DDEBUG=1
RELEASE_CFLAGS := -fPIC -O2 -Wall -DDEBUG=0

すべてのデバッグおよびリリースコンパイラオプションを照合しました。

DEBUG_LINK.c := $(CC) $(DEBUG_CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
RELEASE_LINK.c := $(CC) $(RELEASE_CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

新しいルールを「すべて」のターゲットに追加しました。

.PHONY: all clean

all: $(program_DEBUG_NAME) $(program_RELEASE_NAME)

ルールセットは次のようになります(暗黙的なオブジェクトファイル生成の置き換えを含む):

$(program_DEBUG_NAME): $(DEBUG_OBJS)
    $(DEBUG_LINK.c) -shared -Wl,-soname,$@ $^ -o $(BUILD_DIR)/debug/$@

$(program_RELEASE_NAME): $(RELEASE_OBJS)
    $(RELEASE_LINK.c) -shared -Wl,-soname,$@ $^ -o $(BUILD_DIR)/release/$@

# rule to build object files (replaces implicit rule)
$(BUILD_DIR)/debug/%.o: %.c
    $(DEBUG_LINK.c) $< -c -o $@

$(BUILD_DIR)/release/%.o: %.c
    $(RELEASE_LINK.c) $< -c -o $@

最後に、すべての新しいファイルを処理するようにクリーンに変更しました。

clean:
    @- $(RM) $(BUILD_DIR)/debug/$(program_DEBUG_NAME)
    @- $(RM) $(DEBUG_OBJS)
    @- $(RM) $(BUILD_DIR)/release/$(program_RELEASE_NAME)
    @- $(RM) $(RELEASE_OBJS)

これにより、単一のMakefileを使用してLinuxおよびWindowsプラットフォーム全体でライブラリのデバッグバージョンとリリースバージョンを作成できます。$ make -k

4

2 に答える 2

2

まず最初に。2つのライブラリに異なるバージョンのオブジェクトファイルが必要なようですが、このmakefileにはそれを提供するものはありません。

それを行うにはいくつかの方法があります。最もクリーンなのは、おそらく2つのディレクトリを持つことです。

debug_objs/
  ang.o
  naur.o
  gul.o

release_objs/
  ang.o
  naur.o
  gul.o

2番目にクリーンなのは、異なるファイル名を使用することです。

  ang_debug.o
  naur_debug.o
  gul_debug.o

  ang_rel.o
  naur_rel.o
  gul_rel.o

どちらの方法でも、RELEASE_OBJSとのルールを作成DEBUG_OBJSできます(必要に応じてサポートできます)。

次に、ライブラリのルールを見てください。

$(program_NAME_DEBUG): $(DEBUG_OBJS)
    $(LINK_DEBUG.c) -shared -Wl,-soname,$(program_NAME_DEBUG) $(DEBUG_OBJS) -o $(program_NAME_DEBUG)

$(program_NAME_RELEASE): $(RELEASE_OBJS)
    $(LINK_RELEASE.c) -shared -Wl,-soname,$(program_NAME_RELEASE) $(RELEASE_OBJS) -o $(program_NAME_RELEASE)

自動変数を使用して、より簡潔にすることができます。

$(program_NAME_DEBUG): $(DEBUG_OBJS)
    $(LINK_DEBUG.c) -shared -Wl,-soname,$@ $^ -o $@

$(program_NAME_RELEASE): $(RELEASE_OBJS)
    $(LINK_RELEASE.c) -shared -Wl,-soname,$@ $^ -o $@

(もう少し先に進むこともできますが、プッシュしないでください。)

今のためにall$(program_NAME_RELEASE)それが属する前提条件リストに移動します。

all: $(program_NAME_DEBUG) $(program_NAME_RELEASE)
    $(CP) $(program_NAME_DEBUG) $(BUILD_DIR)/debug/$(program_NAME_DEBUG)
    $(RM) $(program_NAME_DEBUG)
    $(RM) $(DEBUG_OBJS)
    $(CP) $(program_NAME_RELEASE) $(BUILD_DIR)/release/$(program_NAME_RELEASE)
    $(RM) $(program_NAME_RELEASE)
    $(RM) $(RELEASE_OBJS)

ただし、オブジェクトファイルは衝突できないため、削除する理由はありません。中間ファイルの場合は、Makeによってオブジェクトファイルが削除されます。そして、その必要はありませ$(CP)ん。そして、する必要はありません; それがライブラリが属する場所である場合、そもそもそこにライブラリを構築できます。$(RM)mvmv

all: $(program_NAME_DEBUG) $(program_NAME_RELEASE)

$(program_NAME_DEBUG): $(DEBUG_OBJS)
    $(LINK_DEBUG.c) -shared -Wl,-soname,$@ $^ -o $(BUILD_DIR)/debug/$@

$(program_NAME_RELEASE): $(RELEASE_OBJS)
    $(LINK_RELEASE.c) -shared -Wl,-soname,$@ $^ -o $(BUILD_DIR)/release/$@

編集:
オブジェクトファイルを作成するには(Cを使用していると思います):

OBJS:= ang.o naur.o gul.o
DEBUG_OBJS := $(addprefix debug_objs/,$(OBJS))
RELEASE_OBJS := $(addprefix release_objs/,$(OBJS))

debug_objs/%.o: $(SOURCE_DIR)/%.c
    $(CC) $(DEBUG_FLAGS) $< -o $@

release_objs/%.o: $(SOURCE_DIR)/%.c
    $(CC) $(RELEASE_FLAGS) $< -o $@

(これらのディレクトリが存在することを確認してください。自動化することもできますが、1日で十分な変更を加えることができます。)

于 2012-06-07T15:56:10.910 に答える
1

この変更はそれを行う必要があります:

all: $(program_NAME_DEBUG) $(program_NAME_RELEASE)

それ以外の場合は、make all作成に失敗し$(program_NAME_RELEASE)ます。これは、エラーメッセージが示していることです。

于 2012-06-07T09:29:40.290 に答える