尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
嵌入式开发学习日志(多文件工程、Makefile) day17 持续更新中
前言在小型 C 语言项目中代码量少可以全部写在一个.c文件里。当项目规模变大全部代码写在单个源文件会造成维护困难、可读性差、不利于团队协作。这时就要使用多文件工程管理配合Makefile工具实现项目自动化编译。本文梳理头文件、源文件分工、全局变量跨文件使用、Makefile 语法与变量相关知识点。一、C 语言多文件工程结构C 工程主要分为 \\头文件.h和源文件.c\\两类文件。1. 头文件.h职责头文件只做声明不做实现包含需要的其他头文件数据类型声明结构体、枚举、typedef 等函数声明全局变量声明使用extern宏定义⚠️注意头文件中不要定义函数实体、不要初始化全局变量否则多次 include 会出现重复定义报错。2. 源文件.c职责源文件做定义与实现包含需要的头文件一定要包含自身对应的.h头文件函数的具体实现函数体全局变量的定义可以初始化工程一般是一对多关系一个.h头文件对应一个.c实现文件多个模块就有多组 h‑c 文件。main.c 作为程序入口包含各个模块头文件调用模块函数。二、全局变量跨文件使用规则全局变量在多文件项目中极易出现重复定义错误严格遵守下面 4 条规则全局变量在源文件.c中定义可以初始化。如果只在定义该变量的.c内部使用不需要额外声明。如果要在其他外部源文件使用这个全局变量必须做外部声明。在对应头文件中使用extern关键字做变量声明extern 声明时不能给变量初始化。示例// test.c 源文件定义全局变量 int g_num 100; // test.h头文件extern声明供别的.c文件使用 extern int g_num;其他文件只要#include test.h就可以访问g_num。❌错误头文件写extern int g_num100;这变成定义会重复定义。三、Makefile 工程编译管理3.1 Makefile 是什么Makefile 用于管理代码工程的编译、链接由make工具解释执行实现一键编译链接整个工程不用手动敲很长 gcc 命令。文件名可以为Makefile或者makefile。3.2 Makefile 基础语法规则目标文件: 依赖文件 编译规则命令 #❗前面必须是Tab键不能用空格目标文件想要生成的文件比如可执行程序a.out依赖文件生成目标所需要的文件一般是.c源码编译规则gcc 编译命令生成目标。示例a.out: main.c sum.c sub.c div.c gcc main.c sub.c sum.c div.c -I头文件路径 -L库的位置编译运行终端直接输入命令makegcc 参数说明-I(大写 i)指定头文件搜索路径-L指定库文件搜索路径四、Makefile 中的变量变量可以简化 Makefile便于后期维护修改只需要改变量不用修改多处编译命令。4.1 自定义变量定义格式变量名 值引用格式$(变量名)。#定义变量 OBJ a.out SRC main.c sum.c sub.c #引用变量 $(OBJ) 等价于 a.out变量赋值运算符运算符作用普通赋值给变量赋值追加赋值在原有变量基础上新增内容?条件赋值变量未赋值才赋值已有值则保留原值示例SRC main.c SRC sum.c # SRC变为 main.c sum.c4.2 Makefile 内置系统自动变量直接使用自动变量含义$代表当前规则的目标文件$^代表所有的依赖文件$代表第一个依赖文件4.3 完整 Makefile 示例#自定义变量 OBJ a.out SRC main.c SRC sum.c SRC sub.c SRC div.c CC gcc INCLUDE ../include LIBS ../lib #编译规则 $(OBJ): $(SRC) $(CC) $^ -o $ -I$(INCLUDE) -L$(LIBS) -lm #伪目标清理编译产物 clean: rm $(OBJ)使用make执行编译生成 a.outmake clean执行 clean 规则删除可执行文件补充clean没有依赖属于伪目标一般用来删除编译生成的产物。五、常见踩坑总结❌头文件写函数实现、初始化全局变量多次#include触发重复定义报错。 ✅头文件放声明.c文件放实现与变量定义。❌extern int g_val 10;头文件 extern 声明带初始化。 ✅extern 只是声明不能初始化定义写在.c。❌Makefile 编译命令前面用空格不是 Tab直接报语法错误。 ✅规则行命令开头必须是 Tab。❌忘记-I指定头文件路径头文件找不到报错。❌手动敲很长 gcc 命令文件一多修改麻烦。 ✅用 Makefile 变量统一管理。小结.h负责声明.c负责实现多文件工程遵循声明与实现分离。全局变量在.c定义.h中用 extern 做外部声明禁止 extern 时初始化。Makefile 格式目标:依赖Tab 开头写编译命令make 命令执行。使用自定义变量简化维护掌握$ $^ $自动变量简化编译脚本。
RELATED

相关推荐

【CRM选型专题③】行业篇:不懂你行业的供应商,就是在用通用模板套你——6大行业CRM选型逻辑差异全解析

【CRM选型专题③】行业篇:不懂你行业的供应商,就是在用通用模板套你——6大行业CRM选型逻辑差异全解析

本篇是《CRM定制开发选型全景指南》专题系列第3篇。 上一篇讲了需求厘清和P0/P1/P2优先级划分。本篇聚焦第二个维度:行业特性——CRM不是一个通用工具,不同行业的CRM逻辑天差地别。 系列导航 篇号标题状态① 总论篇五维三方选型框架全景解读✅ 已发布②…

📅 2026/9/10 8:47:03
解决双系统启动时GRUB救援模式问题

解决双系统启动时GRUB救援模式问题

1. 问题背景与现象描述 最近在给一台Dell XPS笔记本安装Win10Ubuntu 20.04双系统时,遇到了一个典型问题:每次开机都会直接进入GNU GRUB version 2.04界面,需要手动输入命令才能进入系统。这种情况在双系统安装中并不少见,特别是当…

📅 2026/9/26 2:03:13
AI角色化多语言文本生成:从提示词工程到俄语文学创作实践

AI角色化多语言文本生成:从提示词工程到俄语文学创作实践

在自然语言处理领域,多语言文本生成与情感分析一直是极具挑战性的任务。当项目标题中出现“【雪松】【AI克劳迪娅】【俄语版本】死别”这样的组合时,它通常指向一个融合了特定主题、AI角色和多语言处理的复杂文本生成或分析项目。本文将深入拆解此类项目…

📅 2026/8/23 7:36:56
MORE NEWS

更多资讯

📰

为什么现在大多 Code Agent 的主形态是 CLI/TUI?TaoToken 统一 Key 接入实测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

基于S7-200与组态王的装卸料小车PLC自动控制系统设计

1. 项目背景与需求梳理1.1 为什么需要一个“会自己跑”的装卸料小车港口码头的散货装卸作业里,有一种很常见的场景:皮带机把物料送到某个中转料斗,料斗下方的小车需要沿着轨道往复运动,把料斗里的物料均匀地卸到指定的堆场区域。以…

📰

当Agent学会“自我进化”,你的算法底座还稳吗?TaoToken视角下的递归增强与算法优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

CRC32查表法实战:原理、反转与跨平台实现

1. 这不是“黑魔法”,是工程师每天都在用的CRC32查表法实战笔记 你有没有遇到过这样的场景:嵌入式设备上传固件时提示“校验失败”,串口调试日志里一串十六进制数据后面跟着个CRC32值,你盯着它看了三分钟,却不知道那个…

📰

2026北京EtherCAT芯片选型:嵌入式接口与网关路径的工程决策指南

1. 为什么2026年北京的EtherCAT芯片选型,必须跳出“买芯片写驱动”的惯性思维?2026年,北京工业自动化圈子里聊EtherCAT,已经没人再问“哪家芯片便宜”或者“STM32跑得动几个从站”这种入门级问题了。真正卡住项目落地的&#xff0…

📰

政务热线工单分类:DeepSeek本地部署与推理优化实战

简介:这份PDF文档面向政务信息化从业者、数据分析人员及对DeepSeek落地应用感兴趣的开发者,聚焦民生诉求分类模型的完整部署实践。文档共23页,以1个PDF文件交付,压缩包约1.9MB,内容完整、目录清晰,涵盖背景…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬