使用 emcc 编译 ffmpeg 时出错:“cbrt”的静态声明遵循非静态声明

Posted

技术标签:

【中文标题】使用 emcc 编译 ffmpeg 时出错:“cbrt”的静态声明遵循非静态声明【英文标题】:Errors while ffmpeg compiling with emcc : static declaration of 'cbrt' follows non-static declaration 【发布时间】:2020-08-29 08:51:01 【问题描述】:

我尝试使用 emscripten 通过以下脚本编译 ffmpeg,但在编译时出现错误:(使用 Mac pro - Docker ubuntu FFmpeg:4.3.1 和 emcc:2.0.1)

make: make
CC  libavdevice/alldevices.o
In file included from ./libavutil/internal.h:176:
./libavutil/libm.h:54:32: error: static declaration of 'cbrt' follows non-static declaration
static av_always_inline double cbrt(double x)
                               ^
/home/winixt/emsdk/upstream/emscripten/system/include/libc/math.h:151:13: note: previous declaration is here
double      cbrt(double);
            ^
In file included from ./libavutil/internal.h:176:
./libavutil/libm.h:61:31: error: static declaration of 'cbrtf' follows non-static declaration
static av_always_inline float cbrtf(float x)
                              ^
/home/winixt/emsdk/upstream/emscripten/system/include/libc/math.h:152:13: note: previous declaration is here
float       cbrtf(float);
            ^
In file included from ./libavutil/internal.h:176:
./libavutil/libm.h:68:32: error: static declaration of 'copysign' follows non-static declaration
static av_always_inline double copysign(double x, double y)
                               ^
/home/winixt/emsdk/upstream/emscripten/system/include/libc/math.h:159:13: note: previous declaration is here
double      copysign(double, double);

In file included from ./libavutil/internal.h:176:
./libavutil/libm.h:121:22: error: static declaration of 'erf' follows non-static declaration
static inline double erf(double z)
                     ^
/home/winixt/emsdk/upstream/emscripten/system/include/libc/math.h:171:13: note: previous declaration is here
double      erf(double);
            ^

In file included from ./libavutil/internal.h:176:
./libavutil/libm.h:340:9: warning: 'isnan' macro redefined [-Wmacro-redefined]
#define isnan(x)                  \
        ^
/home/winixt/emsdk/upstream/emscripten/system/include/libc/math.h:66:9: note: previous definition is here
#define isnan(x) ( \
        ^

In file included from ./libavutil/common.h:533:
In file included from ./libavutil/internal.h:176:
./libavutil/libm.h:359:9: warning: 'isfinite' macro redefined [-Wmacro-redefined]
#define isfinite(x)                  \
        ^
/home/winixt/emsdk/upstream/emscripten/system/include/libc/math.h:76:9: note: previous definition is here
#define isfinite(x) ( \
        ^

In file included from ./libavutil/internal.h:176:
./libavutil/libm.h:366:31: error: static declaration of 'hypot' follows non-static declaration
static inline av_const double hypot(double x, double y)
                              ^
/home/winixt/emsdk/upstream/emscripten/system/include/libc/math.h:223:13: note: previous declaration is here
double      hypot(double, double);
            ^
In file included from ./libavutil/internal.h:176:
./libavutil/libm.h:423:22: error: static declaration of 'rint' follows non-static declaration
static inline double rint(double x)
                     ^
/home/winixt/emsdk/upstream/emscripten/system/include/libc/math.h:307:13: note: previous declaration is here
double      rint(double);
            ^
In file included from ./libavutil/internal.h:176:
./libavutil/libm.h:430:43: error: static declaration of 'lrint' follows non-static declaration
static av_always_inline av_const long int lrint(double x)
                                          ^
2 warnings and 12 errors generated.
emcc: error: '/home/winixt/emsdk/upstream/bin/clang -target wasm32-unknown-emscripten -D__EMSCRIPTEN_major__=1 -D__EMSCRIPTEN_minor__=39 -D__EMSCRIPTEN_tiny__=20 -D_LIBCPP_ABI_VERSION=2 -Dunix -D__unix -D__unix__ -Werror=implicit-function-declaration -Xclang -nostdsysteminc -Xclang -isystem/home/winixt/emsdk/upstream/emscripten/system/include/compat -Xclang -isystem/home/winixt/emsdk/upstream/emscripten/system/include -Xclang -isystem/home/winixt/emsdk/upstream/emscripten/system/include/libc -Xclang -isystem/home/winixt/emsdk/upstream/emscripten/system/lib/libc/musl/arch/emscripten -Xclang -isystem/home/winixt/emsdk/upstream/emscripten/system/local/include -Xclang -isystem/home/winixt/emsdk/upstream/emscripten/system/include/SSE -Xclang -isystem/home/winixt/emsdk/upstream/emscripten/system/lib/compiler-rt/include -Xclang -isystem/home/winixt/emsdk/upstream/emscripten/cache/wasm/include -DEMSCRIPTEN -fignore-exceptions -D__EMSCRIPTEN_PTHREADS__=1 -I. -I./ -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DHAVE_AV_CONFIG_H -DBUILDING_avdevice -std=c11 -fomit-frame-pointer -pthread -g -Wdeclaration-after-statement -Wall -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -Wmissing-prototypes -Wno-pointer-to-int-cast -Wstrict-prototypes -Wempty-body -Wno-parentheses -Wno-switch -Wno-format-zero-length -Wno-pointer-sign -Wno-unused-const-variable -Wno-bool-operation -Wno-char-subscripts -O3 -fno-math-errno -fno-signed-zeros -mllvm -stack-alignment=16 -mstack-alignment=16 -Qunused-arguments -Werror=implicit-function-declaration -Werror=missing-prototypes -Werror=return-type -MMD -MF libavdevice/alldevices.d -MT libavdevice/alldevices.o -c -pthread -pthread libavdevice/alldevices.c -Xclang -isystem/home/winixt/emsdk/upstream/emscripten/system/include/SDL -c -o libavdevice/alldevices.o -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr' failed (1)
make: *** [ffbuild/common.mak:59: libavdevice/alldevices.o] Error 1

这是我的命令:

试了emcc不合理的版本(2.0.1、2.0.0、1.40.1、1.39.20),还是遇到同样的错误。

官网的docker image也不好。

emconfigure ./configure \
  --disable-x86asm \
  --ar=emar \
  --cc=emcc \
  --cxx=em++ \
  --objcc=emcc \
  --dep-cc=emcc \
  --disable-inline-asm \
  --disable-doc \
  --disable-stripping

emmake make

【问题讨论】:

【参考方案1】:

我使用这些命令在Ubuntu中构建成功,但它直接返回给我js文件和wasm文件。这与官方文档不同。因此我不知道如何添加emcc pars。

emconfigure   ./configure --cc="emcc" --enable-cross-compile --target-os=none --arch=x86_64 --cpu=generic \
--disable-ffplay --disable-ffprobe --disable-asm --disable-doc --disable-devices --disable-pthreads --disable-w32threads --disable-network \
--disable-hwaccels --disable-parsers --disable-bsfs --disable-debug --disable-protocols --disable-indevs --disable-outdevs --enable-protocol=file  --disable-stripping --ranlib="emranlib"   

emmake make

困扰了我一个星期,如果你发现了什么,请依赖我。谢谢。

【讨论】:

【参考方案2】:

不确定它与使用 emlibc 的线程问题有关。它与 libavutils 冲突。 您可以尝试添加--disable-pthreads--disable-w32threads 因为pthread会被自动检测到。

--disable-pthreads       disable pthreads [autodetect]
emconfigure ./configure \
--cc="emcc" \
--cxx="em++" \
--ar="emar" \
--enable-cross-compile \
--target-os=none \
--arch=x86_32 \
--cpu=generic \
...
--disable-pthreads \
--disable-w32threads \
...

【讨论】:

以上是关于使用 emcc 编译 ffmpeg 时出错:“cbrt”的静态声明遵循非静态声明的主要内容,如果未能解决你的问题,请参考以下文章

将ffmpeg中的x86 asm和inline-asm编译成WebAssembly的问题

如何使 emcc 工作?

Emscripten教程之emcc编译命令

使用 ffmpeg 构建 opencv 时出错

使用 FFMPEG 裁剪视频时出错

FFMpeg;混合两个音频流时出错