Makefile编写示例
#
# := 用于给变量赋值,除此之外还有=、?=
# 一般全大写变量用来表示允许调用make时传入的变量,
# 全小写变量表示仅内部使用的变量
# 这里CC和CXX指定了要使用的C和C++编译器
CC := clang
CXX := clang++
# Makefle中的核心概念是target(目标)
# 定义target的基本格式是(注意每一行command必须用tab缩进):
#
# name: dependencies
# commands
#
# 要构建某个target时,使用如下命令:
#
# make target_name
#
# 下面all是一个target,它依赖另一个target:hello,
# 意味着要构建all,首先要构建hello
# 而all的commands部分为空,表示构建all不需要额外命令
# .PHONY表示all不是一个真实会发生的文件,而是一个“伪目标”
# 伪目标的作用是告诉make,all是一个目标,而不是一个文件
.PHONY: all
all: hello
# 由于后面需要多次使用main.o等目标文件列表,所以这里定义给变量,赋值给变量objects
objects := main.o
# hello是我们最终要生成的可执行文件名,它依赖objects中的所有目标文件
# 他的commands部分使用CXX指定的编译器来讲所有目标文件链接成hello可执行文件
hello: $(objects)
$(CXX) -o $@ $(objects)
# 依赖变量,还是依赖main.o,继续编main.o
# main.o目标文件依赖main.cpp源文件
main.o: main.cpp
$(CXX) -c main.cpp
# clean用于清除构建生成的临时文件、目标文件和可执行文件
# 和all类似,他是一个"伪目标"
.PHONY: clean
clean:
rm -f hello $(objects)
链接多个文件的话,就需要修改一些内容
CC := clang
CXX := clang++
# CXX:指定编译器
# CXXFLAGS:编译器标志
CXXFLAGS := --target=x86_64-w64-windows-gnu
# 这个参数指定了目标平台的架构和环境
# 这里指定了x86_64架构的windows环境
# 这个参数是为了让clang++编译器生成windows下的可执行文件
# 没有这个参数,会报错找不到库
# 具体含义:
# x86_64:指定生成的代码是64位架构
# w64-windows-gnu:指定生成的代码是windows环境下的gnu标准库
.PHONY: all
all: answer
objects := main.o answer.o
# 这里的修改只需要在objects中添加answer.o即可
# 如果要修改目标名的话,只需要修改上一版hello为你想要的名字即可,这里修改为了answer
answer: $(objects)
$(CXX) $(CXXFLAGS) -o $@ $(objects)
# Make可以自动推断
# .o文件是需要依赖同名的.cpp文件的
# 所以其实不需要再依赖中指定main.cpp和answer.cpp,
# 也不需要写编译commands,他知道要用CXX变量制定的命令作为C++编译器
# 这里值需要指定目标文件所依赖的头文件,使头文件变动时可以重新编译对应目录文件
main.o: answer.hpp
answer.o: answer.hpp
.PHONY: clean
clean:
rm -f hello $(objects)
# del ${objects} answer.exe
这里踩了很多坑,应该是配置的问题
顺便记录一下踩的坑
顺便放一下对应的Cpp和hpp代码,方便后续实验
- main.cpp
#include <iostream> #include "answer.hpp" using namespace std; int main(int argc, const char *argv[]){ int excepted_answer = answer::find_the_ultimate_answer(); for(;;){ std::cout << "The ultimate answer is: " << excepted_answer << std::endl; int answer; std::cin >> answer; if(answer == excepted_answer){ std::cout<<"Correct!" << std::endl; break; } } return 0; }
- answer.cpp
#include "answer.hpp" namespace answer{ int find_the_ultimate_answer(){ return 42; } }
- answer.hpp
#ifndef ANSWER_HPP #define ANSWER_HPP namespace answer { int find_the_ultimate_answer(); } #endif
然后就可以编译成功啦,注意一点是直接安装的mingw64里面可能没有make,要用ming32-make编译
ming32-make all
但是可以在目录里面copy一个,改名make