Make 和 CMake

Make

Makefilemake 命令使用,make 命令可以指定参数,以确定要执行 makefile 中的哪个条目,如果不指定参数,则默认执行第一个条目。

编译 main.cppMakefile 内容如下:

# 定义变量(变量名随意,内容随意),给后面的代码使用
IN = main.cpp
OUT = main.out
# 定义变量(使用 OUT 变量的内容作为本变量的内容)
RM_FILES = $(OUT)

# entry 是第一个条目(名字随意),所以单纯执行 make 命令,会默认调用该条目
# 该条目依赖 usage 文件,如果 usage 文件不存在,则会调用 usage 条目
# 调用完 usage 条目后,该条目什么也不做,直接退出 make 命令
entry: usage

# 如果执行 make run 命令,则会调用该条目
# 该条目依赖 $(OUT) 文件,也就是 main.out 文件,如果 main.out 文件不存在,则会调用 $(out) 条目
# 调用完 $(out) 条目后,会输出横线,然后执行 ./main.out 命令,然后再输出横线,然后退出 make 命令
# @ 表示不显示所执行的命令,只显示执行结果,就像 DOS 批处理中的 @ 符号一样
run: $(OUT)
	@echo ------------------------------
	@./$(OUT)
	@echo ------------------------------

# 本条目的名称就是 main.out,为了修改方便,定义成了变量 OUT,本条目依赖 $(IN),也就是 main.cpp
# 如果 main.out 不存在,则执行这里的命令,如果 main.out 存在,但日期比 main.cpp 旧,也会执行这里的命令
# 如果 main.out 存在,且日期比它所依赖的所有文件都新,则执行该条目后,该条目什么也不做。
$(OUT): $(IN)
	clang++ -g -O3 $(IN) -o $(OUT)

# 如果执行 make clean 命令,则会调用该条目
# 该条目没有依赖,所以每次调用都会执行下面的命令
# 这里执行的是 Linux 命令,先判断 RM_FILES 变量中指定的各个文件是否存在,如果存在就将其删除
clean:
	@for i in $(RM_FILES); do if [ -f $$i ]; then rm $$i; fi; done

# 如果执行 make usage 命令,则会调用该条目
# 该条目没有依赖,所以每次调用都会执行下面的命令
# 这里执行的是 Linux 命令,会向终端输出一些文本,如果是 Windows 平台,则不应该使用引号
usage:
	@echo "用法:"
	@echo "  make run    # 编译并运行"
	@echo "  make clean  # 清理临时文件和结果文件"

# 命令前面必须有一个制表符,不能用空格代替
# 注释前面不能是制表符,否则会被当作命令执行

另一个 Makefile,可以在所有子目录中执行 make clean

# 获取当前目录下的所有子目录列表(目录名以数字开头)
SUBDIR = $(shell find . -maxdepth 1 -type d | grep ^\./[0-9])

# 默认不执行任何操作
all:

# 在所有子目录中执行 make clean
clean: $(SUBDIR)
	@for i in $(SUBDIR); do echo $$i; make --no-print-directory clean -C $$i; echo ------------------------------; done

CMake

CMakeLists.txtcmake 命令使用,cmake 命令需要指定 CMakeLists.txt 文件的路径或 CMakeLists.txt 文件所在的目录。

执行 cmake 路径 后,会根据 CMakeLists.txt 生成 Makefile 文件,再执行 make 命令才会得到最终的编译结果。

下面的 CMakeLists.txt 用于编译 OpenGL 示例文件 main.cpp

# 要求 cmake 低版不能低于指定版本
cmake_minimum_required(VERSION 3.0)

# 添加 C++11 标准支持
#set(CMAKE_CXX_FLAGS "-std=c++11")

# 声明一个 cmake 工程
# 一个工程可以生成多个目标文件
project(main)

# 设置头文件的搜索目录,可以有多个
include_directories(
    ${PROJECT_SOURCE_DIR}/../include
)

# 自定义变量 SRC,内容为要编译的文件列表
set(SRC 
    ${PROJECT_SOURCE_DIR}/main.cpp
    ${PROJECT_SOURCE_DIR}/../include/glad.c
)

# 添加一个“可执行的”编译目标 main 及其依赖 ${SRC}
add_executable(main ${SRC})

# 添加 libglfw3.a 静态链接库文件(linux 环境)
add_library(glfw STATIC IMPORTED)
set_property(TARGET glfw PROPERTY IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/../lib/libglfw3.a)

# 指定 main 程序所要链接的库文件
target_link_libraries(main glfw dl GL X11 pthread)

CMakeLists.txt 旁边创建 run.sh 脚本文件,该脚本可以快速编译并运行上面的 main.cpp 程序,内容如下:

#!/bin/sh

# 创建临时目录,进入临时目录
mkdir build
cd build
# 执行 CMake,调用上级目录中的 CMakeLists.txt
# 会在本目录生成 makefile
cmake ..
# 执行 makefile
make --no-print-directory
# 编译后的可执行文件
./main

或者使用一个 makefile 来调用 cmake

run: build/main
# 编译后的可执行文件
	@build/main

build/main: main.cpp
# 创建临时目录,进入临时目录
	@if [ ! -d "./build" ]; then mkdir ./build; fi
# 执行 CMake,调用上级目录中的 CMakeLists.txt
# 会在本目录生成 makefile
	@cd build; cmake ..
# 执行 makefile
	@cd build; make --no-print-directory

clean:
	@if [ -d "./build" ]; then rm -r ./build; fi
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值