一个适用各类场合的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.通用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_
#endifextern void fun0_printf(void);
extern void fun1_printf(void);/*源文件*/
#include <stdio.h>
#include "fun0.h"void fun0_printf(void)
{printf("Call \'fun0\'. \r\n");
}

源码2

/*头文件*/
#ifndef _FUN1_H_
#define _FUN1_H_
#endifextern void fun1_printf(void);/*源文件*/
#include <stdio.h>
#include "fun1.h"void fun1_printf(void)
{printf("Call \'fun1\'.\r\n");
}

主函数源码

/*源文件*/
#include <stdio.h>
#include "fun0.h"
#include "fun1.h"
#include "fun_lib_a.h"
#include "fun_lib_so.h"int main(void)
{#ifdef USE_DEBUGprintf("Debug Application startup.\r\n");#endiffun0_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_
#endifextern void fun_lib_a_printf(void);/*源文件*/
#include <stdio.h>
#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_
#endifextern void fun_lib_so_printf(void);/*头文件*/#include <stdio.h>
#include "fun_lib_so.h"void fun_lib_so_printf(void)
{printf("Call \'fun_lib_so\'.\r\n");
}

编译生成动态库

db93e5d40f6f1fc9cfce9d8122de63b4.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464521.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

毕业十年|我的嵌入式AI学习路线(笔记、代码)

嵌入式从业者接下来会有怎样的黄金十年&#xff1f;在物联网和人工智能的促进下&#xff0c;嵌入式在未来的5-10年内会迎来更多的发展机会&#xff0c;一方面嵌入式开发会迎来更多的应用场景&#xff0c;另一方面嵌入式开发的技术体系也会逐渐丰富&#xff0c;从而拓展物联网开…

在艰苦年代,买不起万用表,怎么测量电路电压?

如何测量电压&#xff1f;有这样一张图片&#xff1a;用舌头来测量&#xff1f;开玩笑的吧&#xff01;不过这张照片勾起了我的回忆&#xff1a;有一位玩电子的老前辈&#xff0c;现在已经70多岁了。和他聊天&#xff0c;他说&#xff0c;当年他们玩电子&#xff0c;条件非常艰…

VBA学习_5:流程控制

1、If If Range("B2").Value >60 Then Range("C2").Value "及格" Else Range("C2").Value"不及格"如果。。。那么。。。。否则。。。。 If Range("B2").Value > 60 ThenRange("C2").Value "…

嵌入式的薪资还是挺低的

我最近和一个比较好的朋友聊天&#xff0c;我这个朋友在一家比较传统的公司&#xff0c;在这个公司做嵌入式软件开发&#xff0c;偏系统方向的。然后最近拿到了几个不错的offer&#xff0c;让我帮忙看看。这几个offer我就不发出来给大家看了。可以肯定的是&#xff0c;这几个of…

新手必看!单片机掉电检测与数据掉电保存方案

单片机在正常工作时&#xff0c;因某种原因造成突然掉电&#xff0c;将会丢失数据存储器&#xff08;RAM&#xff09;里的数据。在某些应用场合如测量、控制等领域&#xff0c;单片机正常工作中采集和运算出一些重要数据&#xff0c;待下次上电后需要恢复这些重要数据。因此&am…

Study Notes ASP.Net 之Theme Skin

基本概念&#xff1a; Theme 和 Skin用以定义页面中各个控件的显示样式&#xff0c;如字体大小&#xff0c;前/后景色等等。一个Theme可以包括多个Skin&#xff0c;一个Skin可以定义多个控件的样式。目的&#xff1a; 使得页面样式的制作可以与页面制作分工进行。<?xml:nam…

推荐一个值得加入C++开发者俱乐部

之前我有篇文章提起过&#xff0c;开始进入某厂是从0开始做项目的&#xff0c;当时看到那套SDK软件&#xff0c;而且97%都是用C写的&#xff0c;我的头都大了。后面也是坚持不断的学习&#xff0c;积累&#xff0c;修改&#xff0c;向身边同事请教&#xff0c;加入优秀社群学习…

DataGrid 完全攻略之四 (实现统计)

前台代码&#xff1a;html<% Page language"c#" Codebehind"UserCount.aspx.cs" AutoEventWireup"false" Inherits"MsDataGrid.UserCount" %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >…

Window系统下安装Redis

下载Redis Redis官网只提供Linux版本&#xff0c;Windows版本只能去GitHub上下载 Redis官网下载地址&#xff1a;http://redis.io/download GitHub下载地址&#xff1a;https://github.com/MSOpenTech/redis/tags 安装Redis 创建redis文件夹&#xff0c;解压到此目录下&#xf…

iTunes“解决方案”发展历程及研究(上)

以下内容来自于我的《iTunes内容解决方案研究》的PPT&#xff0c;懒得往上敲字了&#xff0c;直接以图片的形式发布&#xff0c;有需要的&#xff0c;我可以提供pdf版本给你&#xff0c;版权所有

Linux下的memcpy函数

之前写过一篇关于 memcpy函数面试的文章几个简单的笔试题里面的代码使用的是char指针来实现&#xff0c;今天我们来看看Linux下面的memcpy函数&#xff0c;它的实现上还是有一些巧妙的。void * memcpy(void * dest, const void *src, size_t n) {if (!(((unsigned long) dest ^…

linux命令行抓取网页快照-(xvfb+CutyCapt)

linux命令行抓取网页快照-&#xff08;xvfbCutyCapt&#xff09;又一个 WordPress 博客Browse: Home / 2009 / 十一月 / linux命令行抓取网页快照-&#xff08;xvfbCutyCapt&#xff09;linux命令行抓取网页快照-&#xff08;xvfbCutyCapt&#xff09;By saymoon on 2009年11月…

php过waf木马,一款过waf的一句话木马分析 | CN-SEC 中文网

摘要中午&#xff0c;下班回来&#xff0c;就看一个朋友给我发了几个马儿 让我看看解解密码 很简单中午&#xff0c;下班回来&#xff0c;就看一个朋友给我发了几个马儿 让我看看解解密码 很简单猛不猛我不知道 那时候手机 太长的看着就烦 就回到家瞅瞅了首先我们看这…

你没干什么坏事,你怕什么?

如图我很久就知道深信服这家企业&#xff0c;记得是几年前&#xff0c;我有一个同学跟我说&#xff0c;有一个比较厉害的朋友在这个企业上班&#xff0c;拿到了非常不错的薪水&#xff0c;我如果想去这个公司看看&#xff0c;可以让这位朋友帮忙搭线。后面查这个企业&#xff0…

python用循环打出阶梯图形,matplotlib阶梯图的实现(step())

step函数概述step函数用于绘制阶梯图。根据源码可知&#xff0c;step函数是对plot函数的轻量级封装&#xff0c;很多概念和用法与plot函数非常相似。def step(self, x, y, *args, wherepre, dataNone, **kwargs):cbook._check_in_list((pre, post, mid), wherewhere)kwargs[dra…

嵌入式还有哪些风口值得入?

大家好&#xff0c;我是写代码的篮球球痴前两天发了篇文章说到嵌入式薪资的&#xff0c;很多人想知道目前有哪些不错的行业可以加入&#xff0c;这篇文章罗列了很多风口行业。我相信&#xff0c;半导体芯片会是很重要的方向&#xff0c;但是不管路修得多好&#xff0c;都需要汽…

java 统计单词个数和标点符号

把随机输入的一句话比如:Its only a test!存放在一个char[]的数组中&#xff0c;统计char[]中的单词个数和标点符号的个数。 package com.faintbear; import java.io.*; publicclassTest{ public static void main(String[] args) throws Exception{ BufferedReade…

Luogu 4244 [SHOI2008]仙人掌图

BZOJ 1023 如果我们把所有的环都缩成一个点&#xff0c;那么整张图就变成了一棵树&#xff0c;我们可以直接$dp$算出树的直径。 设$f_x$表示$x$的子树中最长链的长度&#xff0c;那么对于$x$的每一个儿子$y$&#xff0c;先用$f_x f_y 1$更新答案&#xff0c;再用$f_y 1$更新…

outlook 2007 自动答复邮件

outlook 2007自动答复邮件 步骤 1&#xff1a;创建邮件模板 提示 从 Microsoft Office Online 下载正式&#xff08;英文&#xff09;或者非正式&#xff08;英文&#xff09;外出邮件模板。 在“文件”菜单上&#xff0c;指向“新建”&#xff0c;然后单击“邮件”。在“选项…

我的朋友去国外出差回不来了

年前&#xff0c;我一个朋友因为项目调试需要去国外出差&#xff0c;出国的时候好好的&#xff0c;然后飞到当地没几天疫情突然爆发&#xff0c;国内取消了那个国家的航班&#xff0c;然后就直接滞留在当地回不来了。我朋友从事的是硬件开发&#xff0c;包括器件选型、原理图设…