一、Makefile文件

为了方便分析,直接上文件,Makefile 文件中的内容如下所示:

#
# Makefile
# 编译的.o文件和.c文件在同一路径下
# $(info "start...")
# 可执行文件名
PROJECT_NAME = app ##################################### 项目路径 #####################################
PROJECT_PATH ?= ${shell pwd}
OBJ_DIR := $(PROJECT_PATH)/build ##################################### 设置编译器,默认使用GCC #####################################
CC ?= gcc ##################################### 所需头文件的路径 #####################################
CFLAGS += -I$(PROJECT_PATH)/lib/inc ##################################### 编译和链接参数 #####################################
CFLAGS ?= -O3 -g0 -Wall -Wshadow -Wundef -Wmissing-prototypes
LDFLAGS ?= -lm ##################################### 收集需要编译的源文件 #####################################
CSRCS += $(PROJECT_PATH)/application/main.c
include $(PROJECT_PATH)/lib/lib.mk ##################################### 将文件名替换为.o文件 #####################################
CXX_OBJCTS = $(patsubst %.c, $(OBJ_DIR)/%.o, $(notdir $(CSRCS)))
SOURSE_DIR = $(dir $(CSRCS)) vpath %.c $(SOURSE_DIR) $(OBJ_DIR)/%.o: %.c
@$(CC) $(CFLAGS) -c $< -o $@
#@echo "CC $<" all: $(CXX_OBJCTS)
@$(CC) -o $(PROJECT_NAME) $(CXX_OBJCTS) $(LDFLAGS) clean:
@rm -f $(PROJECT_NAME) $(CXX_OBJCTS)

二、代码分析

  1. 查找所有.c文件

    # 方式一
    CSRCS += $(PROJECT_PATH)/application/main.c # 方式二
    CXX_SOURCES = $(foreach dir,$(CSRCS), $(wildcard $(dir)/*.c))

    注意:方式一是直接将所有的 .c 文件追加到 CSRCS 变量中,方式二是将搜索路径下的所有 .c 文件,并追加到 CSRCS 变量中。

  2. 将所有的 .c 文件换成 .o 文件

    # 方式一
    COBJS = $(CSRCS:.c=.o)
    # 方式二
    COBJS= $(patsubst %.c, %.o, $(CSRCS))

    注意:方式一和方式二原理都是一样的,其目的是将所有的 .c 文件换成 .o 文件而已

  3. 生成 .o 文件

    /%.o: %.c
    @$(CC) $(CFLAGS) -c $< -o $@
    #@echo "CC $<"

    注意:第2点只是将 .c 文件 换成了 .o 文件名,得到的只是文件名称而已,这里才是根据相应的目标生成 .o 文件

  4. 链接成可执行文件

    将所有的 .o 文件链接成可执行文件

    @$(CC) -o $(PROJECT_NAME)  $(CXX_OBJCTS) $(LDFLAGS)
  5. 清理所有的 .o 文件

    @rm -f $(PROJECT_NAME) $(CXX_OBJCTS)

注意:以上就是 make 的编译流程,但是编译生成的 .o 文件和.c 文件是在同一目录下的,不满足我们的需求,接着网下看

  1. 将所有的 .o 文件放到指定目录下

    CXX_OBJCTS = $(patsubst  %.c, $(OBJ_DIR)/%.o, $(notdir $(CSRCS)))

    注意: notdir $(CSRCS) 函数是去掉文件路径,只保留文件名,如此便可以在替换后缀的时候,在文件前面加上指定路径

  2. 完成指定路径下的所有 .o 文件的目标

    $(OBJ_DIR)/%.o: %.c
    @$(CC) $(CFLAGS) -c $< -o $@
    #@echo "CC $<"

    注意:这里的作用在源文件中查找能制作目标的文件,因为这里的目标和源文件不在同一目录下,所以需要完成第8点的操作

  3. vpath 和 VPATH

    这里我也不是很理解,在自动目标中需要将源文件路径加入 vpath 或 VPATH 中,如下所示:

    # 方式一
    VPATH += :$(SRC_DIR)
    # 方式二
    SOURSE_DIR = $(dir $(CSRCS))
    vpath %.c $(SOURSE_DIR)

    注意:函数 dir 的作用是提取所有文件的路径

参考链接

linux Makefile 如何将生成的.o文件放到指定文件:https://blog.csdn.net/forgetjoker/article/details/117676029

linux Makefile 如何将生成的 .o 文件放到指定文件夹的更多相关文章

  1. C# 将引用的DLL文件放到指定的目录下

    原文:C# 将引用的DLL文件放到指定的目录下 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sweety820/article/details/2 ...

  2. C# 获得目录下所有文件或指定文件类型文件(包含所有子文件夹)

    public partial class FileGet { /// <summary> /// 私有变量 /// </summary> private static List ...

  3. Python复制指定目录的各个子目录下的同名文件到指定文件夹并重命名

    Python复制指定目录的各个子目录下的同名文件到指定文件夹并重命名 #编码类型 #-*- coding: UTF-8 -*- #导入包 import os import shutil srcpath ...

  4. Linux下find一次查找多个指定类型文件,指定文件或者排除某类文件,在 GREP 中匹配多个关键 批量修改文件名等

    http://blog.sina.com.cn/s/blog_62e7fe670101dg9d.html linux下二进制文件查找: strings 0000.ts | grep -o " ...

  5. python 拷贝文件夹下所有的文件到指定文件夹(不包括目录)

    1.随便简单些写了一下.直接粘结代码,只是简单的实现一下,还很多需要完善和扩展的地方,比如忽略掉后缀文件,删除文件 如果排除的某些的话可以用: sourceF.find('.后缀')>0 2.注 ...

  6. ubuntu上解压目录里的文件到指定文件夹

    去除目录结构加上 --strip-components N 如: 压缩文件eg.tar 中文件信息为 src/src/src/eg.txt 运行 tar -xvf eg.tar --strip-com ...

  7. PHP 解压 ZIP 文件到指定文件夹

    本类实现参考 php manual 评论 [php] view plain copy /** * function: 解压zip 格式的文件 * author:friker * date:2015-1 ...

  8. Java 遍历文件夹里面的全部文件、指定文件

    Java 手册 listFiles public File[] listFiles(FileFilter filter) 返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件 ...

  9. Java操作FTP,从FTP上读取指定文件,把指定文件上传到FTP

    需要添加的依赖 <!-- https://mvnrepository.com/artifact/commons-net/commons-net --> <dependency> ...

  10. python 合并目标文件夹中多个txt文件到指定文件中

    # coding = 'utf-8' # description: 合并目标文件夹中多个txt文件,到指定文件中. import os def file_merge_to_one(dirpath): ...

随机推荐

  1. 一秒变身艺术家!U2Net 跨界肖像画,让你的头像瞬间细节完美复刻,打造个性化头像新风潮!

    效果 测试图片来自网络,如有侵权,联系删除. 项目 关注微信公众号,回复关键字:"一秒变身艺术家",获取程序! 模型信息 Inputs ---------------------- ...

  2. OpenCV 方法及应用速查表

    序  号 方    法 说    明 技术分类 1 image = cv2.imread(filename, flags) 读取图像 基本操作 2 cv2.imshow(winname, mat) 显 ...

  3. #回滚莫队,链表#洛谷 6349 [PA2011] Kangaroos

    题目传送门 分析 首先区间 \([l,r]\) 与 \([L,R]\) 相交当且仅当 \(l\leq R\) 且 \(L\leq r\)(其实就是完全覆盖或者有一端点在区间中) 而且坐标范围太大了,如 ...

  4. Promise + Async&Await + Array.reduce + 函数递归 解决网络/接口请求的依次/排队不间断间隔访问

    背景 试想在一个需要频繁更新数据的场景(例如:监控.图表类),常规方法是设置一个间隔 N 秒的定时器 setInterval:但是这种方式存在一个问题,当前一个请求时间过长时(超过了间隔时间),后一个 ...

  5. Docker 13 网络

    Linux 网络 查看本地网络信息: [root@sail ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueu ...

  6. openGauss数据库将磁盘表转换为MOT

    openGauss 数据库将磁盘表转换为 MOT 一.将磁盘表转换为 MOT 方法 磁盘表直接转换为 MOT 尚不能实现,这意味着尚不存在将基于磁盘的表转换为 MOT 的 ALTER TABLE 语句 ...

  7. Redis Stack功能介绍及redis-om-dotnet使用示例

    为了简化开发人员对较新的 Redis 模块及其提供的功能的体验,同时简化支持其功能的文档和客户端.以帮助开发人员从开始使用 Redis 的那一刻起,就能充分提高工作效率.Redis Stack诞生了. ...

  8. spring-jdbc5新特性,一个配置文件解决临时修改数据库的问题

    import java.sql.SQLException; import java.util.List; import java.util.Map; import javax.sql.DataSour ...

  9. MUI-拿到版本名称和版本code

    场景: 一般App发布了新版本之后,都会提示用户去更新.这就需要我们获取App的当前版本号与后台存储的版本号做对比来判断是否需要更新. 获取版本名称和版本code: 打开manifest.json文件 ...

  10. kolla-ansible部署OpenStack Train版技术方案

    简单架构示意 项目目标 1. 实现容器化部署docker+ Ansible+openstack-tarin 2. 使用keeplived监控nova服务实现在单台服务器宕机的情况下能迅速切断连接减轻平 ...