首页 > 系统相关 >linux Makefile 如何将生成的 .o 文件放到指定文件夹

linux Makefile 如何将生成的 .o 文件放到指定文件夹

时间:2022-12-29 15:35:03浏览次数:78  
标签:文件 %. Makefile PROJECT 文件夹 linux CSRCS ##################################### DIR

一、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

标签:文件,%.,Makefile,PROJECT,文件夹,linux,CSRCS,#####################################,DIR
From: https://www.cnblogs.com/jzcn/p/17012331.html

相关文章

  • Arch Linux配置Java学习环境
    1.JDKJDK8:主流版本$sudopacman-Sjdk8-openjdkJDK11:将会是下一个主流版本$sudopacman-Sjdk11-openjdkJDK19:最新版$sudopacman-Sjdk19-openjdk......
  • Linux: root 密码破解步骤
    在以下界面进入root密码破解界面mount-orw,remount/sysrootchroot/sysrootecho123|passwd--stdinroottouch/.autorelabelexitexit......
  • Linux中的特殊符号含义及作用!
    我们在学习、使用Linux时,会遇到各种各样的符号,很难理解和记忆,但其实符号的作用很大,今天老男孩教育小编给大家详细说明一下:1、通配符?匹配单个字符*代表所......
  • Linux 常用监控指标总结
    1.Linux运维基础采集项做运维,不怕出问题,怕的是出了问题,抓不到现场,两眼摸黑。所以,依靠强大的监控系统,收集尽可能多的指标,意义重大。但哪些指标才是有意义的呢,本着从实践中来......
  • Linux内存管理-slub算法
    Slub简介Linux内核内存管理用了两个算法:伙伴算法(以页为单位的大内存)和slub算法(以字节为单位的小内存),其中slub系统运行在伙伴系统之上。slub进行内存分组管理,分......
  • linux bpf 学习记录
    eBPF介绍BPF(BerkeleyPacketFilter)使普通用户拥有了让啮合执行用户代码并共享数据的能力。用户可以讲eBPF指令直接码传输给内核,然后通过socket写时间来触发内核执......
  • Linux编程的经典书籍-推荐书籍
    Linux编程的经典书籍    作为刚入门的一位linux环境下编程学习,在网上找到的推荐的linux书籍。和大家分享。原文作者:水煮鱼。笔者稍微修改。在此转载申明。    成为......
  • Linux 环境中使用 LVGL
    之前有记录过在esp32中使用LVGL的笔记,需要的小伙伴可以了解一下,esp-idf移植lvgl8.3.3我之前整理的学习资料:https://www.cnblogs.com/jzcn/p/16647106.html一、准备......
  • Linux - 进程间通信(IPC)
    常见的通信方式管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。命名管道FIFO:有名管道......
  • VMware Linux虚拟机在线增加磁盘/磁盘扩容
    扩容前状态只有一块60GB的磁盘[root@RHEL6~]#fdisk-lDisk/dev/sda:53.7GB,53687091200bytes64heads,32sectors/track,51200cylindersUnits=cylindersof204......