2013-09-14 2 views
1

Я изменил проводку gcc/g++ option to place all object files into separate directory для своего сценария. Однако возвращает ошибку при запуске make link.Makefile при srcdir! = Objdir

Project Tree

|--- bin 
| |--- main 
|--- obj 
| |--- object1.o 
| |--- object2.o 
| |--- ... 
|--- src 
| |--- source1.cpp 
| |--- source2.cpp 
| |--- ... 
|--- main.cpp 

Makefile

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 [email protected] 

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 ок! Создание всех объектов (объект/* о.)

Проблема: 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.

я не знаю, как решить , Любая идея, что может быть неправильным?

+1

Когда вы связываете, компоновщик должен найти все ссылки. Кажется, что не найти функцию 'Classes :: functions()', которая, вероятно, не является проблемой в вашем make-файле, но в исходном файле, который содержит (или ДОЛЖЕН содержать) 'Classes :: functions()' - очевидно, не видя ваш исходный код, почти невозможно точно сказать, что здесь не так. –

+0

Включил мой код в сообщение –

+0

'Source.h', вероятно, не должен иметь' #include "Source.h" 'в нем ... –

ответ

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 [email protected] 

$(OBJDIR)/main.o: main.cpp 
    $(CC) -c $(CXX_FLAGS) $< -o [email protected] 

.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 не зависит от чего-либо еще, поэтому делать нечего по make).

(для моей пользы, я также добавил зависимость для compile к link, поэтому я не придется вводить make clean compile link, но может использовать только make clean link).

Как обсуждалось в комментариях, проблема вызвана тем, что $< расширяется до «первого элемента в правиле», который всегда равен srcdir/Source.cpp, а не «независимо от источника, соответствующего объекту.

Я думаю, что можно было что-то использовать, например, VPATH или, может быть, $(<F) переменных ... Но я не могу понять, как сейчас.

+0

Отличный ответ, спасибо. –

Смежные вопросы