几个Makefile通用模板分享!

嵌入式大杂烩 2022-02-15 21:30

原文:https://blog.csdn.net/qq_20553613/article/details/90649734

家好,我是ZhengN。

本次给大家带来三个Makefile模板:编译可执行程序、编译静态库、编译动态库。

往期相关推文:Makefile常用基础知识梳理!

1、写在前面

对于Windows下开发,很多IDE都集成了编译器,如Visual Studio,提供了“一键编译”,编码完成后只需一个操作即可完成编译、链接、生成目标文件。

Linux开发与Windows不同,Linux下一般用的的gcc/g++编译器,如果是开发ARM下的Linux程序,还需用到arm-linux-gcc/arm-linux-g++交叉编译器。

Linux下也可以实现“一键编译”功能,此时需要一个编译脚本“Makefile”,Makefile可以手动编写,也可以借助自动化构建工具(如scons、CMake)生成。手动编写Makefile是Linux和Windows程序员的区别之一,一般地一个通用的Makefile能够适合大部分Linux项目程序。

2、3个Makefile模板

2.1 编译可执行文件Makefile

VERSION  =1.00
CC   =gcc
DEBUG   =-DUSE_DEBUG
CFLAGS  =-Wall
SOURCES   =$(wildcard ./source/*.c)
INCLUDES   =-I./include
LIB_NAMES  =-lfun_a -lfun_so
LIB_PATH  =-L./lib
OBJ   =$(patsubst %.c, %.o, $(SOURCES))
TARGET  =app

#links
$(TARGET):$(OBJ)
 @mkdir -p output
 $(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET)$(VERSION)
 @rm -rf $(OBJ)
 
#compile
%.o: %.c
 $(CC) $(INCLUDES) $(DEBUG) -c $(CFLAGS) $< -o $@

.PHONY:clean
clean:
 @echo "Remove linked and compiled files......"
 rm -rf $(OBJ) $(TARGET) output 

【要点说明】

【1】程序版本

开发调试过程可能产生多个程序版本,可以在目标文件后(前)增加版本号标识。

VERSION = 1.00
$(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET)$(VERSION)

【2】编译器选择

Linux下为gcc/g++;arm下为arm-linux-gcc;不同CPU厂商提供的定制交叉编译器名称可能不同,如Hisilicon“arm-hisiv300-linux-gcc”。

CC = gcc

【3】宏定义

开发过程,特殊代码一般增加宏条件来选择是否编译,如调试打印输出代码。-D是标识,后面接着的是“宏”。

DEBUG =-DUSE_DEBUG

【4】编译选项

可以指定编译条件,如显示警告(-Wall),优化等级(-O)。

CFLAGS =-Wall -O

【5】源文件

指定源文件目的路径,利用“wildcard”获取路径下所有依赖源文件。

SOURCES =$(wildcard ./source/*.c)

【6】头文件

包含依赖的头文件,包括源码文件和库文件的头文件。

INCLUDES =-I./include

【7】库文件名称

指定库文件名称,库文件有固定格式,静态库为libxxx.a;动态库为libxxx.so,指定库文件名称只需写“xxx”部分,

LIB_NAMES =-lfun_a -lfun_so

【8】库文件路径

指定依赖库文件的存放路径。注意如果引用的是动态库,动态库也许拷贝到“/lib”或者“/usr/lib”目录下,执行应用程序时,系统默认在该文件下索引动态库。

LIB_PATH =-L./lib

【9】目标文件

调用“patsubst”将源文件(.c)编译为目标文件(.o)。

OBJ =$(patsubst %.c, %.o, $(SOURCES))

【10】执行文件

执行文件名称

TARGET =app

【11】编译

%.o: %.c
 $(CC) $(INCLUDES) $(DEBUG) $(CFLAGS) $< -o $@

【12】链接

可创建一个“output”文件夹存放目标执行文件。链接完输出目标执行文件,可以删除编译产生的临时文件(.o)。

$(TARGET):$(OBJ)
 @mkdir -p output
 $(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET).$(VERSION)
 @rm -rf $(OBJ)

【13】清除编译信息

执行“make clean”清除编译产生的临时文件。

.PHONY:clean
clean:
 @echo "Remove linked and compiled files......"
 rm -rf $(OBJ) $(TARGET) output 

2.2 编译静态库Makefile

VERSION     =
CC          =gcc
DEBUG   =
CFLAGS  =-Wall
AR   =ar
ARFLAGS     =rv
SOURCES   =$(wildcard *.c)
INCLUDES    =-I.
LIB_NAMES   =
LIB_PATH  =
OBJ         =$(patsubst %.c, %.o, $(SOURCES))
TARGET      =libfun_a

#link
$(TARGET):$(OBJ)
 @mkdir -p output
 $(AR) $(ARFLAGS) output/$(TARGET)$(VERSION).a $(OBJ)
 @rm -rf $(OBJ)

#compile
%.o: %.c
 $(CC) $(INCLUDES) $(DEBUG) -c $(CFLAGS) $< -o $@
  
.PHONY:clean
clean:
 @echo "Remove linked and compiled files......"
 rm -rf $(OBJ) $(TARGET) output 

【要点说明】

基本格式与“编译可执行Makefile”一致,不同点包括以下。

【1】使用到“ar”命令将目标文件(.o)链接成静态库文件(.a)。静态库文件固定命名格式为:libxxx.a。

2.3 编译动态库Makefile

VERSION   =
CC        =gcc
DEBUG     =
CFLAGS    =-fPIC -shared 
LFLAGS   =-fPIC -shared 
SOURCES   =$(wildcard *.c)
INCLUDES  =-I.
LIB_NAMES =
LIB_PATH  =
OBJ       =$(patsubst %.c, %.o, $(SOURCES))
TARGET    =libfun_so

#link
$(TARGET):$(OBJ)
 @mkdir -p output
 $(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) $(LFLAGS) -o output/$(TARGET)$(VERSION).so
 @rm -rf $(OBJ)
 
#compile
%.o: %.c
 $(CC) $(INCLUDES) $(DEBUG) -c $(CFLAGS) $< -o $@

.PHONY:clean
clean:
 @echo "Remove linked and compiled files......"
 rm -rf $(OBJ) $(TARGET) output 

【要点说明】

基本格式与“编译可执行Makefile”一致,不同点包括以下。

【1】编译选项和链接选项增加“-fPIC -shared ”选项。动态库文件固定命名格式为libxxx.so。

3、Demo

3.1 编译应用程序

编写测试例程,文件存放目录结构如下,头文件存放在“include”目录,库文件存放在“lib”目录,源文件存放在“source”目录,Makefile在当前目录下。


源码1:

/*头文件*/
#ifndef _FUN0_H_
#define _FUN0_H_
#endif

extern void fun0_printf(void);
extern void fun1_printf(void);

/*源文件*/
#include 
#include "fun0.h"

void fun0_printf(void)
{
    printf("Call \'fun0\'. \r\n");
}

源码2:

/*头文件*/
#ifndef _FUN1_H_
#define _FUN1_H_
#endif

extern void fun1_printf(void);

/*源文件*/
#include 
#include "fun1.h"

void fun1_printf(void)
{
    printf("Call \'fun1\'.\r\n");
}

主函数源码:

/*源文件*/
#include 
#include "fun0.h"
#include "fun1.h"
#include "fun_lib_a.h"
#include "fun_lib_so.h"

int main(void)
{
    #ifdef USE_DEBUG
        printf("Debug Application startup.\r\n");
    #endif
    
        fun0_printf();
        fun1_printf();
        fun_lib_a_printf();
        fun_lib_so_printf();
        return 0;
}

库文件,“./lib”目录下存放两个库文件,一个静态库libfun_a.a,一个动态库libfun_so.so。

Makefile文件即为“2.1节”的Makefile模板。

测试运行:

【如果执行文件提示无“libfun_so.so”,则需拷贝“libfun_so.so”到根目录下的“/lib”或者“/usr/lib”目录下,因为系统执行程序,默认从该路径引脚动态库】

3. 2 生成静态库

编写测试例程,生产的库文件即为“3.1节”调用的库文件(libfun_a.a)。文件存放目录结构如下:

源文件:

/*头文件*/
#ifndef _FUN_LIB_A_H_
#define _FUN_LIB_A_H_
#endif

extern void fun_lib_a_printf(void);

/*源文件*/
#include 
#include "fun_lib_a.h"

void fun_lib_a_printf(void)
{
    printf("Call \'fun_lib_a\'.\r\n");
}

Makefile文件即为“2.2节”的Makefile模板。

编译生成静态库:

3. 3 生成动态库

编写测试例程,生产的库文件即为“3.1节”调用的库文件(libfun_so.so)。文件存放目录结构如下:

源文件:

/*头文件*/
#ifndef _FUN_LIB_SO_H_
#define _FUN_LIB_SO_H_
#endif

extern void fun_lib_so_printf(void);

/*头文件*/

#include 
#include "fun_lib_so.h"

void fun_lib_so_printf(void)
{
    printf("Call \'fun_lib_so\'.\r\n");
}

编译生成动态库:


温馨提示

由于微信公众号近期改变了推送规则,如果您想经常看到我们的文章,可以在每次阅读后,在页面下方点一个「赞」或「在看」,这样每次推送的文章才会第一时间出现在您的订阅列表里。

免责声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。


往期推荐:

跨平台构建工具,cmake是 yyds ?bjd !

C语言、嵌入式中几个非常实用的宏技巧

分享一个自用的、极简的log模块!

分享一个很酷的IDE!软工必备

C语言、嵌入式位操作精华技巧大汇总

嵌入式大杂烩周记 | 第 1 期

Hello系列 | cmake简明基础知识

干货 | 项目乏力?nanopb助你一臂之力

在公众号聊天界面回复1024,可获取嵌入式资源;回复 ,可查看文章汇总。

点击阅读原文,查看更多分享。

嵌入式大杂烩 专注于嵌入式技术,包括但不限于C/C++、嵌入式、物联网、Linux等编程学习笔记,同时,内包含大量的学习资源。欢迎关注,一同交流学习,共同进步!
评论 (0)
  • 在2024年的科技征程中,具身智能的发展已成为全球关注的焦点。从实验室到现实应用,这一领域正以前所未有的速度推进,改写着人类与机器的互动边界。这一年,我们见证了具身智能技术的突破与变革,它不仅落地各行各业,带来新的机遇,更在深刻影响着我们的生活方式和思维方式。随着相关技术的飞速发展,具身智能不再仅仅是一个技术概念,更像是一把神奇的钥匙。身后的众多行业,无论愿意与否,都像是被卷入一场伟大变革浪潮中的船只,注定要被这股汹涌的力量重塑航向。01为什么是具身智能?为什么在中国?最近,中国具身智能行业的进
    艾迈斯欧司朗 2025-02-28 15:45 372浏览
  • 压力传感器是指能感受压力信号,并能按照一定的规律将压力信号转换成可用的电信号的器件或装置。压力传感器通常由压力敏感元件和信号处理单元组成,按不同测压方法,压力传感器可分为表压传感器、差压传感器和绝压传感器;按不同测压原理,压力传感器又可分为常见的压阻式压力传感器、电容式压力传感器、扩散硅压力传感器、蓝宝石压力传感器与陶瓷压力传感器等。作为工业自动化与智能化的关键器件,压力传感器在各类工业设备中扮演着不可或缺的角色,其通过精确感知和转换物理压力信号,为工业物联网(IIoT)构建起了高效精确的“压力
    华普微HOPERF 2025-03-03 10:19 188浏览
  • 在当今数据驱动的世界,内存解决方案需要的不仅仅是原始性能。贞光科技代理的紫光国芯全系列存储产品提供定制化解决方案,解决各行业面临的独特挑战,同时确保可靠性、兼容性和面向未来的创新。打破“唯性能论”,迎接多元化存储需求一直以来,高性能似乎成了衡量存储产品的唯一标准。 没错,速度快、效率高,固然重要。 但话说回来, 难道所有应用场景,都对性能有着“变态”级的需求吗? 答案显然是否定的。 就像穿鞋一样,合脚才是最重要的, 一味追求“跑得快”, 反而容易磨脚,甚至崴脚!在实际应用中,各行各业对存储的需求
    贞光科技 2025-03-03 17:05 106浏览
  • DeepSeek的风还吹到了TV圈。去年,人工智能领域迎来了重大突破,然而对大多数人而言,它依旧是个颇为模糊的概念。即便是如ChatGPT这样的产品,给人最直接的感受也仅仅是一个相较于Siri更为智能的语音交互工具。直至今年,DeepSeek的惊艳亮相,人们真正感受到了生成式人工智能在实际应用中的价值。在这股浪潮的推动下,电视厂商们也纷纷跟上了脚步。2月11日,海信电视宣布正式接入DeepSeek,并支持满血R1和V3版本自由切换,成为行业首个搭载深度思考智能体的电视品牌。长虹电视紧随其后,宣布
    刘旷 2025-03-03 09:55 249浏览
  • 在2025年世界移动通信大会(MWC 2025)期间,紫光展锐携手美格智能正式推出了基于紫光展锐V620平台的第二代5G Sub6G R16模组SRM812,以超高性价比方案,全面赋能合作伙伴,加速5G规模化应用在各垂直领域的全面落地。展锐芯赋能,全面支持R16关键特性SRM812模组基于紫光展锐推出的V620平台设计,V620是业界首款全面支持R16的5G宽带物联网芯片平台,具备强劲的射频能力和全网通特性。得益于此,SRM812成为业界首批全面支持5G R16宽带物联网特性的芯片平台。SRM8
    紫光展锐 2025-03-04 19:55 79浏览
  • 2025年世界移动通信大会(MWC 2025)期间,紫光展锐联合移远通信,正式发布了全面支持5G R16特性的模组RG620UA-EU,以强大的灵活性和便捷性赋能产业。展锐芯加持,关键性能优异RG620UA-EU模组基于紫光展锐V620平台开发,搭载4核Arm®Cortex®-A55 CPU,符合3GPP R16标准,在传输速率、计算能力、R16关键特性等方面表现优异。该模组配备了丰富的功能接口,包括USXGMII、PCIe3.0、USB3.1、SDIO3.0、UART、SPI、I2S、I2C、
    紫光展锐 2025-03-04 19:54 80浏览
  • 文/Leon编辑/cc孙聪颖在中国制造转向“智造”的过程中,一批80、90后企业创始人闪亮登场,用互联网思维进行创新,在全球市场取得了傲人的成绩,如大疆汪滔、宇树科技王兴兴、影石Insta360刘靖康,都是各自领域的佼佼者。在引领全球市场后,独角兽企业的下一步自然是上市。据悉,中国证监会于2025年2月26日正式批复影石Insta360创新科技股份有限公司(以下简称影石Insta360)的IPO申请,拟在上交所科创板上市,中信证券为保荐机构,拟募集资金4.64亿元。影石Insta360主要从事手
    华尔街科技眼 2025-03-03 18:40 160浏览
  • 振动样品磁强计是一种用于测量材料磁性的精密仪器,广泛应用于科研、工业检测等领域。然而,其测量准确度会受到多种因素的影响,下面我们将逐一分析这些因素。一、温度因素温度是影响振动样品磁强计测量准确度的重要因素之一。随着温度的变化,材料的磁性也会发生变化,从而影响测量结果的准确性。因此,在进行磁性测量时,应确保恒温环境,以减少温度波动对测量结果的影响。二、样品制备样品的制备过程同样会影响振动样品磁强计的测量准确度。样品的形状、尺寸和表面处理等因素都会对测量结果产生影响。为了确保测量准确度,应严格按照规
    锦正茂科技 2025-02-28 14:05 218浏览
  • 2020年,世界经济论坛发布了《将来工作报告》,预言了人工智能 (AI)、机器人和自动化将在五年内对劳动力市场带来反天性的变化。最震撼人心的预测是:85亿个工位将消失,97亿个新工位将被创造。这个信息给我们提出了一些骂烈的疑问:AI究竟会消灭哪些工作?管理者的规划依然重要吗?AI会代替我们的管理之路吗?AI不会替代管理者,会进一步增强他们随着AI在机器学习、自然语言处理和预测分析方面的进步,许多人对AI接管事务表示担心。但研究显示,大多数情况下,AI将作为工具与管理者协同完成任务,而不是替换他们
    优思学院 2025-03-01 12:22 181浏览
  • 1,微软下载免费Visual Studio Code2,安装C/C++插件,如果无法直接点击下载, 可以选择手动install from VSIX:ms-vscode.cpptools-1.23.6@win32-x64.vsix3,安装C/C++编译器MniGW (MinGW在 Windows 环境下提供类似于 Unix/Linux 环境下的开发工具,使开发者能够轻松地在 Windows 上编写和编译 C、C++ 等程序.)4,C/C++插件扩展设置中添加Include Path 5,
    黎查 2025-02-28 14:39 211浏览
  • 中小企业(SME)对全球经济的贡献日益显著,不仅是发展中国家的经济支柱,通常还是其经济快速增长的关键部分。中小企业的其他关键作用还包括促进创业和创新,从而保证竞争力。从这一点来说,中小企业助力了许多大公司,并对世界经济做出重大贡献。本章将介绍中小企业的定义和经济份额,分析其特点以及它们与大型企业的区别。中小企业的定义任何组织在制订计划和策略时,最重要的都是了解业务的性质和类型。全球各企业的分类主要基于它们的体量,例如固定资产、产值、资金和员工数量。从大的分类来讲,大公司被划归为一种类型,而所有其
    优思学院 2025-03-04 11:07 77浏览
  • 在现代各种工业设备的复杂电路中,栅极驱动芯片虽不常被大众提及,却扮演着至关重要的角色。栅极驱动芯片是低压控制器和高压电路之间的缓冲电路,主要用于放大控制器的控制信号,从而令功率器件实现更快速高效的导通和关断,是保障电子设备稳定、高效运行的核心元件之一。驱动芯片的类型(按结构划分)电力电子应用基于功率器件技术,而无论是MOSFET、IGBT,还是SiC MOSFET等功率器件都需要相应的栅极驱动芯片(Gate Driver IC)。选择一款合适的驱动芯片,不仅可以简化相应电气系统的设计复杂度,还可
    华普微HOPERF 2025-03-04 14:40 80浏览
  •           近日受某专业机构邀请,参加了官方举办的《广东省科技创新条例》宣讲会。在与会之前,作为一名技术工作者一直认为技术的法例都是保密和侵权方面的,而潜意识中感觉法律有束缚创新工作的进行可能。通过一个上午学习新法,对广东省的科技创新有了新的认识。广东是改革的前沿阵地,是科技创新的沃土,企业是创新的主要个体。《广东省科技创新条例》是广东省为促进科技创新、推动高质量发展而制定的地方性法规,主要内容包括: 总则:明确立法目
    广州铁金刚 2025-02-28 10:14 147浏览
  • 一、VSM的基本原理震动样品磁强计(Vibrating Sample Magnetometer,简称VSM)是一种灵敏且高效的磁性测量仪器。其基本工作原理是利用震动样品在探测线圈中引起的变化磁场来产生感应电压,这个感应电压与样品的磁矩成正比。因此,通过测量这个感应电压,我们就能够精确地确定样品的磁矩。在VSM中,被测量的样品通常被固定在一个震动头上,并以一定的频率和振幅震动。这种震动在探测线圈中引起了变化的磁通量,从而产生了一个交流电信号。这个信号的幅度和样品的磁矩有着直接的关系。因此,通过仔细
    锦正茂科技 2025-02-28 13:30 157浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦