具有多个目录和依赖项的 Makefile
Makefile with multiple directories and dependencies
``我是 Makefile 的新手,我正在尝试构建一个项目。
这是我项目的结构:
-Project
|-generic
| |-include
| |-src
|-specific
| |-include
| |-src
|-Makefile
|-bin
这里generic主要是接口类(virtual),具体的文件可能要看这些了。
我想编译所有源并将它们对应的 .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)/*
如有任何帮助,我们将不胜感激
假设您有 generic/src/foo.cpp
和 specific.src/bar.cpp
。
这个:
$(BIN_DIR)/%.o: %.cpp
$(CC) $(CPPFLAGS) $*.cpp -o $@
非常接近您的需要(我已将 $(BIN_DIR)/$*.o
替换为 automatic variable $@
,它扩展为目标的名称);唯一的问题是它不起作用。这条规则告诉 Make 它可以从 foo.cpp
构建 obj/foo.o
,但是没有 foo.cpp
。有一个 generic/src/foo.cpp
,但 Make 不知道那是你的意思。我们可以这样写一个规则:
$(BIN_DIR)/%.o: $(GENERIC_SRC_DIR)/%.cpp
$(CC) $(CPPFLAGS) $*.cpp -o $@
但更简洁的方法是使用 the vpath directive:
vpath %.cpp $(GENERIC_SRC_DIR) $(SPECIFIC_SRC_DIR)
$(BIN_DIR)/%.o: %.cpp
$(CC) $(CPPFLAGS) $*.cpp -o $@
这对于构建任何一个目标文件都很好,但是你说你想编译 "all sources"。 这并不总是一个好主意,但是如果这就是你想要的 这并不难,我们使用 wildcard
获取所有源的列表,然后将其转换为相应目标文件的列表,然后全部构建它们:
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)
图书馆现在:
vpath %.o $(BIN_DIR)
$(BIN_DIR)/$(LIB): $(OBJECTS)
ar -cvq $@ $^
可以进一步改进,但这应该会持续一段时间。
``我是 Makefile 的新手,我正在尝试构建一个项目。 这是我项目的结构:
-Project
|-generic
| |-include
| |-src
|-specific
| |-include
| |-src
|-Makefile
|-bin
这里generic主要是接口类(virtual),具体的文件可能要看这些了。 我想编译所有源并将它们对应的 .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)/*
如有任何帮助,我们将不胜感激
假设您有 generic/src/foo.cpp
和 specific.src/bar.cpp
。
这个:
$(BIN_DIR)/%.o: %.cpp
$(CC) $(CPPFLAGS) $*.cpp -o $@
非常接近您的需要(我已将 $(BIN_DIR)/$*.o
替换为 automatic variable $@
,它扩展为目标的名称);唯一的问题是它不起作用。这条规则告诉 Make 它可以从 foo.cpp
构建 obj/foo.o
,但是没有 foo.cpp
。有一个 generic/src/foo.cpp
,但 Make 不知道那是你的意思。我们可以这样写一个规则:
$(BIN_DIR)/%.o: $(GENERIC_SRC_DIR)/%.cpp
$(CC) $(CPPFLAGS) $*.cpp -o $@
但更简洁的方法是使用 the vpath directive:
vpath %.cpp $(GENERIC_SRC_DIR) $(SPECIFIC_SRC_DIR)
$(BIN_DIR)/%.o: %.cpp
$(CC) $(CPPFLAGS) $*.cpp -o $@
这对于构建任何一个目标文件都很好,但是你说你想编译 "all sources"。 这并不总是一个好主意,但是如果这就是你想要的 这并不难,我们使用 wildcard
获取所有源的列表,然后将其转换为相应目标文件的列表,然后全部构建它们:
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)
图书馆现在:
vpath %.o $(BIN_DIR)
$(BIN_DIR)/$(LIB): $(OBJECTS)
ar -cvq $@ $^
可以进一步改进,但这应该会持续一段时间。