Linux_项目自动化构建工具-make/makefile

Makefile是项目自动化构建的核心,通过定义编译规则,实现一键编译。本文介绍了如何创建单文件和多文件的Makefile,包括依赖关系、伪目标`.PHONY`以及特殊变量`$@`、`$^`、`$<`的使用。通过`make clean`可以方便地清理临时文件,提升开发效率。

make是解释makefile中的指令的工具

make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了效率。

1.单文件makefile

首先在项目中 touch makefile(Makefile)文件,然后再makefile文件中写出依赖的编译关系
eg:
在这里插入图片描述
生成的项目为Test,Test依赖test.c

makefile文件格式:
链接关系,之间以冒号连接
Tab键+依赖方法
在这里插入图片描述
之后要重编译项目代码只用在项目中make即可
在这里插入图片描述
如果项目中有临时文件想要删除,只要在makefile文件夹中写出clean的依赖方法。

2.make clean

假设项目生成了很多临时文件
在这里插入图片描述
在这里插入图片描述想要删除
在这里插入图片描述
在这里插入图片描述

3.伪目标.PHONY

在项目中如果项目没有更新,则只能make一次。如果将其改为伪目标,则其不管项目有没有更新都可以make

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

注意:.PHONY只作用于下一行,如上图

4.多文件makefile

在这里插入图片描述
与单文件类似,依赖关系之间要以空格形式隔开

在这里插入图片描述

5.$@ $^ $<

$@:依赖关系中的目标文件

$^:依赖关系中的依赖文件列表

$<:依赖文件列表中的一个个的依赖文件

eg:
在这里插入图片描述

make -C /data/test_wifi8_docker/Iplatform/openwrt/build_dir/target-arm-openwrt-linux-uclibc-bn800v1/bluetopia-profiles-4.2 all "CC=arm-buildroot-linux-gnueabihf-gcc" "GLOBLDFLAGS=-L/data/test_wifi8_docker/Iplatform/openwrt/staging_dir/target-arm-openwrt-linux-uclibc-bn800v1/usr/lib -L/data/test_wifi8_docker/Iplatform/openwrt/staging_dir/target-arm-openwrt-linux-uclibc-bn800v1/lib -Wl,-rpath-link,/data/test_wifi8_docker/Iplatform/openwrt/staging_dir/target-arm-openwrt-linux-uclibc-bn800v1/usr/lib -L/data/test_wifi8_docker/Iplatform/openwrt/../../bcm620L/toolchains/opt/toolchains/crosstools-arm_hf-gcc-13.2-linux-5.15-glibc-2.38-binutils-2.41/usr/lib -L/data/test_wifi8_docker/Iplatform/openwrt/../../bcm620L/toolchains/opt/toolchains/crosstools-arm_hf-gcc-13.2-linux-5.15-glibc-2.38-binutils-2.41/lib -luci -mfloat-abi=softfp" "GLOBINCLDDIRS=" "GLOBCFLAGS=-I/data/test_wifi8_docker/Iplatform/openwrt/staging_dir/target-arm-openwrt-linux-uclibc-bn800v1/usr/include" make[4]: Entering directory '/data/test_wifi8_docker/Iplatform/openwrt/build_dir/target-arm-openwrt-linux-uclibc-bn800v1/bluetopia-profiles-4.2' Makefile:46: *** recipe commences before first target. Stop. make[4]: Leaving directory '/data/test_wifi8_docker/Iplatform/openwrt/build_dir/target-arm-openwrt-linux-uclibc-bn800v1/bluetopia-profiles-4.2' make[3]: *** [Makefile:97: /data/test_wifi8_docker/Iplatform/openwrt/build_dir/target-arm-openwrt-linux-uclibc-bn800v1/bluetopia-profiles-4.2/.built] Error 2 make[3]: Leaving directory '/data/test_wifi8_docker/Iplatform/packages/private/bluetopia-profiles' make[2]: *** [package/Makefile:134: package/feeds/iplatform/bluetopia-profiles/compile] Error 2 make[2]: Leaving directory '/data/test_wifi8_docker/Iplatform/openwrt' make[1]: *** [/data/test_wifi8_docker/Iplatform/openwrt/include/toplevel.mk:186: package/bluetopia-profiles/compile] Error 2 make[1]: Leaving directory '/data/test_wifi8_docker/Iplatform/openwrt' make: *** [Makefile:237: iplatform_package/bluetopia-profiles/compile] Error 2
最新发布
11-20
<think> 我们面对的是一个Makefile构建错误,错误信息是:Makefile:46: *** recipe commences before first target. Stop. 这个错误通常表示在Makefile的第46行之前存在语法问题,比如在目标(target)定义之前出现了规则(recipe)(即命令),而命令前面没有以目标(target)和冒号(:)开始的行。 错误可能的原因包括: 1. 在Makefile中,命令(以Tab开头)前面没有目标声明。 2. 使用了空格而不是Tab来缩进命令。 3. 在Makefile的开头有空白行(但通常Makefile允许空白行,所以这个可能性小)或者有不可见的字符。 由于错误发生在构建bluetopia-profiles-4.2包时,我们需要检查该包的Makefile,特别是第46行附近。 根据构建命令,我们正在使用一个特定的Makefile(位于:/data/test_wifi8_docker/Iplatform/openwrt/build_dir/target-arm-openwrt-linux-uclibc-bn800v1/bluetopia-profiles-4.2/Makefile)。 建议步骤: 1. 检查该Makefile的第46行以及前面的行,看是否有命令(以Tab开头的行)出现在第一个目标之前。 2. 确保所有命令前面都有正确的目标,并且命令的缩进是Tab而不是空格。 由于我们无法直接查看Makefile内容,我们可以推测可能的问题来源: -Makefile可能是由OpenWrt的构建系统生成的,也可能是软件包自带的。如果是软件包自带的,可能存在问题。 - 也可能是构建过程中传递的变量导致了Makefile的生成问题。 但是,错误信息明确指出了第46行有问题,所以重点检查第46行附近。 由于用户提供的信息有限,我们只能给出一般性建议: 解决方案: 1. 打开报错的Makefile(路径如上),定位到第46行。 2. 检查第46行以及前面的行,看是否有命令(以Tab开头的行)出现在目标之前。例如,可能在第46行有一个以Tab开头的命令,但是前面没有目标行。 3. 如果发现这样的行,考虑删除它或者在它前面添加一个目标(如一个伪目标)。 4. 检查缩进:确保命令的缩进是Tab字符,而不是空格。如果是空格,替换为Tab。 另外,注意构建命令中传递的变量(如CC、GLOBLDFLAGS等)是否可能导致Makefile生成问题?但通常这些是编译选项,不应该影响Makefile的结构。 另一种可能性:该Makefile可能是由configure脚本生成的,那么在配置阶段可能就出错了。但错误发生在make阶段。 由于错误是“recipe commences before first target”,所以最可能的原因还是在Makefile的格式上。 如果用户无法修改Makefile(因为它是自动生成的),那么可能需要检查生成Makefile的步骤(比如configure或cmake)是否有问题。 但是,根据OpenWrt的构建流程,这个Makefile可能是OpenWrt的构建系统根据软件包的Makefile模板生成的。因此,可能需要检查软件包目录下的Makefile(在package/feeds/iplatform/bluetopia-profiles/目录下)是否有问题。 由于构建错误发生在OpenWrt的包构建过程中,我们可以尝试: 1. 清理并重新构建该包:`make package/feeds/iplatform/bluetopia-profiles/{clean,compile} V=s` 2. 查看完整的构建日志(使用V=s)以获取更多信息。 但是,根据给出的错误信息,最直接的方法是检查Makefile的第46行。 如果用户能够提供Makefile的第46行附近的内容,我们可以进一步分析。 不过,根据经验,这个错误通常是由于Makefile的格式错误(比如命令出现在目标之前)引起的。因此,请检查第46行是否有以Tab开头的行,并且它前面没有目标行?或者第46行是一个目标行,但是前面有空白行?实际上,Makefile的第一个非注释行必须是目标,不能是命令。 示例错误: 第45行: # This is a comment 第46行: command # 这里以Tab开头,但没有目标,所以错误 或者: 第46行: $(SOME_VAR):=value # 这行如果以Tab开头,也会被当作命令,从而出错 因此,请确保第46行没有以Tab开头,除非它是属于某个目标的命令。 如果第46行是变量赋值,那么不应该用Tab开头,而应该用空格开头(或者顶格)。 所以,解决方法是:找到第46行附近以Tab开头的行(并且它不属于任何目标命令),删除Tab或者改为空格(根据Makefile语法,变量赋值可以用空格开头,也可以顶格)。 但是,如果该行确实是一个命令,那么请确保它前面有一个目标行,例如: 正确示例: target: command # 这里用Tab开头 错误示例: target: command1 command2 # 第46行,但是前面没有目标行?实际上,如果command2前面有command1,且command1和command2属于同一个目标,那么它们之间不需要再写目标。所以这种情况不会出错。 因此,更可能是第46行之前(即第45行或更前)出现了命令,而该命令前面没有目标。 总结:检查Makefile第46行及之前的几行,确保没有命令(以Tab开头的行)出现在目标(以非Tab字符开头且后面有冒号的行)之前。 由于具体内容未知,我们只能给出这样的建议。 §§相关问题§§ 1. 如何定位和修复Makefile中"recipe commences before first target"错误? 2. 在OpenWrt构建过程中,如何调试包编译失败的问题? 3. Makefile中命令的缩进规则是什么?为什么必须使用Tab而不能用空格? 4. 当构建第三方软件包时,如何确保生成的Makefile格式正确? 5. 在交叉编译环境下,环境变量设置错误是否会导致Makefile生成失败? </think> 根据您提供的构建日志,错误信息为:`Makefile:46: *** recipe commences before first target. Stop.`。这是一个典型的Makefile语法错误,通常由以下原因引起: ### 错误分析: 1. **Makefile格式问题**(最常见原因): -Makefile第46行之前存在非法内容(如命令、变量赋值等)出现在第一个目标定义之前 - 第46行附近可能存在: - 以Tab开头的命令语句出现在目标定义前 - 空行或注释位置不当 - 使用了空格代替Tab缩进命令 2. **环境变量传递问题**: - 您通过`make -C`传递的复杂环境变量(特别是`GLOBLDFLAGS`)可能包含特殊字符(如空格、引号),导致Makefile解析错误 - 示例:`"GLOBLDFLAGS=-L/path ... -luci -mfloat-abi=softfp"`中的空格和路径可能被错误解析 3. **Makefile兼容性问题**: - 软件包`bluetopia-profiles-4.2`的Makefile可能不兼容OpenWrt构建系统 - 第46行可能存在条件判断(如`ifeq`)或包含指令(`include`)格式错误 ### 解决方案: #### 步骤1:检查Makefile语法 ```bash # 进入构建目录 cd /data/test_wifi8_docker/Iplatform/openwrt/build_dir/target-arm-openwrt-linux-uclibc-bn800v1/bluetopia-profiles-4.2 # 检查第46行及上下文(关键检查目标前的非法内容) sed -n '40,50p' Makefile ``` 重点关注: - 第46行前是否有以Tab开头的命令 - 是否有未闭合的引号或括号 - 变量赋值是否使用`:=`而不是`=` #### 步骤2:简化环境变量传递 尝试最小化变量传递: ```bash make -C ... all \ "CC=arm-buildroot-linux-gnueabihf-gcc" \ "GLOBLDFLAGS=-mfloat-abi=softfp" # 先只保留关键参数 ``` #### 步骤3:修复Makefile结构 如果发现格式问题,例如: ```makefile # 错误示例:命令出现在target前 SOME_VAR := value # 正确 @echo "Illegal command before target" # 错误!行首有Tab # 正确结构应为首个target定义 all: dependencies # 第一个目标必须顶格 @echo "Build commands" # 命令用Tab缩进 ``` #### 步骤4:检查Makefile版本兼容性 ```bash # 确认Makefile使用的GNU make特性 head -n 5 Makefile # 查看是否声明兼容性如`# Requires GNU make` # 尝试指定make版本 make -C ... MAKE=make-4.3 # 使用特定版本 ``` #### 步骤5:OpenWrt特定修复 ```bash # 清理并重新生成Makefile make package/feeds/iplatform/bluetopia-profiles/{clean,prepare} V=s # 检查软件包补丁 ls /data/test_wifi8_docker/Iplatform/packages/private/bluetopia-profiles/patches ``` ### 预防措施: 1. 在Makefile开头添加`.DEFAULT_GOAL := all`明确默认目标 2. 使用`ifeq`前必须顶格: ```makefile # 正确示例 ifeq (...) # 内容 endif ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BaiRong-NUC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值