如何使用带有 gprof 的 makefile 重新编译依赖项?
Posted
技术标签:
【中文标题】如何使用带有 gprof 的 makefile 重新编译依赖项?【英文标题】:How to use a makefile with gprof to recompile dependencies? 【发布时间】:2020-07-01 18:31:06 【问题描述】:我有一个编译文件并将对象链接在一起以创建可执行文件。为了进行分析,我需要在编译之前使用一个附加标志-pg
。这是我当前的makefile:
# objects required
OBJS = obj1.o obj2.o
# flags
FC = gfortran
FLAGS = -O3
PROFILEFLAG = -pg
# executable
EXE = program.exe
PROFEXE = program_prof.exe
# suffixes
.SUFFIXES: .o .f90
# rules
%.o: %.f90
$(FC) $(FLAGS) -c $<
default: $(OBJS)
$(FC) $(FLAGS) $(OBJS) -o $(EXE)
profile: $(OBJS)
$(FC) $(FLAGS) $(OBJS) -o $(PROFEXE) $(PROFILEFLAG)
clean:
rm *.o *.mod
运行make profile
运行与配置文件关联的规则,该规则创建可执行文件program_prof.exe
,可以对其进行配置文件。但是,由于单独的依赖项 obj1
和 obj2
未使用 -pg
标志编译,因此我无法分析在这些文件中运行的代码。
有没有一种方法可以添加规则,以便在需要分析时也使用 -pg
标志重新编译各个对象?
目前我正在手动编辑单个对象依赖项:
%.o: %.f90
$(FC) $(FLAGS) -c $< -pg
按预期工作,但很耗时(我的实际 makefile 在子文件夹中有多个依赖项,所有这些都需要编辑)。理想情况下,我正在寻找一个规则,它应该使用 `-pg' 标志重新编译单个对象。
【问题讨论】:
当我遇到这个问题时,我一直使用你的“手动”方法。对我来说还有其他问题 - 如何知道存在的.o
文件是否使用 -pg
编译?
这是树外构建节省很多痛苦的地方:有一个构建目录用于配置对象,一个用于生产(等)。
@EricBackus 这正是我面临的问题。一种解决方法可能是在分析时重新编译并链接所有内容,但我不知道该怎么做。
@francescalus,好电话!我可能只是尝试使用单独的目录进行分析。
@smog 实际上,当我仔细观察时,我发现我过去所做的实际上是 MadScientist 下面答案的变体,其中目标文件根据编译选项获得不同的名称或路径.我会选择类似的东西。
【参考方案1】:
你可以做你想做的事,target-specific variables:
PROFILE :=
%.o : %.f90
$(FC) $(FLAGS) $(PROFILE) -c -o $@ $<
default: $(OBJS)
....
profile: PROFILE := -pg
profile: $(OBJS)
....
但是,这通常不是首选方式。除非您真的很努力在配置文件和非配置文件构建之间来回切换时始终进行完全清理,否则很容易混淆,并且有些对象使用配置文件编译而其他对象不编译。
如 cmets 中所述,最好将它们构建到单独的目录中:
$(PDIR)/%.o : %.f90
@mkdir -p $(@D)
$(FC) $(FLAGS) -pg -c -o $@ $<
$(ODIR)/%.o : %.f90
@mkdir -p $(@D)
$(FC) $(FLAGS) -c -o $@ $<
default: $(addprefix $(ODIR)/,$(OBJS))
$(FC) $(FLAGS) $^ -o $@
profile: $(addprefix $(PDIR)/,$(OBJS))
$(FC) $(FLAGS) -pg $^ -o $@
【讨论】:
以上是关于如何使用带有 gprof 的 makefile 重新编译依赖项?的主要内容,如果未能解决你的问题,请参考以下文章
使用cmake与makefile调试需要指定的参数[GDB与Gprof参数]
使用cmake与makefile调试需要指定的参数[GDB与Gprof参数]