我修改了我的方案的gcc/g++ option to place all object files into separate directory帖子。但是,运行make link
时返回错误。
项目树
|--- bin
| |--- main
|--- obj
| |--- object1.o
| |--- object2.o
| |--- ...
|--- src
| |--- source1.cpp
| |--- source2.cpp
| |--- ...
|--- main.cpp
生成文件
SRCDIR = ./src
OBJDIR = ./obj
BINDIR = ./bin
INCDIR = ./src
CC = g++
EXEC = main
SRC = $(wildcard $(SRCDIR)/*.cpp main.cpp)
OBJ = $(addprefix $(OBJDIR)/,$(notdir $(SRC:.cpp=.o)))
compile: $(OBJ)
$(OBJ): $(SRC)
$(CC) -c $< -o $@
link:
$(CC) -o $(EXEC) $(OBJ)
clean:
find -type f -name "$(EXEC)" -delete
find -type f -name "*.o" -delete
find -type f -name "*~" -delete
例如:
的main.cpp
#include <iostream>
#include "Source.h"
using namespace std;
int main(int argc, char* argv[]) {
Source::hello();
return 0;
}
Source.h
#include "Source.h"
#ifndef SOURCE_H
#define SOURCE_H
#include <iostream>
using namespace std;
class Source {
public:
static void hello();
};
#endif
Source.cpp
#include "Source.h"
void Source::hello() {
cout << "Hello Makefile" << endl;
}
make compile
好的!创建所有对象(obj / * .o)
问题:make link
Erro:
g++ -o main ./obj/Source.o ./obj/main.o
./obj/main.o: In function `Source::hello()':
Source.cpp:(.text+0x0): multiple definition of `Source::hello()'
我知道问题
g++ -c src/Source.cpp -o obj/Source.o
g++ -c src/Source.cpp -o obj/main.o.
我不知道如何解决。 知道什么可能是错的吗?
答案 0 :(得分:2)
它可能不是完美的解决方案,但这有效:
SRCDIR = ./src
OBJDIR = ./obj
BINDIR = ./bin
INCDIR = ./src
CC = g++
EXEC = main
SRC = $(wildcard $(SRCDIR)/*.cpp main.cpp)
OBJ = $(addprefix $(OBJDIR)/,$(notdir $(SRC:.cpp=.o)))
CXX_FLAGS = -I $(INCDIR) -Wall
.PHONY : compile
compile: $(OBJ)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -c $(CXX_FLAGS) $< -o $@
$(OBJDIR)/main.o: main.cpp
$(CC) -c $(CXX_FLAGS) $< -o $@
.PHONY : link
link: compile
$(CC) -o $(EXEC) $(OBJ)
.PHONY : clean
clean:
find -type f -name "$(EXEC)" -delete
find -type f -name "*.o" -delete
find -type f -name "*~" -delete
请注意,我已经制定了自动规则来编译所有SRCDIR
来源,然后是main
的特殊规则,因为main
不在同一目录中,所以第一条规则不起作用。
我还为.PHONY
,compile
和link
添加了clean
,因为这些不是“真正的目标”,它们只是用来告诉你想做什么的名字完成。没关系,直到某个时候你碰巧在目录中有一个名为compile
,link
或clean
的文件 - 此时你的makefile突然无法正常工作(例如,它没有“编译”,因为在你的目录中有一个名为compile的文件,compile
不依赖于任何其他内容,因此根据make没有任何事情要做。)
(为了我自己的利益,我还为compile
添加了link
的依赖关系,因此我不必输入make clean compile link
,而只能使用make clean link
)。
正如评论中所讨论的,问题是由$<
扩展为“规则中的第一个元素”引起的,它始终是srcdir/Source.cpp
,而不是“对应于目标文件的任何源。
我认为可以使用例如VPATH
或$(<F)
变量来做某事......但我现在无法弄明白。