多个Makefile文件编译,Makefile多目标编译和多层次编译

2023-11-15

README

文件夹以及文件说明。
根文件夹为make,实现多个Makefile文件编译。

Dir
make-----									/* 一级文件夹:多Makefile编译 */
		|					
		|-------a_b							/* 二级文件夹:多目标编译 */
		|		|
		|		|-------obj					/* 三级文件夹:a_b工程目标文件生成的指定位置 */
		|		|
		|		|------------------main_a.c	/* 第一个目标主文件 */
		|		|------------------main_b.c	/* 第二个目标主文件 */
		|		|------------------test_a.c	/* 第一个目标printf功能函数文件 */
		|		|------------------test_b.c	/* 第二个目标printf功能函数文件 */
		|		|------------------test_a.h	/* 第一个目标功能函数声明头文件 */
		|		|------------------test_b.h	/* 第二个目标功能函数声明头文件 */
		|		|------------------Makefile	/* 二级文件夹a_b多目标编译的Makefile文件 */
		|
		|-------projects					/* 二级文件夹:多层次编译 */
		|		|
		|		|-------a					/* 三级文件夹:a功能函数实现 */
		|		|		|
		|		|		|----------a.c		/* a()功能函数实现 */
		|		|		|----------a.h		/* a()功能函数声明头文件 */
		|		|		
		|		|-------b					/* 三级文件夹: b功能函数实现 */
		|		|		|
		|		|		|----------b.c		/* b()功能函数实现 */
		|		|		|----------b.h		/* b()功能函数声明头文件 */
		|		|		
		|		|-------include				/* 三级文件夹:相关常量宏定义头文件 */
		|		|		|	
		|		|		|----------code.h	/* 相关常量宏定义头文件 */
		|		|
		|		|-------obj					/* 三级文件夹:project2工程目标文件生成的指定位置 */
		|		|		
		|		|-------c.c					/* c()功能函数实现 */
		|		|-------c.h					/* c()功能函数声明头文件 */
		|		|-------main.c				/* project2工程实现主函数,调用a(),b(),c()函数接口 */
		|		|-------Makefile			/* project2工程实现多层次编译的Makefile */
		|		
		|
		|-------Makefile					/* make文件夹实现多个Makefile文件编译,即调用projects和a_b文件夹下Makefile编译 */
		
!!!
注意:
所有非 main*.c 文件只具有简单的printf功能
所有含有 main*.c 文件只有简单的函数接口调用功能
		

Makefile多目标编译

在文件夹a_b中实现。
main_a.c: 第一个目标主文件

#include <stdio.h>
#include <stdlib.h>
#include <test_a.h>

int main() {

	print_a();
	return 0;

}

test_a.c:第一个目标printf功能函数文件

#include <test_a.h>

void print_a() {

	printf( "This is test_a.c!\n" );

}

test_a.h:第一个目标功能函数声明头文件

#ifndef _TEST_A_H
#define _TEST_A_H

#include <stdio.h>
#include <stdlib.h>

void print_a();

#endif

main_b.c:第二个目标主文件

#include <stdio.h>
#include <stdlib.h>
#include <test_b.h>

int main() {

	print_b();
	return 0;

}

test_b.c:第二个目标printf功能函数文件

#include <test_b.h>

void print_b() {

	printf( "This is test_b.c!\n" );

}

test_b.h:第二个目标功能函数声明头文件

#ifndef _TEST_B_H
#define _TEST_B_H

#include <stdio.h>
#include <stdlib.h>

void print_b();

#endif

Makefile:二级文件夹a_b多目标编译的Makefile文件

CC       = gcc #选择编译器为gcc
CFLAGS   = -lm -Wall -g

#获取项目根路径
ROOT     = $(PWD)
#获取当前库函数根路径
INCLUDE  = -I$(ROOT)
#设置目标生成路径
APP      = $(ROOT)/obj

#第一目标生成内容
OBJS1    = main_a.o \
	       test_a.o

#第二目标生成内容
OBJS2    = main_b.o \
	       test_b.o 

#第一与第二目标输出名字
TARGETS1 = $(APP)/main_a
TARGETS2 = $(APP)/main_b
#最终目标汇总
TARGETS  = $(TARGETS1)
TARGETS += $(TARGETS2)
#库函数路径汇总
CFLAGS 	+= $(INCLUDE)

# 生成目标汇总(包含中间生成的临时目标)
OBJS     = $(OBJS1)
OBJS    += $(OBJS2)

all:$(TARGETS)

#目标1自动编译,包括编译依赖关系自动索引
$(TARGETS1):$(OBJS1)
	$(CC) -o $(TARGETS1) $(OBJS1) $(CFLAGS)

#目标2自动编译,包括编译依赖关系自动索引
$(TARGETS2):$(OBJS2)
	$(CC) -o $(TARGETS2) $(OBJS2) $(CFLAGS)

#清除工程编译内容,全部目标清除
clean:
	-$(RM) $(OBJS) 
	-$(RM) $(TARGETS)

Makefile多层次编译

Makefile文件


ROOT    = $(PWD)

A       = $(ROOT)/a
B       = $(ROOT)/b
INCLUDE = $(ROOT)/include
APP     = $(ROOT)/obj

CFLAGS  = -I$(A) 
CFLAGS += -I$(B) 
CFLAGS += -I$(ROOT) 
CFLAGS += -I$(INCLUDE)

OBJS    = main.o $(A)/a.o $(B)/b.o c.o 

TARGET  = $(APP)/app

all:$(TARGET)

$(TARGET):$(OBJS)
	$(CC) -o $(TARGET) $(OBJS) $(CFLAGS)

clean:
	-$(RM) $(OBJS)
	-$(RM) $(TARGET)

c.c:c()功能函数实现

#include <stdio.h>
#include <stdlib.h>
#include <c.h>
#include <code.h>

void c(){

	printf( "%d: This is c function!\n" , C );

}

c.h:c()功能函数声明头文件

#include<stdio.h>
void c();

main.c:project2工程实现主函数,调用a(),b(),c()函数接口

#include <stdio.h>
#include "a.h"
#include "b.h"
#include "c.h"

void main(){

	a();

}

a文件夹

三级文件夹: a功能函数实现
a.c:a()功能函数实现

#include <stdio.h>
#include <stdlib.h>
#include "a.h"
#include "b.h"
#include "c.h"
#include <code.h>

void a(){

	c();
	b();
	printf( "%d: This is a function!\n" , A );
	printf( "Well done!\n" );

}

a.h:a()功能函数声明头文件

void a();

b文件夹

三级文件夹: b功能函数实现
b.c:b()功能函数实现

#include <stdio.h>
#include <stdlib.h>
#include "b.h"
#include <code.h>

void b(){

	printf( "%d: This is b function!\n" , B );

}

b.h:b()功能函数声明头文件

#include <stdio.h>

void b();

include文件夹

code.h:相关常量宏定义头文件

#include <stdio.h>
#include <stdlib.h>

#define A 1
#define B 2
#define C 3

obj文件夹

编译前为空文件夹,编译时为project2工程目标文件生成的指定位置

多个Makefile文件编译

Makefile:位于根文件夹make中

ROOT    = $(PWD)
SUBDIR  = $(ROOT)/a_b
SUBDIR += $(ROOT)/project2

define make_subdir
@for i in $(SUBDIR); do   \
	( cd $$i && make $1 ) \
done;
endef

ALL: 
	$(call make_subdir)

clean:
	$(call make_subdir , clean)

相关截图

make文件夹

make文件夹

a_b文件夹

a_b文件夹

project2文件夹

project2文件夹
/project2/a 文件夹
/project2/a文件夹
/project2/b 文件夹
/project2/b文件夹
/project2/include 文件夹
/project2/include文件夹
/project2/obj 文件夹
/project2/obj文件夹

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多个Makefile文件编译,Makefile多目标编译和多层次编译 的相关文章

随机推荐

  • Stata字符串函数:快捷提取字符信息

    1 substr 函数的用法 语法 substr s n1 n2 a s为需要进行提取的字符串 b n1表示提取的起始位置 c 对于不同编码的文本 n2代表不同含义 对于纯ASCII编码的文本 n2表示要提取字符长度为n2的字符串 而对于其
  • webpack打包文件过大的优化,提取第三方库(vue,ali-oss)到cdn,externals配置

    问题产生原因 vue或用其他第三方库webpack打包导致某单文件js过大 优化形式 webpack的externals配置 从输出的 bundle 中排除依赖 可将第三方库放到html用cdn加载 类似 调试方式 可参考vue cli 脚
  • 访问时被windos防火墙阻止浏览器网页找不到解决方法 postman使用

    postman使用 网页下载postman安装 添加环境 点击右边齿轮状 选择add 输入网址前缀post get各不一样 访问时被windos防火墙阻止浏览器网页找不到解决方法 点击服务管理器仪表板右上方的工具 高级windos设置 出
  • java中char的类型范围,Java中基本类型占字节数以及Uint32的意思

    初学开发的时候 我的第一门语言是JAVA android方向 基本很少考虑java中基本类型的占用字节数 直到工作中接触到串口通讯 与单片机通讯 看着那些通讯文档 看着例如Uint16 Uint32 Uint64 Char 16 Char
  • 如何使用Windows命令关闭被占用的端口

    1 使用快捷键Windows R 打开运行 输入cmd 用管理员权限打开Windows 命令窗口 2 然后执行命令 netstat nao findstr 8080 此处已8080端口为例 小伙伴们若要关闭其他窗口 只需将此处8080更换为
  • Hive Sql 最强最完整学习笔记

    一 DDL语句 数据定义语句 对数据库的操作 包含创建 修改数据库 对数据表的操作 分为内部表及外部表 分区表和分桶表 二 DQL语句 数据查询语句 单表查询 关联查询 hive函数 包含聚合函数 条件函数 日期函数 字符串函数等 行转列及
  • 线程安全list_不安全的集合类学习子笔记

    list 不安全类是什么 不安全类是指在多线程并发的时候不能保证数据正确性的类 通常是由于这些类并没有加锁造成的 为什么不设计成加锁的 其实 在list之前有个集合类vector 它是内部加锁 它是一个线程安全类 不优先使用它的原因是加锁可
  • kali firefox gah. your tab just crashed. 更新Firefox

    kali firefox gah your tab just crashed we can help choose restore this tab to reload the page 这个问题我大概八月份的一个晚上也发生过当时是kali
  • Robotframework 之exe安装(二)

    Robotframework 之pip安装 一 Robotframework 之exe安装 二 Robotframework安装过程中错误解决方案 三 一 exe安装步骤 1 python 2 7 10 amd64 msi 2 安装Robo
  • R 语言 wordcloud 与 wordcloud2 包的安装及参数说明

    一 wordcloud安装说明 install packages wordcloud 二 wordcloud2安装说明 我在RStudio编辑器直接输入 if require devtools install packages devtoo
  • Flutter中屏幕自适应(iPhone iPad Windows)

    flutter屏幕自适应 文章目录 flutter屏幕自适应 适配手机和平板的重要性 一 Sizer插件的使用 二 使用步骤 1 准备工作 2 正常使用的样式 3 判断平台设备的样式 总结 适配手机和平板的重要性 这是未进行屏幕适配的界面
  • HC-05通信的正确打开方式

    1 蓝牙模块RX TX 5 VCC分别与串口线TX RX 5 GND连接 2 打开串口助手 设置串口 波特率9600 打开串口 3 按一下蓝牙模块上的微动开关 4 在串口助手上发送AT PC端就会有OK回应 其它相应指令也会有相同回应了 我
  • Eclipse中配置Tomcat容器

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 问题描述 独立启动tomcat后在浏览器输入http localhost 8080可以成功访问到tomcat主页 但是当在Eclipse中启动tomcat时 虽然启动成功
  • my97日期控件插件的开发与编写

    my97日期控件插件的开发与编写 扩展一个easyui 的my97 控件 function undefined function create target var state data target my97 opts state opt
  • ERROR: Could not build wheels for hdbscan, which is required to install pyproject.toml-based project

    pip安装hdbscan报错 ERROR Failed building wheel for hdbscan Failed to build hdbscan ERROR Could not build wheels for hdbscan
  • iOS开发中的网络请求

    转载自http www cocoachina com ios 20140919 9691 html 今天来说说关于iOS开发过程中的网络请求 关于网络请求的重要性我想不用多说了吧 对于移动客户端来说 网络的重要性不言而喻 常见的网络请求有同
  • N: 无法安全地用该源进行更新,所以默认禁用该源。

    解决方法 cd etc apt sources list d 进入该目录下 删除该目录下的文件 然后更换源 sudo apt get update
  • m计划-python

    题目描述 小明是个鹅卵石收藏者 从小到大他一共收藏了 n块鹅卵石 编号分别为 1 n 价值分别为 a1 a2 an 这天他乘船准备去往蓝桥王国 然而天有不测风云 小明所在的海域下起了暴雨 很快小明船上的积水越来越多 为了防止沉船 小明不得不
  • 有关 Rust 交叉编译的一些思路 (仅供参考)

    近来 使用 Rust 语言开发的应用程序渐渐融入了开发者以及普通用户的日常生活 它们不仅出现在我们常用的工作平台上 不少嵌入式设备或者云服务器上也多见它们的身影 Rust 是一种需要编译的语言 且一些 crate 仍需要 C C 的构建环境
  • 多个Makefile文件编译,Makefile多目标编译和多层次编译

    多个Makefile文件编译 Makefile多目标编译和多层次编译 README Makefile多目标编译 Makefile多层次编译 a文件夹 b文件夹 include文件夹 obj文件夹 多个Makefile文件编译 相关截图 ma