[英]Generic makefile target for object files in multiple subdirectories
我有一个具有以下目录结构的项目:
Root directory
bin/ (for final executable)
Mod1/
build/ (for *.o / *.d files)
inc/
src/
Mod2/
build/
inc/
src/
Mod.../ (future module directories)
build/
inc/
src/
makefile
我当前的makefile包含:
# Directory naming conventions
SRC_DIR_NAME = src
BUILD_DIR_NAME = build
# Parallel source/object/dependency file lists
SRCS = $(shell find -name *.cpp)
OBJS = $(subst $(SRC_DIR_NAME),$(BUILD_DIR_NAME),$(SRCS:%.cpp=%.o))
# Final executable
APP = bin/app
build: $(APP)
$(APP): $(OBJS)
# link objects and compile app
%.o: %.cpp
# compile sources into objects
我的文件列表按预期工作并生成:
SRCS=./mod1/src/file.cpp ./mod2/src/file.cpp
OBJS=./mod1/build/file.o ./mod2/build/file.o
DEPS=./mod1/build/file.d ./mod2/build/file.d
但是,当我运行make时,我收到以下错误:
make: *** No rule to make target `mod1/build/file.o', needed by `/bin/app'. Stop.
我的假设是:
%.o: %.cpp
不适合像这样的输入
mod1/build/file.o
有没有办法制作一个通用目标,它接受一个模块目录,并为该模块的目标文件创建目标,这些目标文件需要该模块的源文件在各自的子目录中?
我知道使用递归make可以解决这个问题,但我希望尽可能避免使用该解决方案。
在GNU Make中无法表达如此复杂的目标。 虽然有一种方法可以生成目标集(和相应的规则)。 除了使用某种工具生成Makefile的明显方法之外,我们可以使用GNU Make的eval功能以编程方式创建规则。 示例代码如下。
# Directory naming conventions
SRC_DIR_NAME := src
BUILD_DIR_NAME := build
# source files list
SRCS := $(shell find -name '*.cpp')
# function to get obj file name from src file name
OBJ_FROM_SRC = $(subst /$(SRC_DIR_NAME)/,/$(BUILD_DIR_NAME)/,$(1:%.cpp=%.o))
# Final executable
APP := bin/app
.PHONY: build
.DEFAULT_GOAL := build
# rule template for obj
define obj_rule_by_src =
src := $(1)
obj := $$(call OBJ_FROM_SRC,$$(src))
OBJS := $$(OBJS) $$(obj)
$$(obj): $$(src)
# compile source into object
echo build $$@ from $$<
endef
# generate rules for OBJS
$(foreach src,$(SRCS),$(eval $(call obj_rule_by_src,$(src))))
$(APP): $(OBJS)
# link objects and compile app
echo create $@ from $^
build: $(APP)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.