web-dev-qa-db-ja.com

makeを使用して特定のディレクトリにオブジェクトファイルを作成する

_GNU Make 3.82
gcc 4.7.2
c89
_

次のメイクファイルがあります。

_INC_PATH=-I/home/dev_tools/apr/include/apr-1
LIB_PATH=-L/home/dev_tools/apr/lib
LIBS=-lapr-1 -laprutil-1
RUNTIME_PATH=-Wl,-rpath,/home/dev_tools/apr/lib
CC=gcc
CFLAGS=-Wall -Wextra -g -m32 -O2 -D_DEBUG -D_THREAD_SAFE -D_REENTRANT -D_LARGEFILE64_SOURCE $(INC_PATH)
SOURCES=$(wildcard src/*.c)
OBJECTS=$(patsubst %.c, %.o, $(SOURCES))

EXECUTABLE=bin/to

all:    build $(EXECUTABLE)

$(EXECUTABLE):  $(OBJECTS)
    $(CC) $(CFLAGS) -o $@ $(RUNTIME_PATH) $(OBJECTS) $(LIB_PATH) $(LIBS)

$(OBJECTS): $(SOURCES)
    $(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS)

build:
    @mkdir -p bin

clean:
    rm -rf $(EXECUTABLE) $(OBJECTS) bin
    find . -name "*~" -exec rm {} \;
    find . -name "*.o" -exec rm {} \;
_

私のディレクトリ構造はこのような_project/src project/bin_です。 Makefileはproject (root)フォルダーにあり、*。hおよび* .cはすべてsrcディレクトリーにあります。現在、timeout.cというソースファイルが1つしかありません。

私はこのエラーを受け取ります:

_gcc: error: src/timeout.o: No such file or directory
_

これを使用して、すべてのソースファイルを取得しました。

_SOURCES=$(wildcard src/*.c)
_

そして、オブジェクトファイル:

_OBJECTS=$(patsubst %.c, %.o, $(SOURCES))
_

ただし、makeはMakefileがあるプロジェクトルートフォルダーにオブジェクトファイルを作成するようです。 srcディレクトリに入れてはいけませんか?

22
ant2009

このルールには2つの問題があります(3つ)。

$(OBJECTS): $(SOURCES)
    $(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS)

まだ気付いていませんが、ルールはeachオブジェクトをallソース、およびそのように構築しようとします。ソースが1つだけであれば問題ありません。 静的パターンルール および 自動変数 で簡単に修正できます。

$(OBJECTS): src/%.o : src/%.c
    $(CC) $(CFLAGS) -c $< $(LIB_PATH) $(LIBS)

また、コマンド( "$(CC)...")は出力ファイル名を指定しないため、gccはソースファイル名から推測します。 src/timeout.cを指定すると、timeout.o(作業ディレクトリのproject/)が生成されます。そのため、出力ファイルへの目的のパスを指定する必要があります。別の自動変数で簡単に実行できます。

$(OBJECTS): src/%.o : src/%.c
    $(CC) $(CFLAGS) -c $< $(LIB_PATH) $(LIBS) -o $@
18
Beta

gccの-​​-oオプションを使用して、出力ファイルを特定の場所に書き込みます。たとえば、あなたは言うことができます:

_$(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS) -o $(OBJECTS)
_

残念ながら、この行には問題があります。$(SOURCES)に複数のソースファイルがある場合、$(OBJECTS)にも複数のファイル名が含まれるため、動作しません。 -oオプションは、最初の引数にのみバインドします。

ソースコードファイルのリスト内の各ファイルをコンパイルする方法は、暗黙のルールを使用することです。 gmakeには、次のように記述します。

_$(EXECUTABLE):  $(OBJECTS)
        $(CC) $(CFLAGS) -o $@ $(RUNTIME_PATH) $(OBJECTS) $(LIB_PATH) $(LIBS)

%.o : %.c
        $(CC) $(CFLAGS) -c $< -o $@
_

$ <は入力ファイルの名前に置き換えられ、$ @は出力ファイルの名前に置き換えられます。

5
radical7