Error: impossible constraint in ‘asm‘

在Windows环境下编译FFmpeg时遇到警告和错误,涉及mathops.h文件中的asm指令。文章提供了解决方案,建议更新到最新版的mathops.h并替换相应代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

错误如下:

我在windows下编译ffmpeg源码时,出现了如下的错误:

./libavcodec/x86/mathops.h:127:5: warning: 'asm' operand 1 probably does not match constraints
  127 |     __asm__ ("shrl %1, %0\n\t"
      |     ^~~~~~~
./libavcodec/x86/mathops.h:127:5: error: impossible constraint in 'asm'
make: *** [ffbuild/common.mak:60:libavformat/adtsenc.o] 错误 1
make: *** 正在等待未完成的任务....
CC      libavformat/anm.o
In file included from ./libavutil/common.h:488,
                 from ./libavutil/avutil.h:296,
                 from ./libavutil/samplefmt.h:24,
                 from ./libavcodec/avcodec.h:31,
                 from libavformat/avformat.h:319,
                 from libavformat/anm.c:28:

解决:

将ffmpeg源码中 mathops.h 中的如下代码做一个修改,其实在新版本的ffmpeg中已经修复了这个问题,可以去查看一下最新版的ffmpeg中 libavcodec/x86/mathops.h 中的修改,然后将我们的mathops.h 修改为如下:

#define MULL MULL
static av_always_inline av_const int MULL(int a, int b, unsigned shift)
{
    int rt, dummy;
    __asm__ (
        "imull %3               \n\t"
        "shrdl %4, %%edx, %%eax \n\t"
        :"=a"(rt), "=d"(dummy)
        :"a"(a), "rm"(b), "c"((uint8_t)shift)
    );
    return rt;
}
#define NEG_SSR32 NEG_SSR32
static inline  int32_t NEG_SSR32( int32_t a, int8_t s){
    __asm__ ("sarl %1, %0\n\t"
         : "+r" (a)
         : "c" ((uint8_t)(-s))
    );
    return a;
}

#define NEG_USR32 NEG_USR32
static inline uint32_t NEG_USR32(uint32_t a, int8_t s){
    __asm__ ("shrl %1, %0\n\t"
         : "+r" (a)
         : "c" ((uint8_t)(-s))
    );
    return a;
}

具体可查看下面这篇文章:点击此处

<think>嗯,用户遇到了一个错误:在使用Google OR-Tools库时,尝试给约束添加条件,但报错说'Constraint'对象没有'OnlyEnforceIf'属性。首先,我需要确认这个问题的可能原因。 根据错误信息,用户可能错误地使用了solver.Add()方法返回的约束对象。在OR-Tools中,solver.Add()返回的是一个Constraint实例,而这个类可能确实没有OnlyEnforceIf方法。正确的做法应该是使用cp_model库中的CpModel类来创建约束,并且使用Add方法的同时直接应用条件。 接下来,我需要回忆OR-Tools的CP-SAT求解器的使用方法。CpModel类中的Add方法允许添加带有条件的约束,比如使用OnlyEnforceIf。可能用户错误地使用了solver.Add()而不是model.Add(),或者没有正确导入CpModel。 另外,用户代码中的变量x_lom可能是使用CpModel创建的IntVar,所以应该通过model来添加约束,而不是直接使用solver。正确的语法应该是model.Add(s_lom == 0).OnlyEnforceIf(...),而不是通过solver对象。 因此,解决方案应该是将solver.Add替换为model.Add,并确保model是CpModel的实例。同时,检查是否正确导入了CpModel,例如使用from ortools.sat.python import cp_model。 还需要验证用户是否在创建变量时使用了正确的模型实例。例如,x_lom应该通过model.NewBoolVar()等方法创建,而不是solver的方法,因为OR-Tools的CP-SAT求解器推荐使用CpModel来管理变量和约束。 总结错误原因:用户可能混淆了solver和model的用法,错误地通过solver添加约束,而应该使用model来添加带有条件的约束。需要调整代码结构,使用CpModel实例的Add方法,并正确应用OnlyEnforceIf。</think>这个错误是由于在Google OR-Tools的CP-SAT求解器中错误地使用约束条件方法导致的。以下是逐步分析及解决方案: **错误原因分析:** 1. `solver.Add()`返回的是一个基础约束对象,这个对象本身没有`OnlyEnforceIf()`方法。 2. CP-SAT的条件约束必须通过`cp_model.CpModel`类的方法链式调用直接创建。 **正确代码应满足以下条件:** ```python # 正确写法示例 model.Add(s_lom == 0).OnlyEnforceIf(x_lom[lotID, operationID, machineID].Not()) ``` **具体修改步骤:** 1. **确认模型对象类型**: ```python from ortools.sat.python import cp_model model = cp_model.CpModel() # 必须是CpModel实例 ``` 2. **使用model.Add()代替solver.Add()**: ```python # 错误写法 ❌ solver.Add(...).OnlyEnforceIf(...) # 正确写法 ✅ model.Add(...).OnlyEnforceIf(...) ``` 3. **检查变量定义方式**: 确保`x_lom`是使用CpModel创建的布尔变量: ```python x_lom = {} for lot in lot_list: for op in op_list: for machine in machine_list: x_lom[lot, op, machine] = model.NewBoolVar(f'x_{lot}_{op}_{machine}') ``` 4. **完整示例代码结构**: ```python from ortools.sat.python import cp_model model = cp_model.CpModel() solver = cp_model.CpSolver() # 定义变量 x_lom = model.NewBoolVar(...) # 必须是CpModel创建的变量 # 添加条件约束 constraint = model.Add(s_lom == 0).OnlyEnforceIf(x_lom.Not()) ``` **关键注意事项:** - CP-SAT求解器中所有约束必须通过`CpModel`对象添加 - `OnlyEnforceIf()`只能用于布尔类型的变量/表达式 - 确保使用的OR-Tools版本≥9.3(旧版本可能不支持此语法) 建议参考官方文档验证代码结构:[OR-Tools CP-SAT Constraints](https://developers.google.com/optimization/cp/cp_solver#constraints)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

21岁被迫秃头

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

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

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

打赏作者

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

抵扣说明:

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

余额充值