Makefile 编写教程(由简至难)

article/2025/9/11 17:12:46

目录

  • 一、测试代码
  • 二、.c 文件与Makefile同级
  • 三、.c文件与Makefile不同级
  • 四、链接静态库

一、测试代码

本文以将main.c add.c common.h三个文件编译成一个可执行文件为例,来讲解Makefile的编写。以下是每个文件的代码(很简单,测试用)

1.main.c

 #include <stdio.h>#include "common.h"                                                                                                                                                                                        int main(){int a = 1;int b = 2;printf("add(%d, %d) = %d\n",a, b, add(a,b));return 0;}

2.add.c

int add(int a, int b)
{return a+b;                                                                                                                                                                                            
}

3.common.h

#ifndef __COMMON_H__                                                                                                                                                                                       
#define __COMMON_H__extern int add(int a, int b);#endif

二、.c 文件与Makefile同级

将.c 文件放在Makefile同级目录,然后单独建一个目录.h头文件,如图。
在这里插入图片描述
以下是 Makefile 原文:

 CC = gccTARGET = progOBJS = main.o add.oINCLUDE = -I./include$(TARGET):$(OBJS)$(CC) $(OBJS) -o $(TARGET)   %.o:%.c$(CC) $(INCLUDE) -c $^ -o $@                                                                                                                                                                           .PHONY:cleanclean:rm *.o prog

逐行解释:

  • CC = gcc= 号在Makefile中是声明变量并给变量赋值的意思。这里声明了一个 自定义变量 CC,并用gcc编译器赋值。

  • TARGET = prog:声明Makefile目标文件,也就是这个Makefile最终目标是生成一个叫prog的文件。一般这种最终输出的文件都用TARGET来承载

  • INCLUDE = -I./include :用-I 选项指定自己写的头文件的路径。-I和路径之间有没有空格都行,一般没有空格

  • ** ( T A R G E T ) : (TARGET): (TARGET):(OBJS) **
    ** $(CC) $(OBJS) -o $(TARGET) **:
    格式

要生成的目标文件:生成目标文件所需要依赖的所有文件编译命令
  • %.o:%.c : %是Makefile的一个通配符。这句话的作用是将所有的.c文件自动编译成同名的.o文件。比如,有了这句话,那么1.c就会自动编译成1.o2.c就会自动编译成2.o

  • INCLUDE应该加在哪里
    程序在预处理时就会把头文件的内容展开,所以在调用 -c 选项 将 .c 文件编译成 .o文件时,就要指定头文件路径,否则会报错,提示找不到头文件路径

  • 通配符的作用

符号描述
$^所有依赖文件的集合,用空格分开,如果其中有重复的依赖文件,则只保留一个。比如依赖文件有三个: 1.c, 2.c, 1.c,那么$^拿到的只有 1.c 和 2.c 两个文件,舍弃了一个1.c
$<依赖文件中的第一个文件。如果依赖文件是以 “%” 定义的,那么 $< 就是依赖文件的集合。一般不会有重复的依赖文件,所以上面的 Makefile,用 $^ 替换掉 $< 也是可以的
$+与 $^ 一样,只是如果有重复的依赖文件,不会舍弃重复的依赖文件
$@目标文件的集合

三、.c文件与Makefile不同级

.c 文件放在src目录,.h文件放在include 目录,目录结构如图:
在这里插入图片描述
以下是 Makefile 原文:

 CC = gccTARGET = progSOURCE = $(wildcard ./src/*.c)      #获取src目录下所有.c文件OBJS = $(patsubst %.c, %.o, $(SOURCE))INCLUDE = -I./include$(TARGET):$(OBJS)  $(CC) $(OBJS) -o $(TARGET)     #另一种写法: $(CC) -o $(TARGET) $(OBJS)%.o:%.c$(CC) $(INCLUDE) -c $^ -o $@   #另一种写法:  $(CC) $(INCLUDE) -c -o $@ $^                                                                                                                                                                       .PHONY:cleanclean:rm $(OBJS) $(TARGET) 

这里只有第3、4行需要注意,相当于用这两行内容可以找到指定目录下的文件

  • 第3行 wilcard是获取src目录下所有的.c文件
  • 第4行patsubst是列出 SOURCE中 .c文件对应的所有 .o 文件

四、链接静态库

在前面的基础上,新建目录lib,创建sub.c
在这里插入图片描述
sub.c编译成静态库libsub.a,代码如下:

int sub(int a, int b)
{return a - b;                                                                                                                                                                                          }

编译成静态库的命令

gcc -c sub.c -o sub.o
ar crv libsub.a sub.o
补充: 如果静态库依赖于多个源文件,则依次编译得到.o,然后将所有的.o编译成 .a 静态库。
eg. 要将1.c、2.c、3.c编译成一个静态库,则ar crv libXXX.a  1.o 2.o 3.o

当然,除了用命令编译,也可以写成在lib目录下写一个Makefile,我就是这么做的,如下。(这个Makefile只用于编译静态库)

CC = gcc
TARGET = libsub.a
OBJS = sub.o
$(TARGET):$(OBJS)ar crv $(TARGET) $(OBJS)
%.o:%.c$(CC) -c -o $@ $<
.PHONY:cleanclean:rm *.o $(TARGET) 

接下来,就是修改我们最开始的那个Makefile

 CC = gccTARGET = progSOURCE = $(wildcard ./src/*.c) #获取src目录下所有.c文件OBJS = $(patsubst %.c, %.o, $(SOURCE))INCLUDE = -I./includeLIBS = -lsubLIBPATH = -L./lib$(TARGET):$(OBJS)$(CC) $(OBJS) -o $(TARGET)  $(LIBPATH) $(LIBS)%.o : %.c$(CC) $(INCLUDE) -c -o $@ $<                                                                                                                                                                           .PHONY:cleanclean:rm $(OBJS) $(TARGET)

第5、6行,编译时需要用 -L 指定静态库的路径,用 -l 指定静态库。
注意: 链接静态库是编译的最后一步链接做的事情。所以要加在第10行,而且只能加在末尾,如果直接跟在 $(CC)后面,make时会提示找不到静态库里的函数


http://chatgpt.dhexx.cn/article/YA1pFFmv.shtml

相关文章

好看的vscode字体

vscode下载上面出现的字体(自行百度搜索) (Cascadia Code, 等线)(等线是中文, Cascadia Code是英文, 自认为比较cool的搭配, 也可以自行选择)然后放到C:\Windows\Fonts 会自动安装就完事了~ 欢迎大家关注我的公众号:<前端成长指南> 我会把我的原创作品陆续放在上面

Unity3D中字体样式

字体样式分为三种 系统默认字体 自定义字体&#xff08;包括全部字体&#xff09; 自定义字体&#xff08;不包括全部字体&#xff09;系统默认字体描述优点内存占用小缺点没有艺术效果&#xff0c;没有灵魂 自定义字体&#xff08;包括全部字体&#xff09;描述优点具有一定…

前端HTML字体和文本样式

前端HTML字体和文本样式 文章目录 前端HTML字体和文本样式1.字体样式1.1字体大小1.2 字体粗细1.3 字体样式&#xff08;是否倾斜&#xff09;1.4字体类型1.5 样式层叠问题1.6 字体复合属性 2.文本样式2.1 文本缩进2.2 文本水平对齐方式2.3文本修饰 3.行高 属性表示注意点font-s…

layui表头样式_Layui表格好看样式

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Layui表格好看样式 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 开发工具与关键技术&#xff1a;web 作者&#xff1a;xq 撰写时间&#xff1a;2019.7.27 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~…

android+字体样式包,android 改变全局字体样式(第三方字体包)

android 改变全局字体样式 参考&#xff1a;http://stackoverflow.com/questions/2711858/is-it-possible-to-set-font-for-entire-application/16883281#16883281 1.将要替换的字体包放到assets下 2.具体代码&#xff1a; //设置新的字体样式 public static void setDefaultFo…

IDEA 修改字体样式

每次发现别人的IDEA字体都是这么好看&#xff0c; 今天这里推荐一款设置方法美化我们IDEA的代码&#xff0c; 代码变漂亮了&#xff0c;写代码也更带劲&#xff01;注意哦这针对的都是windows系统哦&#xff0c;mac系统就不用了&#xff0c;已经很完美了 第一步&#xff1a;下载…

7.20 Web前端-字体样式

今天为大家介绍一下关于字体的相关知识&#xff0c;这里的知识比较简单&#xff0c;因为之前的教学中我们已经接触到了一部分关于字体的知识&#xff0c;在这里我来汇总说一下。 1.长度单位&#xff1a; 长度单位就是你的字体在网页中占用的长度是多少&#xff0c;在web中不是…

9款漂亮的纯css字体样式

样式&#xff1a; 代码&#xff1a; <html> <head> </head> <style>body{text-align: center;}.hcqFont{position:relative;letter-spacing:.07em;font-size:3em;font-weight:normal;margin:0 auto}.hcqFont:before,.hcqFont:after{position:absolut…

7款漂亮的纯css字体样式

简单粗暴&#xff0c;直接上马&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><h1 class"vintage1">美丽的中国语</h1><h1 class"vi…

纯Css比较好看的中英文字体样式(持续整理版)

刚好公司要用到&#xff0c;需要纯css的&#xff0c;不用任何插件就可以显示很不错的字体 样式一&#xff1a; <style type"text/css"> .tb-js-yf-style{font-family: "Arial","Microsoft YaHei","黑体","宋体",san…

Windows 安装 HDF5 C++库

1. 简介 HDF5可以自己从源码编译&#xff0c;也可以通过下载已经编译好的版本的安装包安装。下面介绍的是安装包安装的方式。 2. HDF5安装包下载 地址1&#xff1a; https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8/hdf5-1.8.18/bin/windows/ 地址2&#xff1a; h…

HDF5 使用介绍

1、HDF5介绍 HDF 是用于存储和分发科学数据的一种自我描述、多对象文件格式。HDF 是由美国国家超级计算应用中心&#xff08;NCSA&#xff09;创建的&#xff0c;以满足不同群体的科学家在不同工程项目领域之需要。HDF 可以表示出科学数据存储和分布的许多必要条件。HDF 被设计…

hdf5 文件生成 C++

使用 hdf5 配置 1. 包含目录 E:\WorkSpace\SoftWare\hdf5\include 2.库目录 E:\WorkSpace\SoftWare\hdf5\lib\ 3.链接器 -输入 hdf5.lib hdf5_cpp.lib 4. C/C -预处理器定义 H5_BUILT_AS_DYNAMIC_LIB; 注意 使用 hdf5 用于 训练 过程 void dataToMat(vector<Lan…

HDF5 学习总结1

目录 一 HDF5简介 1.1 HDF5背景 1.2 抽象数据模型 1.2.1 File 1.2.2 Group 1.2.3 Dataset 1.2.4. Dataspace 1.2.5. Datatype 1.2.6. Attribute 1.2.7. Property List 1.2.8. Link 一 HDF5简介 1.1 HDF5背景 HDF5:(Hierarchical Data Format)是由美国伊利诺伊大…

HDF5 windows编译 release版本、Debug版本

由于最近急需的一个项目&#xff0c;需要hdf5库&#xff0c;误打误撞&#xff0c;编译成功。特此记录 1、下载源代码 官网下载地址&#xff1a;https://portal.hdfgroup.org/display/support/HDF51.12.2#files 找到如下地址&#xff0c;本人电脑有cmake软件&#xff0c;我下…

[HDF5]如何使用CMake一起编译自己的代码和HDF5库

以一个实际项目来举例 目录 一.目录结构 二.CMakeLists.txt内容 三.执行CMakeLists命令 一.目录结构 1.build放CMake执行后生成的所有的内容&#xff0c;包括最后的工程或可执行文件等; 2.include放工程的头文件&#xff0c;以及HDF5的头文件&#xff0c;可以直接把HDF5中…

HDF5简介

1、介绍 HDF 是用于存储和分发科学数据的一种自我描述、多对象文件格式。HDF 是由美国国家超级计算应用中心&#xff08;NCSA&#xff09;创建的&#xff0c;以满足不同群体的科学家在不同工程项目领域之需要。HDF 可以表示出科学数据存储和分布的许多必要条件。HDF 被设计为&…

HDF5数据的打包与使用(以图像数据为例)

文章目录 1 什么是HDF5数据2 HDF5数据格式的生成3 HDF5数据的查看 注&#xff1a;此篇内容主要作为使用PyTorch构建GAN生成对抗网络博客中&#xff0c;HDF5数据类型的补充介绍。 1 什么是HDF5数据 HDF5 数据是存储在一种名为 Hierarchical Data Format version 5 (HDF5) 的二进…

HDF5-简介

HDF&#xff08;Hierarchical Data Format&#xff09;是一种设计用于存储和组织大量数据的文件格式&#xff0c;最开始由美国国家超算中心研发&#xff0c;后来由一个非盈利组织HDF Group支持.HDF支持多种商业及非商业的软件平台&#xff0c;包括MATLAB、Java、Python、R和Jul…

HDF5到底是什么

HDF5到底是什么 《Python和HDF 5大数据应用》——1.2 HDF5到底是什么-阿里云开发者社区 1.2 HDF5到底是什么 HDF5是一种存储相同类型数值的大数组的机制&#xff0c;适用于可被层次性组织且数据集需要被元数据标记的数据模型。 它跟SQL风格的关系型数据库区别相当大&…