Makefile命令行指定参数传递到C语言文件的4个步骤、2类关键字和2种变量

本文介绍了如何在Makefile中使用ifeq,elseifeq和ifdef进行条件判断,根据命令行传递的变量或配置来设置C语言的宏定义,以实现不同平台和调试模式下的编译差异。作者还强调了多层传递机制在工程设计中的应用和灵活性。
摘要由CSDN通过智能技术生成

要点:

  • make 命令行使用 xxx=abc传递,本质是在makefile中定义了makefile的变量。使用的判断关键字是 ifeq 以及 else ifeq和else
  • make 传递给C语言的配置本质是宏定义,使用的判断关键字是 if defined或者 ifdef ,elif definded

核心:
make ifeq 与 else ifeq
c ifdef 与 else ifdef。并且ifdef = if defined

Step1: 命令行定义

make CFG_TEST_VAR=linux

Step2: Makefile中使用

makefile中可以根据配置进行条件判断,条件判断中可以根据条件配置C语言的cflags传递给C文件,但是Makefile的变量不能直接传递

# 如果DEBUG参数被传递,则打印一条消息
ifeq ($(CFG_TEST_VAR),linux)
    $(info "Debug mode is enabled.")
    DEBUG_FLAG = -g
endif
 
# 其他规则和目标
mytarget:
    gcc myprogram.c -o myprogram $(DEBUG_FLAG)

如果有多个分支:

# 如果DEBUG参数被传递,则打印一条消息
ifeq ($(CFG_TEST_VAR),linux) #linux平台优化1
    $(info "Debug mode is enabled.")
    DEBUG_FLAG = -O1
else ifeq ($(CFG_TEST_VAR),mac) #其他平台优化2
	DEBUG_FLAG = -O2
else
	#xxx
endif

# 其他规则和目标
mytarget:
    gcc myprogram.c -o myprogram $(DEBUG_FLAG)

Step3: 传递给C语言:

传递给 C 语言本质是 Makefile 根据make变量,定义C语言的宏定义,相当于是通过 m变量 到 c宏 的转换,C语言宏定义使用CFLAGS中 -Dxxx或者-Dxxx=abc来传递

makefile中定义宏

  • 定义值模式,这种场景是有多个类似的选择
ifeq ($(CFG_TEST_VAR),linux)
	CFLAGS += -DPLATFORM_TYPE=1 # 定义值模式,这种场景是有多个类似的选择
else
	CFLAGS += -DPLATFORM_TYPE=2
endif
  • 定义判断宏模式
ifeq ($(CFG_TEST_VAR),linux)
	#或者直接定义宏
	CFLAGS += -DCFG_FEATURE_A # 定义判断宏模式,这种场景通常是某种功能开关,这种一般不常用else组合
endif

注意是-Dxxx

Step4: C语言中使用

判断宏定义的值:

方法1:使用变量值模式

#if defined(PLATFORM_TYPE) && (PLATFORM_TYPE == 1)
    printf(xxx);
#else if defined(PLATFORM_TYPE) && (PLATFORM_TYPE == 2)
	printk(xxx);
#else
    log(xxx);
#endif

方法2:使用值是否定义模式

#if defined(CFG_FEATURE_A)
    struct abc def;
    def.fature_a_enable = True;
#endif

其他总结

工程实践场景

  • 使用在 命令参数,比如 echo 参数,GCC 参数
  • 使用在定义条件分支,比如 ifeq linux 或者 mac
  • 使用在定义 relase 或者 debug 发布
  • 使用在定义 C 语言cflags
  • 有某个功能宏定义开关,C语言根据场景判断是否有这种功能代码进行预编译区分(优势是能够节省代码段)

坑:

坑1:在ifeq中使用make命令行传递进来的时候如果是个字符串,不需要额外添加",比如

  • 命令行:
make CFG_TEST_VAR=linux
  • make中
ifeq ($(CFG_TEST_VAR), linux) #对
ifeq ($(CFG_TEST_VAR), "linux") #错,将不会执行

总结

  • 核心:
    • make ifeq 与 else ifeq
    • c ifdef 与 else ifdef。并且ifdef = if defined
  • makefile中是makefile的变量,ifeq和else ifeq是makefile的语法关键字。本质是变量,那么就有变量的判断逻辑。可以通过命令行送变量进来,也可以直接在makefile中定义变量。(命令行送进来的本质是变量)
  • C中是C宏定义,#ifdef 和 #if defined这些宏定义的关键字就可以用,#ifdef 的多个条件分支是 #elif defined。
  • make和c的这个多层次(4个层次)传递方式,使用变量+宏,串联起了从命令行 经过makefile,再经过gcc的-D传参,送入C语言的宏定义,最后作用在C的变量,从而控制了二进制程序的代码。体现了工程分层以及工程接口和灵活组合的设计关联。很有意思。

引用

姊妹篇:
《C语言如何根据Makefile配置宏定义值进行编译预处理 #if defined(CFG_XXX_TYPE) && (CFG_XXX_TYPE == 1)》 https://blog.csdn.net/essencelite/article/details/135857713

  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用Makefile将多个不同的C语言文件编译成Stm32可执行文件,需要在Makefile中定义多个源文件和目标文件,并将它们编译链接到一起生成可执行文件。以下是一个示例Makefile,用于将多个不同的C语言文件编译成Stm32可执行文件: ``` CC = arm-none-eabi-gcc CFLAGS = -Wall -Wextra -std=c99 -O2 -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 LDFLAGS = -T stm32.ld -nostartfiles SOURCES = main.c file1.c file2.c OBJECTS = $(SOURCES:.c=.o) EXECUTABLE = myprogram all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@ .c.o: $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f $(OBJECTS) $(EXECUTABLE) ``` 在这个Makefile中,定义了三个变量: - `SOURCES`:源文件的路径和名称,包括main.c、file1.c和file2.c; - `OBJECTS`:目标文件的路径和名称,根据源文件的不同生成不同的目标文件,例如main.o、file1.o和file2.o; - `EXECUTABLE`:生成的可执行文件的路径和名称,例如myprogram。 在Makefile中定义了以下几个规则: - `all`:默认生成规则,依赖于源代码文件和目标文件,生成可执行文件; - `$(EXECUTABLE)`:生成可执行文件的规则,依赖于目标文件,使用gcc将目标文件链接成可执行文件; - `.c.o`:将C语言文件编译成目标文件的规则,依赖于源文件,使用gcc将源文件编译成目标文件; - `clean`:清理生成的目标文件和可执行文件。 使用这个Makefile生成Stm32可执行文件步骤和前面的示例相同。需要注意的是,在编写C语言代码时,需要使用Stm32的相关库函数,并将这些库函数的源代码添加到Makefile中进行编译链接。通常情况下,这些库函数的源代码会被组织成一个库文件(例如libstm32f4xx.a),需要在Makefile指定文件的路径和名称,并将它们链接到可执行文件中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值