makefile

Makefile命令参数、调用其他Makefile、嵌套 介绍make运行参数和调用其他makefile 阅读详情

1.hello.c

#include <stdio.h>
int main()
{
    printf("Hello World!\n");
    return 0;
}

2.Makefile

hello : hello.o
    cc -o hello hello.o

hello.o : hello.c
    cc -c hello.c

clean : 
    rm hello.o

说明:cc -o hello hello.o前面是一个tab的空格

3.执行make,产生可执行文件hello

输出如下:
cc -c hello.c
cc -o hello hello.o

4.执行make clean,删除产生的中间文件hello.o

输出如下:
rm hello.o


另转:http://hi.baidu.com/s_rlzheng/blog/item/4bc10a06892e217d030881ef.html

  本来早就应该学Makefile了,只是我偷懒,现在才学呵呵^_^makefile的好处叫我说,老实说我也说不出什么之所以然来,但是可以肯定的是它是linux平台的软件工程师都要必备的知识^_^

一、程序的编译及链接

    我们编译程序,无非是想要得到一个可执行文件,而这个过程则是经过这两步:

***.c->编译->***.o->链接->可执行文件。即.c经过编译得到.o文件,.o文件是一个中间文件,再对这些中间文件进行链接最终可得到可执行文件。

二、Makefile的规则

首先,来看一看Makefile的书写规则:

target ... : prerequisites ...

            command

            ...

            ...

    target也就是一个目标文件,可以是.o文件,也可以是执行文件,还可以是一个标签(Label)。

    prerequisites就是,要生成那个target所需要的文件或是目标。

    command也就是make需要执行的命令(任意的Shell命令)。这里要注意的是在命令前面要加上一个tab键,不是空格,是按一个tab键按出来的空格。

     这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比 target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则,也就是Makefile中最核心的内容。这是Makefile的主线和核心,但要写好一个Makefile还得继续努力。

三、一个最简单的Makefile例子

如有一个工程,含有3个头文件及四个c文件,那为了生成所需的可执行文件,这时的Makefile可以这样写:

test:main.o t1.o t2.o t3.o

     gcc –o test main.o t1.o t2.o t3.o

main.o:main.c

     gcc –c main.c

t1.o:t1.c t1.h

     gcc –c t1.c

t2.o:t2.c t2.h

     gcc –c t2.c

t3.o:t3.c t3.h

     gcc –c t3.c

clean:

     rm test main.o t1.o t2.o t3.o

到这里一个最简单的makefile就写好了,把它的名字保存为Makefile就可以了,这时你只要在终端敲一下make,它就自动帮你编译链接了^_^如果敲入make clean,它将删掉那些中间文件及可执行文件。

***************************************************************************

工程中的代码分别存放在add/add_int.c、add/add_float.c、add/add.h、sub/sub_int.c、sub/sub_float.c、sub/sub.h、main.c中。

Makefile的一个具体的实例

 

文件main.c

#include <stdio.h>

#include "add.h"            

#include "sub.h"

intmain(void)

{

      int input = 0;

      int a = 10, b = 12;

      float x= 1.23456,y = 9.87654321;

      

      printf("int a+b IS:%d\n",a+b);

      printf("int a-b IS:%d\n",a-b);

      printf("float x+y IS:%f\n",x+y);

      printf("float x-y IS:%f\n",x-y);

 

 

      return 0;      

}

加操作 

#ifdef __ADD_H__

#define __ADD_H__

extern int add_int(int a, int b);

extern float add_float(float a, float b);

#endif  

float add_float(float a, float b)

{

      return a+b;  

}  

intadd_int(int a, int b)

{

      return a+b;  

}

减操作

#ifdef __ADD_H__

#define __ADD_H__

extern float sub_float(float a, float b);

extern int sub_int(int a, int b);

#endif 

float sub_float(float a, float b)

{

      return a-b;   

} 

intsub_int(int a, int b)

{

      return a-b;   

}

命令行编译程序:

#gcc-c add/add_int.c -o add/add_int.o     #生成add_int.o目标函数

#gcc-c add/add_float.c -o add/add_float.o   #生成add_float.o目标函数

#gcc-c sub/sub_int.c -o sub/sub_int.o      #生成sub_int.o目标函数

#gcc-c sub/sub_float.c -o sub/sub_float.o    #生成sub_float.o目标函数

#gcc-c main.c -o main.o                 #生成main.o目标函数

#gcc-o casu add/add_int.o add/add_float.o sub/sub_int.o sub/sub_float.omain.o

#链接生成cacu

多文件的makefile:

#生成casu,“;”右边为目标

casu:add_int.o add_float.o sub_int.o sub_float.omain.o

      gcc -o casu add/add_int.o add/add_float.o \          #\为连接符

                    sub/sub_int.o sub/sub_float.o main.o    

#生成add_int.o的规则,将add_int.c编译生成目标文件add_int.o

add_int.o:add/add_int.c add/add.h

      gcc -c -o add/add_int.o add/add_int.c

#生成add_float.o的规则

add_float.o:add/add_float.c add/add.h

      gcc -c -o add/add_float.o add/add_float.c

#生成sub_int.o的规则

sub_int.o:sub/sub_int.c sub/sub.h

      gcc -c -o sub/sub_int.o sub/sub_int.c

#生成sub_float.o的规则

sub_float.o:sub/sub_float.c sub/sub.h

      gcc -c -o sub/sub_float.o sub/sub_float.c

#生成main.o的规则

main.o:main.c add/add.h sub/sub.h

      gcc -c -o main.o main.c -Iadd -Isub

      

#清理规则

clean:

      rm -f casu add/add_int.o add/add_float.o \

           sub/sub_int.o sub/sub_float.o main.o

使用自定义变量的makefile文件:

CC = gcc                                #CC定义成gcc

CFLAGES =   -Iadd -Isub -O2   #加入头文件搜索路径sub和add,O2为优化#目标文件

OBJS = add/add_int.o add/add_float.o \

             sub/sub_int.o sub/sub_float.o main.o

TARGET = casu                          #生成的可执行文件

RM = rm -f                              #删除的命令

$(TARGET):$(OBJS)                      #TARGET目标,需要先生成OBJS目标

      $(CC) -o $(TARGET) $(OBJS) $(CFLAGES)   #生成可执行文件

$(OBJS):%.o:%.c         #将OBJS中所有扩展名为.o的文件替换成扩展名为.c的文件

      $(CC) -c $(CFLAGES) $< -o $@       #采用CFLAGS指定的选项编译生成目标文件

clean:                              #清理

      -$(RM) $(TARGET) $(OBJS)          #删除所有的目标文件和可执行文件

使用预定义变量的makefile文件:

CFLAGES =   -Iadd -Isub -O2              #编译选项

OBJS= add/add_int.o add/add_float.o \

               sub/sub_int.osub/sub_float.o main.o

TARGET = casu                         #生成的可执行文件

$(TARGET):$(OBJS)                      #TARGET目标,需要先生成OBJS目标

      $(CC) -o $(TARGET) $(OBJS)$(CFLAGES)  #生成可执行文件

$(OBJS):%.o:%.c         #将OBJS中所有扩展名为.o的文件替换成扩展名为.c的文件

      $(CC) -c $(CFLAGES)$< -o $@       #采用CFLAGS指定的选项编译生成目标文件

clean:                              #清理

      -$(RM) $(TARGET)$(OBJS)          #删除所有的目标文件和可执行文件

使用自动变量的makefile文件:

CFLAGES =   -Iadd -Isub -O2              #编译选项

OBJS= add/add_int.o add/add_float.o \

               sub/sub_int.osub/sub_float.o main.o

TARGET = casu                          #生成的可执行文件

$(TARGET):$(OBJS)                      #TARGET目标,需要先生成OBJS目标

      $(CC) -o  $@  $^$(CFLAGES)         #生成可执行文件

$(OBJS):%.o:%.c         #将OBJS中所有扩展名为.o的文件替换成扩展名为.c的文件

      $(CC) -c $<  $(CFLAGES) -o$@     #采用CFLAGS指定的选项编译生成目标文件

clean:                              #清理

      -$(RM) $(TARGET) $(OBJS)          #删除所有的目标文件和可执行文件

使用搜索路径的makefile文件:

CFLAGES =   -Iadd -Isub -O2  

OBJSDIR = .objs

VPATH = add:sub:.        

OBJS= add_int.o add_float.o sub_int.o sub_float.o main.o

TARGET = casu                          

$(TARGET):$(OBJSDIR) $(OBJS)     #先检测OBJSDIR和OBJS依赖项是否存在                

      $(CC) -o $(TARGET) $(OBJSDIR)/*.o $(CFLAGES)

 #将OBJSDIR目录中所有的.o文件链接成casu          

$(OBJS):%.o:%.c         

      $(CC) -c $< $(CFLAGES) -o $(OBJSDIR)/$@ #生成目标文件,存放在OBJSDIR目录中

$(OBJSDIR):

      mkdir -p ./$@           #建立目录,-p选项可以忽略父目录不存在的错误

clean:                                

      -$(RM) $(TARGET)       #删除casu

      -$(RM) $(OBJSDIR)/*.o   #删除OBJSDIR目录下的所有.o文件

使用自动推导规则的makefile:

CFLAGS = -Iadd -Isub -O2        # 用户自定义变量

VPATH=add:sub               #搜索路径

OBJS= add_int.o add_float.o sub_int.o sub_float.o main.o

TARGET = cacu

$(TARGET):$(OBJS)            #OBJS依赖项的规则自动生成

      $(CC) -o $(TARGET) $(OBJS) $(CFLAGS)    #链接文件

clean:

      -$(RM) $(TARGET)        #“-”表示当前操作失败时不报错,命令继续执行

      -$(RM) $(OBJS)

使用函数的makefile文件:

CC =gcc                              #CC定义成gcc

VPATH =add:sub

CFLAGES =   -Iadd -Isub -O2    #加入头文件搜索路径sub和add,O2为优化#目标文件

TARGET = casu                        #生成的可执行文件

DIRS= sub add .                    #DIRS字符串的值为目录add、sub和当前目录

FILES = $(foreach dir, $(DIRS),$(wildcard$(dir)/*.c))  #查找所用目录下的.c文件

OBJS = $(patsubst %.c,%.o,$(FILES))          #将.c替换成.o

$(TARGET):$(OBJS)                       #TARGET目标,需要先生成OBJS目标

      $(CC) -o $(TARGET) $(OBJS) $(CFLAGES)  #生成可执行文件

clean:                                 #清理

      -$(RM) $(TARGET) $(OBJS)             #删除所有的目标文件和可执行文件



【makefile】顶层Makefile向下层Makefile传递参数 阅读详情

相关推荐

Cadence仿真数字电路功耗

Cadence仿真数字电路功耗 数字电路的功耗采用平均电流乘电源电压获得,所以本文的关键是测量平均电流。 仿真前设置好仿真参数后,在仿真的ADE街边选择:outputs➡to be saved➡select on design 选择电源的负端电流(若选择正端,则电流为负): 选择完成后,在ADE界面讲所选节点的plot也勾选上,点击run。仿真完成后自动显示波形。在波形上选中该电流曲线,右击选择:send to➡calculator 注意上图中,商店前的波形不稳定,需要进行截取。在calculator

qq_41519780的博客 1万+

CFLAGS用法

CFLAGS 表示用于 C 编译器的选项, CXXFLAGS 表示用于 C++ 编译器的选项。 这两个变量实际上涵盖了编译和汇编两个步骤。 CFLAGS: 指定头文件(.h文件)的路径,如:CFLAGS=-I/usr/include -I/path/include。同样地,安装一个包时会在安装路径下建立一个include目录,当安装过程中出现问题时,试着把以前安装的包的include目录加入到该变量中来。 LDFLAGS :gcc 等编译器会用到的一些优化参数,也可以在里面指定库文件的位置。用法:LDFLA

qq_40309341的博客 6070

ESP32 Arduino学习篇 (一) 引脚和串口的基本使用

简单来讲arduino就是通过源代码控制开发板的信号输入输出从而实现对一些电子元件的控制,例如LED灯,蜂鸣器,按键arduino程序首先来讲arduino程序是基于C语言,而实现类似对于LED灯和蜂鸣器的简单控制只需简单C语言知识即可实现。arduino程序是基于函数的,而在arduino的库有很多函数,我们只需要调用即可。arduino的程序主体是**setup()函数和loop()**函数以及其它在使用过程中需要构建的函数:setup()函数。

DOF526570的博客 1万+

Make的使用与Makefile的写法结构

Make: 工程管理器,也叫“自动编译管理器”, “自动”的意思是指它能够根据文件更改的时间自动发现更新过的文件而减少编译的工作量, 同时,它通过读入Makefile文件的内容来执行大量的编译工作 Makefile基本结构 是Make读入的唯一配置文件 由make工具创建的目标体(target),通常是目标文件或可执行文件 要创建的目标体所依赖的文件(dependency_file) 创建每个目标体时需要运行的命令(command) 注意:命令行前面必须是一个”TAB键”,否则编译错误为:*** missi

weixin_52668204的博客 510

Simulink封装与库的建立

第二栏设置标签,第三栏是对应变量名,即是第一张图中的常量名。1.先将输入与常量模块相连接并生成子系统。按照如图所示添加修改,最后的效果如下图。封装子系统搭建测试环境。

lensyu1994的博客 1739

做小程序支付时,我是怎么被“虚拟支付”绊了一跤的

微信小程序支付开发中,普通支付与虚拟支付存在本质差异。开发者常误将虚拟权益(会员、点数等)当作普通商品支付,导致审核失败。两者在审核关注点、结算方式、API调用及平台政策上都截然不同。关键点在于:1)先明确交易对象类型;2)产品命名需真实反映权益性质;3)支付成功≠业务完成;4)审核说明要详细描述交付逻辑;5)避免依赖过时规则。正确顺序应是:判断商品属性→选择支付类型→设计订单系统→准备审核材料。这个认知差异比技术实现更重要,提前理解平台规则可大幅减少返工。

zhurizhe71的学习之路 2580

2.变量

变量的作用域 局部变量:在规则中声明的变量为局部变量。自动化变量是局部变量。# 此时CFLAGES的值是:-g prog: CFLAGES = -g全局变量 赋值符号 = 赋值 := 赋值,但不使用未定义的变量 += 追加赋值 override 修饰符,用来保护变量的值。使用该修饰符的变量,其值无法在命令行中进行修改。 自定义变量自定义的变

TonyaBaSy 324

【python快速编程入门(第二版)黑马程序员课后编程题】

python快速编程入门(第二版)黑马程序员课后编程题

weixin_46167259的博客 1万+

Makefile的编写

代码目录: add/add_int.c add/add_float.c add/add.h sub/sub_int.c sub/sub_float.c sub/sub.h main.c 文件main.c #include #include "add.h"             #include "sub.h" intmain(void) {

rayylee 871

告别手动打卡:逍遥模拟器+宥马运动自动跑步脚本配置全流程

本文详细介绍了如何利用逍遥模拟器和自动化脚本实现宥马运动的自动跑步功能,告别手动打卡的繁琐。从环境准备、脚本部署到定位配置和智能调度,全流程指导用户完成自动化设置,提升效率并确保运动数据的真实性。

weixin_42532473的博客 537

SAP 管道业务(Pipeline Procurement)是用于水、电、气等不间断供应且无库存管理的物料采购场景,核心是消耗即记账、无库存持有,通过 MM-FI 集成实现实时负债与成本过账

摘要:SAP管道业务适用于水电气等无库存管理的物料采购场景,通过消耗即记账机制实现实时负债与成本过账。核心配置包括创建PIPE物料类型(无库存管理)、维护管道采购信息记录、配置自动记账科目等。SAP PO可集成外部系统实现流程自动化,如自动过账提取数据、发票校验等。实施要点在于物料主数据、信息记录和科目确定的精准配置,以及PO接口的可靠对接,最终构建端到端的高效采购与财务结算体系。

金牌架构师 748

Makefile CFLAGS

CFLAGS的值是在Makfile中是gcc的编译选项,可以再CFLGAS加上想要定义的宏、include的搜索路径、共享库(静态库和动态库)文件搜索路径、生成的动态库文件等信息。 Makefile中的变量赋值一般使用 := 的方式,这样变量只在定义的时候将所有变量展开,不会在使用的时候展开,这样避免了递归无休止展开的情况。 关于gcc的编译选项参考《嵌入式linux应用手册》

xiaoshengqdlg的专栏 1584

Flask基础项目:从零到一搭建用户管理系统

本文介绍了一个基于Flask的用户管理系统,具有完整的增删改查功能。系统采用SQLAlchemy ORM进行数据库操作,自动处理SQL注入并首次运行时创建表结构。主要特点包括:实时统计用户总数和平均年龄、智能即时搜索、前后端双重数据验证、邮箱唯一性检查、流畅动画效果和响应式设计。后端使用Flask框架实现RESTful API,前端采用现代化UI设计,支持异步操作不阻塞界面。系统安装简单,只需创建数据库并安装依赖即可运行,适合作为基础用户管理系统的参考实现。

数据知道的博客 3837

什么是makefile

1什么是Makefile 在之前学习C程序的编译过程中,我们知道编译一个程序还比较简单, 如果要编译多个文件,或者不同文件夹中的文件,需要生成不同的库文件,以及确定这些文件的编译先后顺序,往往所需要的命令行特别多,而且比较复杂,甚至对于以后项目的维护也比较麻烦。 再想想如果我们需要编译Linux内核这样好几W个文件的项目难道需要我们一个命令的输入吗 ? 那估计是一场噩梦。 那么这个时候如果我们能够把所有的编译规则全部规范到文件中,然后通过解析该文件去执行对应的编译...

jinking01的专栏 1万+

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Makefile文件:Makefile介绍

本文介绍Makefile的一些基本概念以及简单的用法。本文所用的编译器是Hightec tricore v4.9.1.0。 文章目录1 Makefile的作用2 Makefile的规则3 一个简单的Makefile3.1 帮助文档中的例子3.2 例程1:一个简单的Makefile 1 Makefile的作用 简单来说,Makefile的作用是告诉make如何编译和链接程序。我们在Eclipse界面中写好代码后,会点击一下rebuild按钮来将工程重新编译和链接。这背后就是通过Makefile来实现的。本文博

u013288925的博客 2872

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【makefile入门】makefile选项和makefile.buil

学习makefile的常用选项,并通过一个案例来学习makefile.build

jk_lovers的博客 2077

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

makefile使用MAKEFILE_LIST获取inlcude文件所在的目录

文章目的 记录下MAKEFILE_LIST的获取目录的使用技巧 测试目录 |----Makefile |----test01 |----test.txt |----001 |----test.txt |----test02 |----test.txt |----002 |----test.txt makefile 文件 #inlcue获取路径技 pkgdir ...

mjLlm的博客 2142

Makefile 入门教程

Makefile 定义了软件开发过程中,项目工程编译链、链接的方法和规则。由 IDE 自动生成或者开发者手动书写。Unix(MAC OS、Solaris)和Linux(Red Hat、Ubuntu、SUSE)系统下由 make 命令调用当前目录下的 Makefile 文件,实现项目工程的自动化编译。Windows 环境开发人员,可能并未听说过 Makefile,但是时时刻刻在使用 Makefile 来完成程序的编译,因为开发者并不需要手动编写 Makefile,而是通过 IDE 自动生成。

Doublelv 的博客专栏。 9152

Makefile 变量MAKEFILE_LIST

make程序在读取多个makefile文件时,包括由环境变量“MAKEFILES”指定、命令行指定、当前工作下的默认的以及使用指示符“include”指定包含的,在这些文件进行解析执行之前make读取的文件名将会被自动依次追加到变量“MAKEFILE_LIST”的定义域中。 这样我们就可以通过测试此变量的最后一个字来获取当前make程序正在处理的makefile文件名。具体的说就是在一个makefile文件中如果使用指示符“include”包含另一个文件之后,变量“MAKEFILE_LIST”的最后一个字只

肥叔菌的博客 8572

【Linux】Makefile

Makefile是一个包含了一系列指令的文件,这些指令定义了如何编译和链接程序。Makefile被make命令使用,make是一个构建自动化工具,它根据Makefile中定义的规则来决定哪些文件需要重新编译。

Tesseract_9527的博客 1451

Makefile中获取当前执行的Makefile所在路径

Linux下我们可以用pwd命令来获取当前所执行命令的目录,在Makefile中对应可用PWD := $(shell pwd)来获取。但是如果子Makefile 文件是从别处执行的(通过make -f .../Makefile 执行),那么$(shell pwd)得到的目录即为执行make -f命令的当前目录。在这种情况下, Makefile本身里面的命令不能对当前目录作出假设.那么如何获取被

专注探索c++,Linux等后台开发相关机制,欢迎关注,欢迎交流 2万+

Makefile新手?千万别错过了《驾驭Makefile》

Makefile新手?千万别错过了《驾驭Makefile》 网上搜索makefile教程,转载和推荐最多的就是陈皓《跟我一起写 Makefile》系列,无出其右。 这个系列很不错,适合初学Makefile,了解Makefile的各种规则、语法、依赖和命令。 网上有人说学了一下午《跟我一起写 Makefile》就会写makefile了。 我也试过,照着《跟我一起写 Makefile》学了几天,还是没能把一个小工程的Makefile写出来。所以,如果你学习了几天也没写出可以工作的Makefile来,相信我,你并

洛奇看世界 3932

Makefile入门

定义:变量名=变量值使用:$(变量名)/${变量名}clean:自定义函数不是真正的函数,本质上是多行命令放在了目标外可以传递参数$(0)为本身文件名1∗∗为要接受的参数∗∗(1)** 为要接受的参数 **1∗∗为要接受的参数∗∗(A)$(2)为要接受的参数asd没有返回值callFUNC2∗∗会报错,可以在∗∗(call FUNC2)** 会报错,可以在 **callFUNC2∗∗会报错,可以在∗∗。

zhexiangsi的博客 2357

Makefile 中获取自身目录(pwd, lastword,dirname)

命令解释 shell pwd make_dir:=$(shell pwd) // := 的意思是将$(shell pwd) 表示为make_dir,类似于宏定义 make_dir2:=$(pwd) all: @echo $(make_dir) //有输出 @echo $(make_dir2) //无输出 lastword && MAKEFILE_LIST MAKEFIL...

ym & blog 1万+

Makefile.am和makefile.in生成Makefile

很多时候,我们在网上下载的linux开源软件都会遇到一个问题,就是源码里面没有直接的makefile,但是它有Makefile.am和makefile.in或者它有Makefile.am和configure.in,这里就不详细解释他们直接的关联,直接给出如何操作生成makefile。 具体操作步骤如下: 1. 执行aclocal,产生aclocal.m4文件 aclocal是...

丨晋丨 8069
上一篇: RS232、RS485、TTL电平、CMOS电平
下一篇: vim配置及插件安装管理
csshuke
博客等级 码龄16年 1517粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值