当前位置: 首页 > article >正文

ffmpeg configure 研究1-命令行参数的分析


author: hjjdebug
date: 2025年 02月 14日 星期五 17:16:12 CST
description: ffmpeg configure 研究1
./configure 命令行参数的分析


文章目录

    • 1 configure 对命令行参数的分析,在4019行
      • 1.1 函数名称: is_in
      • 1.2. 函数名称: enable
      • 1.3. 函数名称: set_all
    • 2 执行退出判断的关键代码:
      • 2.1. 函数名称: map
      • 2.2 函数名称: die_license_disabled
      • 2.3 函数名称 enabled()
    • 3. 小测试代码
    • 4.执行结果 $ ./1.sh
    • 5.小结:
      • 小结1: 命令行参数分析过程概括.
      • 小结2: bash脚本的本质是什么?

详细分析了 ffmpeg 下执行
./configure --enable-libx264
libx264 is gpl and --enable-gpl is not specified.
程序退出的过程

如果说在命令行上有 --enable-libx264 而没有 --enable-gpl 就退出,
用c 写也就寥寥几句,
libx264_enable=false,gpl_enable=fale;
for(int i=0;i<argc;i++)
{
if(strcmp(arg[i],“–enable-libx264”)0) libx264_enable=true;
if(strcmp(arg[i],“–enable-gpl”)0) gpl_enable=true;
}
if(libx264_enable
true && gpl_enable
false) exit(1)

如果用bash 又应该怎么写呢?
如果只是实现上边的功能,bash 也可以写的很简单, 但在configure 文件中就不是那样写了.
而是有一个复杂的架构,
为什么?因为它要支持一些复杂的功能.

所以该博客就是来了解这个简单的功能是如何在复杂的架构上实现的.
让我们能窥斑见豹. 别被它庞大的架构吓唬注了.
这些是bash编程最基本的东西, 就从此开始吧.

1 configure 对命令行参数的分析,在4019行

for opt do
因为 opt 后面没有 in 参数, 实际上就是 in “ @ " , 代码处于顶层 , @",代码处于顶层, @",代码处于顶层,@就是命令行参数,此时
$opt = --enable-libx264
case 语句会匹配到4087行
–enable-?|–disable-?)
eval ( e c h o " (echo " (echo"opt” | sed ‘s/–/action=/;s/-/ option=/;s/-/_/g’)
if is_in $option $COMPONENT_LIST; then
test $action = disable && action=unset
eval $action $$(toupper ${option%s})_LIST
elif is_in $option $CMDLINE_SELECT; then
$action $option
else
die_unknown $opt
fi

bash 在每次执行命令前要进行8大变换. 其是也是很简单的.
大括号扩展 {} , 把形如 {1…5} 扩展为 1 2 3 4 5
波浪线扩展 ~ , 把~扩展为你的家目录
变量扩展 , 简单方式就是 {} , 简单方式就是 ,简单方式就是var样式, 就是变量引用和变量替换
算术扩展 $(()) , 数学运算在这里进行
命令替换 $()或 ``, 这里可以调用命令,先执行命令
分词分割 IFS , 按照空格,tab,回车来分割成单词
路径扩展 * ? [] , 把*展开匹配任意字符,?匹配0或1个字符,[]匹配指定字符
引号去除 , 去除其中的双引号,单引号

把该行信息都收拾一遍叫扫描,然后再交给bash去执行命令,
eval ( e c h o " (echo " (echo"opt" | sed ‘s/–/action=/;s/-/ option=/;s/-//g’)
eval 语句会进行2次扫描. 即扩展了一遍还要再扩展一遍,所以有$$(…)之类的写法
执行第一遍扫描,进行变量扩展
eval $(echo --enable-libx264 | sed 's/–/action=/;s/-/ option=/;s/-/
/g’)
,进行命令替换
eval action=enable option=libx264

运行eval命令,执行第二遍扫描,(此例第一遍已经扩展干净了,第二遍没有要改变的.)
action=enable option=libx264
这条语句交给bash执行,就是定义了2个变量,并赋值.
elif is_in $option $CMDLINE_SELECT; then
$action o p t i o n l i b x 264 在 option libx264 在 optionlibx264CMDLINE_SELECT 中被发现,会执行 enable libx264 函数


1.1 函数名称: is_in

输入参数: 列表
输出参数:
返回值: 0(成功), 1(失败,假)
描述: 把第一个参数作为值, 依次与后续参数做比较,如果想等,返回成功,全部不成功,返回失败.


is_in(){
value=$1 # 第一个参数为value
shift
for var in KaTeX parse error: Expected 'EOF', got '#' at position 7: *; do #̲ 后续参数与value相比
[ $var = KaTeX parse error: Expected 'EOF', got '&' at position 9: value ] &̲& return 0 # 相同…value被扩展为libx264, $CMDLINE_SELECT 被扩展为一堆字符串, 其中包含libx264, 所以其返回为成功.
$action $option 被扩展为:
enable libx264


1.2. 函数名称: enable

输入参数: 列表
输出参数: 无
返回值: 无
描述: 把参数都做为变量,其值设置为"yes"


enable(){
set_all yes $*
}
执行结果, 把libx264 设置为了 yes, 等价与 libx264=yes


1.3. 函数名称: set_all

输入参数: 列表
输出参数: 无
返回值: 无
描述: 把第一个参数作为value, 其余的参数都作为变量用$value赋值


set_all(){
value=$1 # 第一个参数为value,
shift # 移除第一个参数
for var in $*; do
eval v a r = var= var=value # 其余参数都设置为$value
done
}

注意: 调试时打印pr value 是没有意义的, pr $value才是对变量的引用.

2 执行退出判断的关键代码:

map “die_license_disabled gpl” $EXTERNAL_LIBRARY_GPL_LIST $EXTERNAL_LIBRARY_GPLV3_LIST
$EXTERNAL_LIBRARY_GPL_LIST 变量在1721行有定义,包括libx264,libx265及其它模块
该语句功能. 检查一系列模块,如果enable 了模块而没有enable gpl, 就退出.


2.1. 函数名称: map

输入参数: 列表
输出参数: 无
描述: 把第一个参数作为命令, 后续参数依次作为$v参数,来执行第一条命令


map(){
m=$1 # 把die_license_disabled gpl 赋值给m
shift
for v; do eval $m; done # 把后面的参数依次送给v, 执行 $m,即执行die_license_disabled gpl 函数
}


2.2 函数名称: die_license_disabled

输入参数: 函数调用参数 1 , 全局参数 1, 全局参数 1,全局参数v
输出参数: 无
功能描述: 判断第1个参数(对应“gpl”,“nonfree”)是否enabled,如果已经enabled,则正常退出;
否则判断$v 参数是否 enabled, 如果为真则打印错误信息并退出(die 函数)
注意: 不满足条件时会退出程序.


die_license_disabled() {
enabled $1 || { enabled KaTeX parse error: Expected 'EOF', got '&' at position 3: v &̲& die "v is $1 and --enable-$1 is not specified."; }
}
命令可以作为map 的第一个参数. 该命令接受的参数是$1 和 $v


2.3 函数名称 enabled()

输入参数: 一个参数
输出参数: 无
返回值: 0或1
描述: 对参数$1 判断其值是否是"yes"


enabled(){
test “${1#!}” = “$1” && op=“=” || op=“!=” # 该句设置op为等号或不等号
eval test “x$${1#!}” $op “xyes” # 运行test返回真值或假值.
}
${1#!}是$1变量去除从开始到!止部分,$1无!则不会去除任何东西.

3. 小测试代码

为了对enabled() 函数,die() 及颜色设置有更深入理解,我写了如下测试函数

$ cat 1.sh
#!/bin/bash
enabled(){
    test "${1#!}" = "$1" && op="=" || op="!=" # 根据第一个参数是否首字符为!为op赋值=或者!=
    eval test "x\$${1#!}" $op "xyes"  # 测试变量的值是否为yes
}
if test -t 1 && which tput >/dev/null 2>&1; then
    ncolors=$(tput colors)
    if test -n "$ncolors" && test $ncolors -ge 8; then
        bold_color=$(tput bold)
		warn_color=$(tput setaf 3)    # 设置前景色为黄(3)
		error_color=$(tput setaf 1)   # 设置前景色为红(1) , set attr foregroud
        reset_color=$(tput sgr0)      # 恢复颜色, set groud 0
    fi
    # 72 used instead of 80 since that's the default of pr
    ncols=$(tput cols)
fi
: ${ncols:=72}  # :就是空操作, 退出总是成功 ${var:=}, 如果ncols 没有值,就给72,否则保持不变

logfile="1.log"
log(){
    echo "$@" >> $logfile
}
die(){
    log "$@"
    echo "$error_color$bold_color$@$reset_color" # 设置红色,加重的颜色,显示$@ 然后颜色再恢复
}

abc=yes
enabled abc && echo "abc enabled" || echo "abc not enabled"
enabled abb && echo "abb enabled" || echo "abb not enabled"

die "I hope this is red"

4.执行结果 $ ./1.sh

abc enabled
abb not enabled
I hope this is red

5.小结:

小结1: 命令行参数分析过程概括.

对于 --enable-libx64 参数而言,它是一个动词-名词的结构,首先用sed将它分为2部分.
把动词作为函数,把名字作为参数执行函数, 实现把名词作为变量进行赋值.
命令行参数分析完后, 对变量进行数值判断,不满足条件则退出程序.

小结2: bash脚本的本质是什么?

bash脚本命令. 就是一个命令的集合体.
命令就是你在控制台下与机器交互输入的命令
你在命令行下所做的操作, 用bash脚本都可以完成.
命令是带参数的.
参数是可以用变量来存储的.
参数经过8大扩展再传递给命令
引入变量和函数可以简化人机的接口,使少敲几个字符就给计算机说明白了.
函数也是由命令集合来构成,支持参数传递,为完成特定功能而编写.
变量和函数的灵活性也增加了代码的复杂性.

所以bash脚本就是不断的执行预定的命令. 不用你在控制台下手敲了.
常在bash下工作的人, 用脚本编程简化维护等工作也是很自然的了.


http://www.kler.cn/a/552775.html

相关文章:

  • 什么是网络安全?网络安全防范技术包括哪些?
  • 【新人系列】Python 入门(三十一):内存管理
  • 【系列专栏】银行IT的云原生架构-混合云弹性架构 13
  • 2.18寒假
  • 【2.18更新版】WordPress内容生成免费插件:AI图文+视频+长尾关键词自动生成,已内置deepseek、kimi全模型
  • 【R语言】聚类分析
  • Apifox 增强 AI 接口调试功能:自动合并 SSE 响应、展示DeepSeek思考过程
  • 驾培行业转战无人机飞手执照培训的优缺点分析及技术详解
  • 网络安全“挂图作战“及其场景
  • Tauri+Trae+Deepseek写几个小游戏
  • 预定义委托(C# and Unity)
  • 网络编程套接字之TCP
  • ES8字符串填充用法总结:padStart(),padEnd(),rest剩余参数的用法{name,...obj},扩展运算符的用法,正则表达式命名捕获组
  • LabVIEW利用CANopen的Batch SDO写入
  • DEX-EE三指灵巧手:扩展AI与机器人研究的边界
  • win10系统上的虚拟机安装麒麟V10系统提示找不到操作系统
  • 赛前启航 | Azure 应用开发实战指南:开启创意的无限可能
  • RadASM环境,win32汇编入门教程之六
  • MySQL 索引失效处理:原因分析与优化实战
  • vue3项目,旅游景点页面