当前位置: 首页 > news >正文

Makefile学习

C语言的编译过程

预处理(Preprocessing)

-E是让编译器在预处理之后就退出,不进行后续编译过程;-o是指定输出文件名。

gcc -E hello.c -o hello.i

编译(Compilation)

这里的编译不是指程序从源文件到二进制程序的全部过程,而是指将经过预处理文件(test.i)之后的程序转换成特定汇编(test.s)代码的过程。

gcc -S hello.i -o hello.s

汇编

汇编过程将上一步的汇编代码转换成机器码,这一步产生的文件叫做目标文件,是二进制格式。

gcc -c hello.s -o hello.o

链接

链接过程使用链接器将该目标文件与其他目标文件、库文件、启动文件等链接起来生成可执行文件。附加的目标文件包括静态连接库和动态连接库。

gcc hello.o -o hello

总结

生成可执行程序过程为成四个步骤:

1、由.c文件到.i文件,这个过程叫预处理。
2、由.i文件到.s文件,这个过程叫编译。
3、由.s文件到.o文件,这个过程叫汇编。
4、由.o文件到可执行文件,这个过程叫链接。

静态库

在编译的过程中,会被直接载入到可执行文件中,将多个文件组成一个库,实现复用,以lib开头,以.a结尾,使用ar命令

动态库

在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。这就带来了一个明显的好处:不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,减小了各个模块之间的耦合程度,也减小了可执行文件的体积。

MakeFile

基本格式

target ... : prerequisites ...command......

make debug执行下面的命令

debug:echo hello
.PHONY: clean # 伪目标
clean:rm *.o

变量

cpp := src/main.cpp
obj := obj/main.o${obj}: ${cpp}g++ -c ${cpp} -o ${obj}# $@ target的名称# $< 第一个依赖文件# $^ 所有的依赖文件compile: ${obj}clean:rm -rf obj# Windows下使用del obj.PHONY: clean debug

运算符号

:=:赋值后不可改变

= :可以改变

?=:在变量尚未设置时才将其设置为值

+=:添加

\:续行符

函数

shell:把执行操作系统命令后的输出作为函数返回,本质上就是执行shell命令。

cpp_srcs := ${shell find src -name *.cpp}

subst、patsubst

格式:源字符串都是<text>的内容

$(subst <from>,<to>,<text>)
$(patsubst <pattern>,<replacement>,<text>) # pattern中的%和replacement中的%相同

foreach

$(foreach <var>,<list>,<text>)# eg
names := a b c d
files := $(foreach n,$(names),$(n).o)
# $(file) := a.o b.o c.o d.o 

dir

$(dir <names...>) #取目录函数
$(dir src/foo.c hacks) # 返回值是 src/ ./

notdir、filter

$(notdir <names...>) # 取文件函数
$(notdir src/foo.c hacks) # 返回值是 foo.c hacks
$(filter <pattern...>,<text>) # 过滤出text中符合pattern的字符串
sources := foo.c bar.c baz.s ugh.h
foo: $(sources)cc $(filter %.c %.s,$(sources)) -o foo # $(filter %.c %.s,$(sources)) 返回的值是 foo.c bar.c baz.s

编译带有头文件的项目

Makefile示例(1):

cpp_srcs := $(shell find src -name *.cpp)
cpp_objs := $(patsubst src/%.cpp,objs/%.o,$(cpp_srcs))# 你的头文件所在文件夹路径(建议绝对路径)
include_paths := 
I_flag        := $(include_paths:%=-I%)objs/%.o : src/%.cpp@mkdir -p $(dir $@)@g++ -c $^ -o $@ $(I_flag)workspace/exec : $(cpp_objs)@mkdir -p $(dir $@)@g++ $^ -o $@ run : workspace/exec@./$<debug :@echo $(I_flag)clean :@rm -rf objs.PHONY : debug run

Makefile示例(2):

# Compiler
CXX := g++# cpp sources
cpp_srcs := ${shell find src -name *.cpp}
# $(warning cpp_srcs is ${cpp_srcs})# cpp objects
cpp_objs := ${patsubst src/%.cpp,objs/%.o,${cpp_srcs}}
# $(warning cpp_objs is ${cpp_objs})# cpp include path
include_path := /home/mirac/Desktop/Retest/include
I_flags := ${include_path:%=-I%}
# ${warning I_flags is ${I_flags}}# compile option
Compile_option := -g -O3 -w
Compile_option += ${I_flags}
# $(warning Compile_option is ${Compile_option})objs/%.o : src/%.cpp@mkdir -p ${dir $@}@${CXX} -o $@ -c $^  ${Compile_option}workspace/testJson: ${cpp_objs}@${CXX} -o $@  $^ run : workspace/testJson@./$<debug:echo ${cpp_srcs}echo ${cpp_objs}echo ${I_flags}
# @echo ${CC} -o $@ -c $^  ${Compile_option}clean : @rm -r objs@rm -r workspace/*.PHONY: clean debug

相关文章:

  • MacOS 14.3 安装 brew
  • 20.HarmonyOS App(JAVA)表格布局Layout使用方法
  • Unity根据落点和抛物线运行时间,求初始力
  • Redis RCountDownLatch RSemaphore的应用
  • sklearn 计算 tfidf 得到每个词分数
  • [C#][opencvsharp]opencvsharp sift和surf特征点匹配
  • lua只读表
  • Security ❀ TCP异常报文详解
  • 【JavaEE进阶】 图书管理系统开发日记——肆
  • git的分支的使用,创建分支,合并分支,删除分支,合并冲突,分支管理策略,bug分支,强制删除分支
  • 字面跳动前端面试题:React Hook为什么不能放在if/循环/嵌套函数里面?
  • js数组和字符串之间的转换方式以及数组的一些方法
  • 51单片机实验课二
  • 二、人工智能之提示工程(Prompt Engineering)
  • JAVA中枚举的方法
  • ES6核心特性
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • Java多态
  • js
  • NSTimer学习笔记
  • PAT A1120
  • PHP CLI应用的调试原理
  • rabbitmq延迟消息示例
  • vagrant 添加本地 box 安装 laravel homestead
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 成为一名优秀的Developer的书单
  • 初识 beanstalkd
  • 分布式任务队列Celery
  • 复杂数据处理
  • 欢迎参加第二届中国游戏开发者大会
  • 三分钟教你同步 Visual Studio Code 设置
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 小程序01:wepy框架整合iview webapp UI
  • 小程序开发中的那些坑
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • 带你开发类似Pokemon Go的AR游戏
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • ![CDATA[ ]] 是什么东东
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #1014 : Trie树
  • #ubuntu# #git# repository git config --global --add safe.directory
  • (11)MSP430F5529 定时器B
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (一)基于IDEA的JAVA基础1
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件