嘿我正在尝试使用不同的后缀同时构建一些文件。不知何故,在一行中做这件事似乎是不可能的。我的makefile如下所示:
ARCH=ar
ARCHFLAGS=r
F90=gfortran
F90FLAGS=-O2 -Wall
LDFLAGS=-llapack -lblas
SRCF=/Users/pm/bin/src
OBJF=/Users/pm/bin/objs
MODF=/Users/pm/bin/mods
LIBF=/Users/pm/bin/include
SOURCES=a.f b.f90 c.f90
OBJECTS=$(addprefix $(OBJF)/,$(addsuffix .o,$(basename $(SOURCES))))
MODULES=$(addprefix $(MODF)/,*.mod)
TARGET=lib_pm_math_lib.a
$(LIBF)/$(TARGET): $(OBJECTS)
$(ARCH) $(ARCHFLAGS) $@ $(OBJECTS) $(MODULES)
obmod.clean :
rm $(OBJECTS) $(MODULES)
clean :
rm $(OBJECTS) $(MODULES) $(LIBF)/$(TARGET)
$(OBJECTS): $(OBJF)/%.o : $(addprefix $(SRCF)/,$(join %.,$(suffix $(SOURCES))))
$(F90) $(F90FLAGS) $(LDFLAGS) -c $< -o$@ -J$(MODF)
#$(OBJECTS): $(OBJF)/%.o : $(subst .x, ,$(addprefix $(SRCF)/,$(addsuffix .x$(suffix $(SOURCES)),%)))
# $(F90) $(F90FLAGS) $(LDFLAGS) -c $< -o$@ -J$(MODF)
#$(OBJECTS): $(OBJF)/%.o : $(SRCF)/%.f90
# $(F90) $(F90FLAGS) $(LDFLAGS) -c $< -o $@ -J$(MODF)
如您所见,我已经设法定义了我的OBJECTS。但是我无法为对象的构建部分创建一个相同的构造。当然我的第一次尝试是使用没有额外点的连接,但是由于任何原因,这只会产生后缀。用一个点代替两个点也可以。所以我迷路了。我命令的行是另一个有趣的尝试,只有.f90后缀的工作版本。实际上我希望像下面这样的东西能够起作用:
$(OBJECTS): $(OBJF)/%.o : $(SRCF)/%.*
$(F90) $(F90FLAGS) $(LDFLAGS) -c $< -o $@ -J$(MODF)
我希望它不会太乱。我发布了整个文件,因为我打赌你看到其他问题,我到目前为止还没有想到。提前谢谢!
答案 0 :(得分:1)
在这种情况下,我可能只使用两条规则:
$(OBJF)/%.o: $(SRCF)/%.f
$(F90) $(F90FLAGS) $(LDFLAGS) -c $< -o$@ -J$(MODF)
$(OBJF)/%.o: $(SRCF)/%.f90
$(F90) $(F90FLAGS) $(LDFLAGS) -c $< -o$@ -J$(MODF)
你可以将它们组合成一个,但这并不值得付出努力。
答案 1 :(得分:1)
如果我正确理解你,你需要一个基于后缀的通配符规则,你可以在多个文件后缀上运行。每个食谱只能有一个通配符,所以没有办法直接进行。每个后缀都需要单独的规则。
简单的解决方案是复制粘贴一个规则并更改后缀。当你开始有很多后缀时,这可能变得无法管理。另一个选项是创建规则模板并使用它为您动态生成规则:
# Template for build rules
# Pass a file extension for an argument
define build_rule
$(OBJF)/%.o: $(SRCF)/%.$(1)
$(F90) $(F90FLAGS) $(LDFLAGS) -c $$< -o$$@ -J$(MODF)
endef
# Generate rules for each selected file extension
FILE_EXTS = f f90
$(foreach ext,$(FILE_EXTS),$(eval $(call build_rule,$(ext))))
这将动态生成一个规则,该规则仅与输入文件中使用的文件扩展名不同。要支持新的文件扩展名,只需将其添加到FILE_EXTS
列表。
请注意,当make最初解析配方模板(在call
内)时,它会扩展变量。您必须将模板中的$
翻倍,以便在实际执行配方(例如$@
或$<
)之前,不要进行扩展。
您不需要做任何特别的事情来确保只编译OBJECTS
列表中的对象。由于您的默认make target仅列出$(OBJECTS)
作为依赖项,因此$(OBJECTS)
中的文件将是唯一构建的文件。