如何创建makefile指定对象和可执行文件的ifferent目录

时间:2016-03-03 14:41:14

标签: c++ makefile

    --folder
    ----book.h
    ----book.cpp
    ----library.h
    ----library.cpp
    ----main.cpp

这是目录结构,我创建了这个make文件,它在同一目录中生成目标文件和可执行文件。

    main : main.o book.o library.o
        g++ main.o book.o library.o -o main

    main.o : main.cpp book.h library.h
        g++ -c main.cpp

    library.o : library.cpp library.h book.h
        g++ -c library.cpp

    book.o : book.cpp book.h 
        g++ -c book.cpp

    clean:
        rm -f *.o main

但我想分别为文件夹中的目标文件和可执行文件创建文件夹obj和bin。我该怎么做?

3 个答案:

答案 0 :(得分:2)

也许是这样的

TARGET  = bin/main
SOURCES = main.cpp book.cpp library.cpp
OBJ_DIR = obj

OBJECTS = $(SOURCES:%.cpp=$(OBJ_DIR)/*.o)

$(TARGET): $(OBJECTS)
    $(LD) $(LDFLAGS) $^ -o $@ $(LIBS)

$(OBJ_DIR)/%.o: %.cpp
    $(CXX) $(CXXFLAGS) $< -c -o $@

这要求首先存在binobj目录。

阅读the GNU Make manual了解详情。

我有一段时间,所以我为你编写了一个完整的自动化Makefile。如果目录不存在,这将创建目录。

BINDIR  = bin/
OBJDIR  = obj/

TARGET  = $(BINDIR)target
SOURCES = main.cpp book.cpp library.cpp

LD      = g++

OBJECTS = $(SOURCES:%.cpp=$(OBJDIR)%.o)

.PHONY: all
all: target

.PHONY: target
target: before_target actual_target after_target

.PHONY: before_target
before_target: $(OBJDIR) $(BINDIR)

.PHONY: actual_target
actual_target: $(TARGET)

.PHONY: after_target
after_target:

$(TARGET): $(OBJECTS)
    $(LD) $(LDFLAGS) $^ -o $@ $(LIBS)

$(OBJDIR)%.o: %.cpp
    $(CXX) $(CXXFLAGS) $^ -c -o $@

$(OBJDIR) $(BINDIR):
    mkdir $@

.PHONY: clean
clean:
    -rm -rf $(BINDIR)
    -rm -rf $(OBJDIR)

答案 1 :(得分:1)

使用VPATH!这篇文章做了一个很好的(和详细的)工作,向您展示如何:Multi-Architecture Builds

这是基本理论:

首先,将有一个级别的递归。这将自动cd处理obj ect目录,而不是出于任何目录层次结构原因。

其次,您将使用VPATH指定源代码相对于对象目录的位置:VPATH=../src

第三......嗯......获利!

这是一个简化的例子(未经测试)。你可以扩展这个,或者跟随文章来获得一个更丰富的&#34;版本:

ifneq (obj,$(notdir $(CURDIR)))
    # Not in object directory, so we must be in root (src) directory!

    .SUFFIXES:

    OBJDIR := obj

    MAKETARGET = $(MAKE) --no-print-directory -C $@ -f $(CURDIR)/Makefile \
             SRCDIR=$(CURDIR) $(MAKECMDGOALS)

    .PHONY: $(OBJDIR)
    $(OBJDIR):
        ;+@[ -d $@ ] || mkdir -p $@
        +@$(MAKETARGET)

    Makefile : ;
    %.mk :: ;

    % :: $(OBJDIR) ; :

    .PHONY: clean
    clean:
        rm -rf $(OBJDIR)
else
    VPATH=../src
    CXX := g++  # The default, just so you know it's here

    # CXXFLAGS = ...
    # LDFLAGS = ...
    # LDLIBS = ...

    main : main.o book.o library.o

    main.o : main.cpp book.h library.h

    library.o : library.cpp library.h book.h

    book.o : book.cpp book.h 

endif

答案 2 :(得分:1)

您可以使用obj/为您的对象添加前缀,使用bin/添加可执行文件,并添加命令以生成目录mkdir -p bin等。

# make your subfolders targets
all: bin obj bin/main

bin/main : obj/main.o obj/book.o obj/library.o
    g++ -o bin/main obj/main.o obj/book.o obj/library.o

obj/main.o : main.cpp book.h library.h
    g++ -c -o obj/main.o main.cpp

obj/library.o : library.cpp library.h book.h
    g++ -c -o obj/library.o library.cpp

obj/book.o : book.cpp book.h 
    g++ -c -o obj/book.o book.cpp

# create subfolders if not present
bin obj:
    mkdir -p bin
    mkdir -p obj

clean:
    rm -f bin/* obj/*

然后输入make(制作targer all)。