2016-03-24 3 views
1

Я пытаюсь создать Makefile для проекта со следующей структурой:файлов Создание зависимостей в отдельной папке

├──bin/ 
├──build/ 
│ ├──foo.d 
│ └──bar.d 
├──include/ 
│ └──foo.h 
│ 
├──lib/ 
├──src/ 
│ ├──foo.cc 
│ └──bar.cc 
│ 
├──Makefile 

Вот Makefile:

# Define the compiler and the linker. 
CXX = g++ 
CC = g++ 
# Folders 
srcdir = src 
builddir = build 
out  = bin 

# Define preprocessor, compiler, and linker flags. 
CPPFLAGS = -I include -std=c++11 
LDFLAGS = -g -Llib 

# Phony targets 
.PHONY: all clean test 

# Targets 
all : $(out)/bar 
$(out)/bar : $(addprefix $(builddir)/,bar.o foo.o) 

# Standard clean 
clean : 
    rm -f $(builddir)/*.o $(builddir)/*.d 

# Generate dependencies in *.d files 
$(builddir)/%.d: $(srcdir)/%.cc 
    @set -e; rm -f [email protected]; \ 
    $(CPP) -MM $(CPPFLAGS) $< > [email protected]$$$$; \ 
    sed 's,\($*\)\.o[ :]*,$(builddir)/\1.o [email protected] : ,g' < [email protected]$$$$ > [email protected]; \ 
    rm -f [email protected]$$$$; 

deps = $(patsubst $(srcdir)/%.cc,$(builddir)/%.d,$(wildcard $(srcdir)/*.cc)) 
include $(deps) 

Файлы зависимостей содержат следующее:

foo.d

build/foo.o build/foo.d : src/foo.cc include/foo.h 

bar.d (зависит от Foo)

build/bar.o build/bar.d : src/bar.cc include/foo.h 

Есть ли способ, чтобы генерировать .D файлов в каталоге/сборки, компиляции объектных файлов в ту же папку, а затем скомпилировать программу бен/бара? Любая помощь оценивается.

EDIT:

Проблема, что я ожидал

all : $(out)/foo 

$(out)/foo : $(addprefix $(builddir)/,foo.o bar.o) 

$(builddir)/%.o : $(srcdir)/%.cc 
    $(CXX) -c $< -o [email protected] -MP -MMD -MF $(@:.o=.d) 

волшебно скомпилировать программу Foo (она работает, когда все файлы находятся в одной и той же папке).

Вместо этого я должен был указать рецепт:

all : $(out)/foo 

$(out)/foo : $(builddir)/foo.o $(builddir)/bar.o 
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o [email protected] 

$(builddir)/%.o : $(srcdir)/%.cc 
    $(CXX) -c $< -o [email protected] -MP -MMD -MF $(@:.o=.d) 
+0

Обратите внимание, что правила зависимостей являются удобством для разработчиков проектов, а не фактическим требованием к сборке. Если вы просто хотите как можно быстрее перейти от простого дистрибутива источника к двоичному файлу, а затем не создавать правила зависимостей. В этих обстоятельствах вы знаете, что вам все равно нужно строить все. –

+0

В отношении поставленного вопроса, однако, мне непонятно, что вы спрашиваете. Как сгенерировать файлы '.d' в каталоге' build', а не в другом месте? Как написать правила make, которые позволят запускать все описанные вами шаги одним запуском? Что-то другое? –

+0

Я уточнил вопрос для ясности. Фактический проект, в котором я пытаюсь написать makefile, содержит множество файлов. Файл makefile при использовании одной папки был действительно чистым и эффективным. Я просто пытаюсь сохранить автоматическую генерацию зависимостей во время миграции на достойную структуру папок проекта. –

ответ

2

отбросить все sed нонсенс. GCC может генерировать все в одном дыхании:

$(builddir)/%.o : $(srcdir)/%.cc 
    $(CPP) -c $< -o [email protected] -MP -MMD -MF $(@:.o=.d) 

Это будет в один присест строить build/foo.o и build/foo.d, где build/foo.d будет иметь автогенерируемые зависимости для build/foo.o.

+0

По какой-то причине это дает мне 'foo.o: файл не распознан: формат файла не распознан collect2: ошибка: ld возвращен 1 статус выхода' –

+0

@SebastianN в каком контексте? – Barry

+0

Я ошибался, когда думал, что моя проблема связана с генерацией зависимостей, это была просто ошибка новичков, когда дело доходило до определения рецептов.Ошибка, о которой я рассказывал выше, заключалась в том, что я использовал '$ (CPP)' вместо '$ (CXX)' в своем рецепте. Благодарим вас за предоставление этой более чистой версии поколения зависимостей, чем на основе sed, предложенной моим профессором. –

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