一、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. 记录--vue+three,制作iview大波浪特效

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.效果图 具体效果可参考iview官方界面iView - 一套高质量的UI组件库 大波浪效果,使用的是three.js的官方例子,需要先 ...

  2. C# ASP.NET MVC 配置 跨域访问

    在web.config文件中的 system.webServer 节点下 增加如下配置        <httpProtocol>             <customHeader ...

  3. KingbaseES V8R6 集群运维案例 -- 禁止普通用户su到root

    案例说明: 在集群管理中,会使用到root权限(如ip.aring命令等),为安全需要,有的生产环境禁止普通用户su切换到root,本案例测试了禁止普通用户su切换到root对集群管理带来的影响. 集 ...

  4. #倍增,LCA,Kruskal#JZOJ 1092 洛谷 4180 [BJOI 2010] 次小生成树

    题目 给出一个无向图,问它的严格次小生成树(数据保证有解) 分析 首先先找一棵最小生成树,然后对于每条非树边\((x,y,w)\)可以找到最小生成树上\(x,y\)路径上略小于\(w\),首先如果能找 ...

  5. 基于HANA重构业务的总结

    本文于2019年7月29日完成,发布在个人博客网站上. 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来. 依据领导的规划,本月启动了一项业务迁移工作,作为特别行动,部门安 ...

  6. Git安装和配置教程:Windows/Mac/Linux三平台详细图文教程,带你一次性搞定Git环境

    Git是一款免费.开源的分布式版本控制系统,广泛应用于软件开发领域.随着开源和云计算的发展,Git已经成为了开发者必备的工具之一.本文将为大家介绍Git在Windows.Mac和Linux三个平台上的 ...

  7. Python 集合(Sets)1

    集合 集合用于在单个变量中存储多个项.集合是 Python 中的 4 种内置数据类型之一,用于存储数据集合,其他 3 种是列表(List).元组(Tuple)和字典(Dictionary),它们都具有 ...

  8. Prometheus Operator与kube-prometheus之二-如何监控1.23+ kubeadm集群

    简介 系列文章: 标签 - Prometheus - 东风微鸣技术博客 (ewhisper.cn) Prometheus Operator 的上一篇: Prometheus Operator 与 ku ...

  9. 电脑开机时报错No Bootable Device找不到索引的解决方法

      本文介绍笔记本电脑出现No Bootable Device错误提示,且无法开机的多种解决办法. 1 问题产生   最近,笔记本电脑正在正常使用时,突然蓝屏,出现你的设备遇到问题,需要重启.的提示: ...

  10. 保护C#代码的艺术:深入浅出代码混淆技术

    摘要 在C#开发中,代码的保护是一个不可忽视的问题.本文深入探讨了几种常用的C#代码混淆工具,帮助开发者理解如何有效地保护代码不被反编译.同时,本文也对混淆技术的优缺点进行了分析,并提供了一些实际使用 ...