Opened 7 years ago
Closed 7 years ago
#6429 closed defect (wontfix)
ffmpeg does not build properly without compiler optimization
Reported by: | patatahooligan | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | build system |
Version: | git-master | Keywords: | |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
I get the following error when building ffmpeg on Windows 10 with MSYS2 and the MSVC compiler.
swscale.o : error LNK2019: unresolved external symbol _ff_sws_init_swscale_ppc referenced in function _ff_getSwsFunc swscale.o : error LNK2019: unresolved external symbol _ff_sws_init_swscale_aarch64 referenced in function _ff_getSwsFunc swscale.o : error LNK2019: unresolved external symbol _ff_sws_init_swscale_arm referenced in function _ff_getSwsFunc swscale_unscaled.o : error LNK2019: unresolved external symbol _ff_get_unscaled_swscale_ppc referenced in function _ff_get_unscaled_swscale swscale_unscaled.o : error LNK2019: unresolved external symbol _ff_get_unscaled_swscale_arm referenced in function _ff_get_unscaled_swscale swscale_unscaled.o : error LNK2019: unresolved external symbol _ff_get_unscaled_swscale_aarch64 referenced in function _ff_get_unscaled_swscale utils.o : error LNK2019: unresolved external symbol _ff_yuv2rgb_init_tables_ppc referenced in function _sws_setColorspaceDetails yuv2rgb.o : error LNK2019: unresolved external symbol _ff_yuv2rgb_init_ppc referenced in function _ff_yuv2rgb_get_func_ptr libswscale/swscale-4.dll : fatal error LNK1120: 8 unresolved externals
I used the following commands
./configure --enable-asm --enable-yasm --arch=i386 --disable-ffserver --disable-avdevice --disable-doc --disable-ffplay --disable-ffprobe --disable-ffmpeg --enable-shared --disable-static --disable-bzlib --disable-libopenjpeg --disable-iconv --disable-zlib --prefix=<my local ffmpeg path> --toolchain=msvc --extra-cflags='-MDd -wd"4996" -MP' --optflags="-Od" --extra-ldflags='/NODEFAULTLIB:libcmt' --enable-debug make
Removing the '--optflags="-Od"' option leads to a successful build.
I tracked down some of the function calls in the error message to the following snippet from /libavutil/cpu.c
static int get_cpu_flags(void) { if (ARCH_AARCH64) return ff_get_cpu_flags_aarch64(); if (ARCH_ARM) return ff_get_cpu_flags_arm(); if (ARCH_PPC) return ff_get_cpu_flags_ppc(); if (ARCH_X86) return ff_get_cpu_flags_x86(); return 0; }
The functions are declared in libavutil/cpu.h and each one is defined in the corresponding libavutil/<architecture>/cpu.c file. Note how ff_get_cpu_flags_x86 was properly resolved. The other unresolved symbols are found in very similarly structured functions.
I assume configure only passes the folder to the currently selected architecture to the compiler, but libavutil/cpu.c technically relies on all of them having being compiled. However, by default the compiler seems to optimize away the if statements and function calls so the project links properly without the "-Od" option.
Changing these to preprocessor ifdefs or macros would solve this problem in a way that make the most sense in my opinion. Another solution would be to change configure so that it compiles the other architecture files, but this could lead to more errors and it doesn't really make sense to have this resolved at runtime even for debug builds. Not specifying a build doesn't change configure's behavior because it defaults to x86 anyway.
Requiring a certain level of optimizations (particularly Dead Code Elimination) is a known limitation of our code base. I'm sure there is various tickets already and a lot of discussions to be found.