静态库递归引用产生的问题

由于静态库可以避免程序运行时去找动态库,所以编译的时候经常使用。

一、出问题的场景

a编译成静态库lib.a,b引用lib.a编译成静态库libb.a
这时项目c要使用b,但是直接引用libb.a和b的头文件并不能成功。
c需要同时引用a、b并且在Makefile中a必须写在b的后面。

二、具体描述说明

使用redis做二次开发。
首先将redis-3.2.6打包成静态库redis.a,
编写了一套C++的接口slibredis封装redis.a,把slibredis也打包成静态库slibredis.a,
用封装的slibredis.a写项目。

(1)本以为只需要引用自己封装的静态库即可,也就是slibredis.a和其对应的头文件;
    没想到会出错。各种"not found"

(2)没办法,只能引用redis-3.2.6的头文件;
    结果还是不行,各种"undefined reference to `_XXXXXXXX()`"

(3)没办法,只能把redis.a也引用进来。
    结果还是不行,各种"undefined reference to `_XXXXXXXX()`"

(4)后来查了资料,原来这种情况对Makefile也有要求,
    也就是在Makefile中,需要把最先引用的静态库写在后引用静态库的后面,
 也就是Makefile中需要这样写:g++ (省略n个字) /path/to/slibredis.a /path/to/redis.a
 终于成功了。

三、其他解决方案

    当然网上也说了各种添加参数,可以在封装slibredis的时候可以避免静态库递归的。不过最终还是没能成功。

 

转载于:https://www.cnblogs.com/bugutian/p/6249596.html

<think>好的,用户想了解Makefile中静态模式赋值的用法,需要给出使用方法示例。首先,我需要确定用户所说的“静态模式赋值”具体指什么。根据提供的引用内容,引用[3]提到了Makefile的四种变量赋值方式,其中简单赋值使用`:=`,这可能就是用户所指的静态赋值。静态赋值在Makefile中被称为立即展开赋值,变量在定义时立即展开,不会延迟到使用时。 接下来,我需要确认静态模式赋值的正确术语用法。根据引用[3],简单赋值(:=)是立即赋值的,而其他赋值方式如递归赋值(=)会延迟展开。因此,用户的问题应该是指使用`:=`进行变量赋值,也就是静态赋值或立即赋值。 然后,我需要整理静态赋值的使用方法。要点包括:变量在定义时展开,不会包含后续的变量改变,适合需要立即确定值的情况。例如,如果变量B依赖于变量A,使用`:=`会在定义B时立即展开A的当前值,而后续A的变化不会影响B。 接下来,需要准备示例。根据引用[1][2]中的示例,可以构造一个涉及编译静态库的Makefile例子。例如,定义源文件、目标文件编译选项,使用静态赋值来确保变量的值在定义时确定。同时,可以展示递归赋值静态赋值的区别,比如变量值的覆盖情况。 还要注意用户提供的引用内容中的Makefile结构,如引用[2]中的变量定义规则,确保示例符合常见的Makefile写法。例如,使用`CC := gcc`来静态赋值编译器,`CFLAGS := -Wall -O2`定义编译选项,然后生成目标文件静态库。 最后,生成相关问题,帮助用户进一步学习,比如其他赋值方式的区别、选择静态赋值的场景,以及Makefile中的模式规则等。这些问题需要基于引用内容中的知识点,如引用[3]提到的四种赋值方式引用[4]关于Makefile的常见规则。 总结步骤: 1. 解释静态赋值(:=)的定义特点。 2. 提供使用方法的步骤。 3. 给出具体示例,展示静态赋值在Makefile中的应用。 4. 对比静态赋值递归赋值的区别。 5. 生成相关问题,引导深入学习。 需要确保示例代码正确,符合Makefile语法,并参考提供的引用中的结构,比如处理.o文件生成静态库的过程。同时,引用相关的引用来源,比如引用[3]来解释赋值方式,引用[2]中的示例结构。</think>### Makefile中静态模式赋值(`:=`)的用法详解 在Makefile中,**静态模式赋值**(即**立即展开赋值**)通过`:=`符号实现。其核心特点是变量在**定义时立即展开**,后续变量值的变化**不会影响**已定义的变量[^3]。 --- #### 一、使用方法 1. **基本语法** ```makefile 变量名 := 值 ``` - **值**可以是常量、其他变量或表达式 - 变量值的解析在**定义时完成**,而非使用时 2. **典型场景** - 需要**固定变量值**(如编译器路径、编译选项) - 避免变量因后续修改产生**意外覆盖** - 提高Makefile的**执行效率**(减少重复解析) --- #### 二、示例解析 ##### 示例1:基础静态赋值 ```makefile # 静态赋值定义编译器 CC := gcc CFLAGS := -Wall -O2 # 定义源文件目标文件 SRC := main.c utils.c OBJ := $(SRC:.c=.o) # 生成目标文件 %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ # 生成静态库 static_library: $(OBJ) ar -rcs libdemo.a $(OBJ) ``` - **特点**:`CC``CFLAGS`的值在定义时确定,即使后续被修改也不会影响已定义的规则。 --- ##### 示例2:静态赋值与递归赋值的对比 ```makefile # 递归赋值(=):延迟展开 A = 123 B = $(A) A = 456 # 静态赋值(:=):立即展开 C := $(A) A = 789 print: @echo "B=$(B), C=$(C)" ``` - **输出结果**:`B=789, C=456` - **原理**:`B`使用递归赋值,最终值为`A`的最终值;`C`使用静态赋值,值为`A`的当前值。 --- #### 三、关键注意事项 1. **性能优化** 静态赋值减少变量解析次数,适合**高频使用的变量**(如`CC`、`CFLAGS`)[^4]。 2. **避免值污染** 若变量值依赖**外部环境变量**(如`PATH`),建议使用静态赋值确保稳定性。 3. **与模式规则结合** 静态赋值常用于定义模式规则中的**固定参数**: ```makefile # 定义编译规则 COMPILE := $(CC) $(CFLAGS) -c %.o: %.c $(COMPILE) $< -o $@ ``` --- §§ 1. Makefile中递归赋值(`=`)静态赋值(`:=`)有什么区别? 2. 如何选择静态赋值条件赋值(`?=`)的场景?[^3] 3. Makefile中的模式规则(如`%.o: %.c`)如何与静态赋值结合使用?[^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值