猿代码 — 科研/AI模型/高性能计算
0

makefile示例及解释。语法,$^ 和$@的意思

摘要: makefile可以理解为一个脚本文件,使用make命令工具解析,其中定义了一系列的编译规则,如哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译。1)makefile源文件# Makefile for compilation fo complet ...
makefile可以理解为一个脚本文件,使用make命令工具解析,其中定义了一系列的编译规则,如哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译。

1)
makefile源文件
# Makefile for compilation fo complete project
# Source code files should be in folder src/
# Header files should be in folder include/


# C compiler
CC = g++

# MPI C++ compiler
MPICC = mpi++.mpich2

# OpenMP compiler option
OMP = -fopenmp

# Folder for header files
head = -I include/
# Additional option
OPT = -c
#OPT = -O3 -c

VPATH = src

PROG = multigrid
OBJECTS = array3d.o boundarycondition3d.o matvecAv.o misc.o prolongation3d.o restriction3d.o smoother7p.o timer.o

$(PROG).exe: $(OBJECTS) $(PROG).cpp
#       @echo "Compile" $@
        @echo $(CC) $(OMP) $(head) $^ -o $@
        @$(CC) $(OMP) $(head) $^ -o $@

%.o: %.cpp
        @echo "Compile" $^
        @echo $(CC) $(OMP) $(head) $^ $(OPT)
        @$(CC) $(OMP) $(head) $^ $(OPT)

clean:
        rm -f *.o *.exe *.py

.PHONY: clean, run

2)
删除
make clean
rm -f *.o *.exe *.py

3)
编译等:
make
Compile src/array3d.cpp
g++ -fopenmp -I include/ src/array3d.cpp -c
src/array3d.cpp: In function ‘double evaluate_array3d(const double*, int, int, int, int)’:
src/array3d.cpp:40:1: warning: control reaches end of non-void function [-Wreturn-type]
   40 | }
      | ^
Compile src/boundarycondition3d.cpp
g++ -fopenmp -I include/ src/boundarycondition3d.cpp -c
Compile src/matvecAv.cpp
g++ -fopenmp -I include/ src/matvecAv.cpp -c
Compile src/misc.cpp
g++ -fopenmp -I include/ src/misc.cpp -c
Compile src/prolongation3d.cpp
g++ -fopenmp -I include/ src/prolongation3d.cpp -c
Compile src/restriction3d.cpp
g++ -fopenmp -I include/ src/restriction3d.cpp -c
Compile src/smoother7p.cpp
g++ -fopenmp -I include/ src/smoother7p.cpp -c
Compile src/timer.cpp
g++ -fopenmp -I include/ src/timer.cpp -c
g++ -fopenmp -I include/ array3d.o boundarycondition3d.o matvecAv.o misc.o prolongation3d.o restriction3d.o smoother7p.o timer.o src/multigrid.cpp -o multigrid.exe

4)下面解释一下经典makefile的语法及命令
CC = g++
表示CC被赋值为g++
现时下面几个 都是赋值:

# MPI C++ compiler
MPICC = mpi++.mpich2

# OpenMP compiler option
OMP = -fopenmp

# Folder for header files
head = -I include/
# Additional option
OPT = -c
#OPT = -O3 -c

VPATH = src


PROG = multigrid
OBJECTS = array3d.o boundarycondition3d.o matvecAv.o misc.o prolongation3d.o restriction3d.o smoother7p.o timer.o

注意OBJECTS 包含了多个.o文件

5)
$(PROG).exe: $(OBJECTS) $(PROG).cpp
#       @echo "Compile" $@
        @echo $(CC) $(OMP) $(head) $^ -o $@
        @$(CC) $(OMP) $(head) $^ -o $@

这个地方是精华
PROG被前面赋值为multigrid,意思是
OBJECTS 被赋值为 array3d.o boundarycondition3d.o matvecAv.o misc.o prolongation3d.o restriction3d.o smoother7p.o timer.o
multigrid.exe: array3d.o boundarycondition3d.o matvecAv.o misc.o prolongation3d.o restriction3d.o smoother7p.o timer.o multigrid.cpp
即multigrid.exe依赖后面这些文件
这个地方唯一不明白的地方就是VPATH什么时候给了PROG,不是特别明白

根据网上资料:
因为main.c这些源文件已经移动到src目录中去了,默认情况下,make时只会在当前目录下寻找目标和依赖,也就是寻找main.o main.c这类文件,当前目录没有这些文件,肯定不能生成最终的目标文件prog,那么如何在其它目录下搜索目标和依赖呢?在Makefile中可以使用VPATH或者vpath,

可见vpath就表示要去找main所在的目录。

6)

@echo $(CC) $(OMP) $(head) $^ -o $@
CC和OMP分别被赋值为g++和-fopenmp
head被赋值为 -I include/
那么
$^表示$(PROG).exe: $(OBJECTS) $(PROG).cpp这一句的后半部分,即array3d.o boundarycondition3d.o matvecAv.o misc.o prolongation3d.o restriction3d.o smoother7p.o timer.o src/multigrid.cpp
$@表示$(PROG).exe: $(OBJECTS) $(PROG).cpp这一句的前半部分,即multigrid.exe
从而 组合起来为
g++ -fopenmp -I include/ array3d.o boundarycondition3d.o matvecAv.o misc.o prolongation3d.o restriction3d.o smoother7p.o timer.o src/multigrid.cpp -o multigrid.exe

src/multigrid.cpp应该是VPATH的作用。

7)
%.o: %.cpp
        @echo "Compile" $^
        @echo $(CC) $(OMP) $(head) $^ $(OPT)
        @$(CC) $(OMP) $(head) $^ $(OPT)

%.o大概指$(PROG).exe: $(OBJECTS) $(PROG).cpp中$(PROG).exe所依赖的所有.o文件
%.cpp表示这个对应名字的cpp文件,但是不知道 怎么会加上VPATH
从而 是类似下面这些命令
Compile src/boundarycondition3d.cpp
g++ -fopenmp -I include/ src/boundarycondition3d.cpp -c

8)关于VPATH

makefile还有一个VPAH的变量,也是指定搜索路径的,只不过不能像vpath那样指定文件的匹配模式,这在大型的工程中查找指定文件会比较费时。用法:

VPATH=include:src
  • 1

多个路径集间用冒号":"分隔。

VPATH就是目录,让make命令在下面的目录中自己去找。

感觉没有vpath好用 ,但是应该也可以。

 VPATH可能存在的问题:

(1)如果大型文件会很慢

(2)如果同名找第一个?
















说点什么...

已有0条评论

最新评论...

本文作者
2024-2-24 23:55
  • 0
    粉丝
  • 334
    阅读
  • 0
    回复
资讯幻灯片
热门评论
热门专题
排行榜
Copyright   ©2015-2023   猿代码-超算人才智造局 高性能计算|并行计算|人工智能      ( 京ICP备2021026424号-2 )