所以,首先,我想明确表示我没有使用Make及其Makefiles的经验。话虽这么说,我已经尝试在互联网上找到关于通配符和递归技术来编译和链接我的项目。直到我在这个站点上发现了一个使用make的模块化类型系统的线程。
我想首先告诉大家我的项目是如何构建的:
.
|---- Makefile
|
|---- build/
| |---- bin/
| |
| |____ obj/
|
|---- includes/
| |
| |____ graphics/
| |____ vga.h
|
|---- libs/
| |____ linker.ld
|
|____ src/
|---- module.mk
|
|---- asm/
| |---- asm_module.mk
| |____ boot.s
|
|____ cpp/
|---- cpp_module.mk
|---- main/
| |---- main_module.mk
| |____ main.cpp
|
|____ graphics/
|---- graphics_module.mk
|____ vga.cpp
所以现在你知道了。我制作了以下Makefile和module.mk来尝试制作项目:
生成文件:
PROJECT := GOODY
CXX := i686-elf-g++
LD := i686-elf-ld
AS := nasm
SRC_DIR := src
BUILD_DIR := build
OBJ_DIR := $(BUILD_DIR)/obj
BIN_DIR := $(BUILD_DIR)/bin
CXX_SRCS :=
ASM_SRCS :=
SUBDIRS :=
CXXFLAGS :=
LDFLAGS :=
include $(SRC_DIR)/module.mk
CXX_OBJS := $(addprefix $(OBJ_DIR)/, $(CXX_SRCS:.cpp=.o))
ASM_OBJS := $(addprefix $(OBJ_DIR)/, $(ASM_SRCS:.s=.o))
OBJS := $(CXX_OBJS) $(ASM_OBJS)
DEPS := $(OBJS:.o=.d)
TMPS := $(OBJS) $(OBJS:.o=.d)
CXXFLAGS := -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector \
-fno-rtti -O2 -Wall -Werror -fno-exceptions -ffreestanding \
-m32 -Iincludes
LDFLAGS := -Tlibs/linker.ld -melf_i386 --oformat=elf32-i386
ASFLAGS := -felf
all: $(BIN_DIR)/$(PROJECT)
$(OBJ_DIR)/%.o, $(SRC_DIR)/%.cpp
@echo "\tCompiling [$@]"
$(CXX) $(CXXFLAGS) $< -o $@
$(OBJ_DIR)/%.o, $(SRC_DIR)/%.s
@echo "\tCompiling [$@]"
$(AS) $(ASFLAGS) $< -o $@
$(BIN_DIR)/$(PROJECT): $(OBJS)
@echo "\tLinking Kernel..."
@$(LD) $(OBJS) -o $(PROJECT) $(LDFLAGS)
$(OBJS): | $(OBJ_DIR)
$(OBJ_DIR):
@mkdir -p $(OBJ_DIR)
@for dir in $(SUBDIRS); \
do \
mkdir -p $(OBJ_DIR)/$$dir; \
done
clean:
rm -rf $(TMPS)
rm -rf $(BIN_DIR)/$(PROJECT)
rm -rf $(OBJ_DIR)
.PHONY: clean
module.mk:
SUBDIRS += asm cpp
include $(SRC_DIR)/asm/asm_module.mk
include $(SRC_DIR)/cpp/cpp_module.mk
asm_module.mk:
UP_DIR := asm
MOD_SRCS := boot.s
ASM_SRCS := $(addprefix $(UP_DIR)/, $(MOD_SRCS))
cpp_module.mk:
SUBDIRS := main graphics
include $(SRC_DIR)/cpp/main/main_module.mk
include $(SRC_DIR)/cpp/graphics/graphics_module.mk
main_module.mk:
UP_DIR := main
MOD_SRCS := main.cpp
CXX_SRCS := $(addprefix $(UP_DIR)/, $(MOD_SRCS))
graphics_module.mk:
UP_DIR := graphics
MOD_SRCS := vga.cpp
CXX_SRCS := $(addprefix $(UP_DIR)/, $(MOD_SRCS))
现在我来自make的错误。它如下:
$ make
Linking Kernel...
i686-elf-ld: cannot find build/obj/graphics/vga.o: No such file or directory
i686-elf-ld: cannot find build/obj/asm/boot.o: No such file or directory
Makefile:49: recipe for target 'build/bin/GOODY' failed
make: *** [build/bin/GOODY] Error 1
现在我可以看出,ld找不到.o文件......在查看build / obj目录后,那里什么也没有。
我的问题是,我做错了什么?
编辑:= 所以看起来它实际上根本没有编译* .cpp或* .s文件,它只是直接跳到链接阶段,显然没有找到任何可以链接的内容。
所以猜测它也可能与之相关:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) $< -o $@
我也尝试过原始帖子建议的内容:
$(COMPILE.cpp) $(OUTPUT_OPTION) $< # Also $(COMPILE.c) too.
答案 0 :(得分:1)
因此,在我的笔记本电脑停留了一段时间之后,我又回到了它,并意识到我后来做了一些错误。
我需要让* .mk文件改为:
module.mk:
DIR_SRC := src
SUBDIRS := cpp asm
include $(DIR_SRC)/cpp/cpp_module.mk
include $(DIR_SRC)/asm/asm_module.mk
cpp_module.mk:
DIR_CPP := cpp
SUBDIRS := main graphics
include $(SRC_DIR)/$(DIR_CPP)/main/main_module.mk
include $(SRC_DIR)/$(DIR_CPP)/graphics/graphics_module.mk
main.module.mk :(注意:这与graphics_module.mk几乎相同)
DIR_MAIN := main
MOD_SRCS := main.cpp
CXX_SRCS := $(addprefix $(DIR_CPP)/$(DIR_MAIN)/, $(MOD_SRCS))
这解决了我的问题。