具有多个目录和依赖项的Makefile

时间:2016-02-08 22:28:55

标签: makefile g++

``我是Makefile的新手,我正在尝试构建一个项目。 这是我项目的结构:

-Project
|-generic
|  |-include
|  |-src
|-specific
|  |-include
|  |-src
|-Makefile
|-bin    

这里泛型主要包含接口类(虚拟),具体的文件可能依赖于那些。 我想编译所有源代码并将相应的.o文件放在bin中,并在bin中创建一个静态库。

修改

CC=k1-g++
CPPFLAGS=-c -I$(GENERIC_INCLUDE_DIR) -I$(SPECIFIC_INCLUDE_DIR) -Os -std=gnu++11 -mos=nodeos 
CXXFLAGS=-c -I$(GENERIC_INCLUDE_DIR) -I$(SPECIFIC_INCLUDE_DIR) -Os -std=gnu++11 -mos=nodeos 
LFLAGS=-pthread -lnodeos  

GENERIC_INCLUDE_DIR=generic/include
SPECIFIC_INCLUDE_DIR=specific/include
GENERIC_SRC_DIR=generic/src
SPECIFIC_SRC_DIR=specific/src


LIB = libengine.a
BIN_DIR=bin

vpath %.cpp $(GENERIC_SRC_DIR) $(SPECIFIC_SRC_DIR)
SOURCES := $(wildcard $(GENERIC_SRC_DIR)/*.cpp $(SPECIFIC_SRC_DIR)/*.cpp)
#SOURCES := $(wildcard $(GENERIC_SRC_DIR)/*.cpp $(SPECIFIC_SRC_DIR)/*.cpp)
SOURCES := $(notdir $(SOURCES))
OBJECTS := $(patsubst %.cpp,$(BIN_DIR)/%.cpp.o,$(SOURCES))



all: $(OBJECTS) $(LIB)

$(LIB): $(OBJECTS)
    ar -cvq $(BIN_DIR)/$@ $^

#$(BIN_DIR)/%.cpp.o: $(GENERIC_SRC_DIR)/%.cpp
#   $(CC) $(CPPFLAGS) $< $(LFLAGS) -o $@

$(BIN_DIR)/%.cpp.o: %.cpp
    $(CC) $(CPPFLAGS) $< $(LFLAGS) -o $@




.PHONY: clean

clean:
    rm -f $(BIN_DIR)/* 

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

假设您有generic/src/foo.cppspecific.src/bar.cpp

此:

$(BIN_DIR)/%.o: %.cpp
    $(CC) $(CPPFLAGS) $*.cpp -o $@

与您的需求非常接近(我已将$(BIN_DIR)/$*.o $@替换为obj/foo.o foo.cpp,其扩展为目标名称);唯一的问题是它不起作用。此规则告诉Make it可以从foo.cpp构建generic/src/foo.cpp,但没有$(BIN_DIR)/%.o: $(GENERIC_SRC_DIR)/%.cpp $(CC) $(CPPFLAGS) $*.cpp -o $@ 。有一个vpath %.cpp $(GENERIC_SRC_DIR) $(SPECIFIC_SRC_DIR) $(BIN_DIR)/%.o: %.cpp $(CC) $(CPPFLAGS) $*.cpp -o $@ ,但Make并不知道那是你的意思。我们可以写一个这样的规则:

SOURCES := $(wildcard $(GENERIC_SRC_DIR)/*.cpp $(SPECIFIC_SRC_DIR)/*.cpp)
SOURCES := $(notdir $(SOURCES))
OBJECTS := $(patsubst %.cpp,%.o, $(SOURCES))
# We could have done that all in one line, but this way is easier to read.

all: $(OBJECTS)

但更简洁的方法是使用automatic variable

vpath %.o $(BIN_DIR)

$(BIN_DIR)/$(LIB): $(OBJECTS)
    ar -cvq $@ $^

这对于构建任何一个目标文件都很有用,但是你说要编译&#34;所有来源&#34;。这不是一个好主意,但是如果这就是你想要的并不困难,我们使用the vpath directive来获取所有源的列表,然后将其转换为相应的目标文件列表,然后构建它们: / p>

{{1}}

现在为图书馆:

{{1}}

可以进行进一步的改进,但这应该会保持一段时间。