4956
`make`において、以下の構成でプロジェクトを作成したいのですが、objディレクトリにオブジェクトファイルを格納するような`Makefile`はどのように作れば良いでしょうか。

**環境構成**

```

    ./
      ├ bin/     # 実行ファイル用ディレクトリ
      ├ include/ # インクルードファイル用ディレクトリ
      │  └ Util.h
      ├ obj/     # オブジェクトファイル用ディレクトリ
      ├ src/     # ソースコード用ディレクトリ
      │  ├ main.cxx
      │  └ Util.cxx
      └ Makefile
    
```

一応以下のやり方で実行ファイルの生成は出来ましたが、カレントディレクトリにオブジェクトファイルができてしまい、所望の動作ではないです。  
(中途半端な変数化はスルーしてください･･･)

```

    TARGET=./bin/test
    SOURCES=$(wildcard src/*.cxx)
    OBJECTS=$(notdir $(SOURCES:.cxx=.o))
    VPATH=src
    
    .SUFFIXES: .cxx .o
    
    $(TARGET): $(OBJECTS)
        rm -f $@
        g++ -Wall -I./include -o $@ $^
    
    .cxx.o:
        g++ -Wall -I./include -c $<
    
    .PHONY: all clean
    all:
        echo $(SOURCES)
        echo $(OBJECTS)
    clean:
        rm -f *.o bin/*
    
```

オブジェクトファイルをobjディレクトリに格納するため、以下のようにしましたが、`make`時にエラーになってしまいます(`-c
$<`が常に`Util.cxx`を指してしまう)。

```

    TARGET=./bin/test
    SOURCES=$(wildcard src/*.cxx)
    OBJECTS=$(patsubst src/%.cxx, obj/%.o, $(SOURCES))
    
    $(TARGET): $(OBJECTS)
        rm -f $@
        g++ -Wall -I./include -o $@ $^
    
    $(OBJECTS): $(SOURCES)
        g++ -Wall -I./include -o $@ -c $<
    
    .PHONY: all clean
    all:
        echo $(SOURCES)
        echo $(OBJECTS)
    clean:
        rm -f bin/* obj/*
    
```

**実行結果**

```

    $ make
    g++ -Wall -I./include -o obj/Util.o -c src/Util.cxx
    g++ -Wall -I./include -o obj/main.o -c src/Util.cxx # ここがNG。src/main.cxxになって欲しい
    
```

**環境**  
`GNU Make 3.81`
CC BY-SA 3.0
2015-01-21T03:25:02.153
4946
2015-02-09T00:12:01.007
2015-02-09T00:12:01.007
7214
7214
question
c++ makefile
Makefile : カレントディレクトリ以外にオブジェクトファイルを生成したい
書いておられる Makefile の

```

    $(OBJECTS) : $(SOURCES)
    
```

は `$(SOURCES)` から1回のアクションで `$(OBJECTS)` を出力するという意味になります。gcc
コマンドの出力は1つですので出来ませんよね。(Makefile の $@ は出力先リストから1つしか取り出されません)  
そこで以下の様に `%` を用いた指定を使います。

```

    TARGET=./bin/test
    SOURCES=$(wildcard src/*.cxx)
    OBJECTS=$(addprefix obj/,$(notdir $(SOURCES:.cxx=.o)))
    
    $(TARGET): $(OBJECTS)
        rm -f $@
        g++ -Wall -I./include -o $@ $^
    
    obj/%.o : src/%.cxx
        g++ -Wall -I./include -o $@ -c $<
    
    .PHONY: all clean
    all:
        echo $(SOURCES)
        echo $(OBJECTS)
    clean:
        rm -f bin/* obj/*
    
```

必要に応じて `.SUFFIXES: .o .cxx` を追加して下さい。
CC BY-SA 3.0
2015-01-21T04:21:30.247
4956
2015-01-21T04:21:30.247
440
4946
answer