Log in

View Full Version : Help compiling x264 from source on Cygwin - fatal errors unless AVS is disabled


Kaos-Industries
5th March 2019, 02:54
I'm trying to follow the FFmpeg wiki's guide here to build FFmpeg from source with the most superior codecs it can make use of, like libfdk-aac and libopus:

https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu

I've sorted many of the dependencies to get it to work on Cygwin, and thankfully I didn't need to build most of the packages in that guide from source because they were included in the Cygwin repository, but there are 2 or 3 that are not, including x264 and x265.

So I'm now trying to build x264 from source with the following command:

cd /ffmpeg_sources && git -C x264 pull 2> /dev/null || git clone --depth 1 https://git.videolan.org/git/x264
&& cd x264 && PATH="/usr/local/bin:$PATH" PKG_CONFIG_PATH="/ffmpeg_build/lib/pkgconfig" ./configure --prefix="/ffmpeg_build"
--bindir="/usr/local/bin" --enable-static --enable-pic && PATH="usr/local/bin:$PATH" make -j4 && make install

But at the configure stage of this command, I get a few errors and lots of warnings, but the final error is this one:

[Makefile:272: input/avs.o] Error 1

The error immediately before the one above is the HMODULE error here:

https://stackoverflow.com/questions/45181102/ffmpeg-on-cygwin-failed-to-compile-libx264-error-unknown-type-name-hmodule

And in that question the OP and another answer are trying to follow the very same guide I am while using Cygwin on the same 64-bit Windows 7.

What's the problem here and how can I solve it? The errors go away and the compilation works when I include --disable-avs, but I don't want the version of FFmpeg that I build to come without AVS/Avisynth support.

Thank you in advance.

qyot27
7th March 2019, 04:52
You're confusing which parts make which input active and for which program. --disable-avs is what x264's configure script uses to disable AviSynth support in the x264 CLI program. It does absolutely nothing to libx264 (which has no input modules), FFmpeg uses libx264, and FFmpeg doesn't care at all whether x264's CLI program has AviSynth enabled. Making AviSynth enabled in FFmpeg is its own option given to FFmpeg's configure script, --enable-avisynth.

The SO answer by Missy tells you exactly what's needed to make x264.exe compile with AviSynth under Cygwin. The problem lies in Cygwin's w32api headers not including wtypes.h in the correct place. The proper fix is that Cygwin's windows.h header needs to include wtypes.h; a stop-gap would be to edit x264's local input/avs.c and insert the wtypes.h include before the include for extras/avisynth_c.h before you compile it. FFmpeg likely will hit the exact same roadblock, making it imperative on Cygwin to fix their header if you want this to be possible without editing stuff yourself.

Kaos-Industries
7th March 2019, 21:00
You're confusing which parts make which input active and for which program. --disable-avs is what x264's configure script uses to disable AviSynth support in the x264 CLI program. It does absolutely nothing to libx264 (which has no input modules), FFmpeg uses libx264, and FFmpeg doesn't care at all whether x264's CLI program has AviSynth enabled. Making AviSynth enabled in FFmpeg is its own option given to FFmpeg's configure script, --enable-avisynth.

The SO answer by Missy tells you exactly what's needed to make x264.exe compile with AviSynth under Cygwin. The problem lies in Cygwin's w32api headers not including wtypes.h in the correct place. The proper fix is that Cygwin's windows.h header needs to include wtypes.h; a stop-gap would be to edit x264's local input/avs.c and insert the wtypes.h include before the include for extras/avisynth_c.h before you compile it. FFmpeg likely will hit the exact same roadblock, making it imperative on Cygwin to fix their header if you want this to be possible without editing stuff yourself.

Interesting, I suppose I assumed that FFmpeg can only build from the features of the sources that it builds from - my knowledge of compiling isn't too great.

I have tried approaching the Cygwin mailing lists with this but the response I got was that Cygwin wasn't the problem, but maybe coming to them with a more specific solution will change that.

Thanks for the succinct explanation of the problem, a lot of this now falls into place and makes sense, but something still doesn't add up here. I had tried Missy's answer prior, and it resulted in AVS being disabled by default. Sure enough, when I make the necessary change to the windows.h file (which is part of the MinGW Runtime Environment and located in "/usr/include/w32api/") and then run configure and make as before:

cd /ffmpeg_sources && git -C x264 pull 2> /dev/null || git clone --depth 1 https://git.videolan.org/git/x264 && cd x264 && PATH="/usr/local/bin:$PATH"
PKG_CONFIG_PATH="/ffmpeg_build/lib/pkgconfig" ./configure --prefix="/ffmpeg_build" --bindir="/usr/local/bin" --enable-static --enable-pic && PATH="usr/local/bin:$PATH" make -j4 && make install

...I get the following output that says AVS has been disabled:

Cloning into 'x264'...
remote: Counting objects: 258, done.
remote: Compressing objects: 100% (257/257), done.
remote: Total 258 (delta 42), reused 31 (delta 0)
Receiving objects: 100% (258/258), 998.27 KiB | 2.43 MiB/s, done.
Resolving deltas: 100% (42/42), done.
.git config.guess doc filters tools x264cli.h
.gitignore config.sub encoder input version.sh x264dll.c
AUTHORS configure example.c Makefile x264.c x264res.rc
common COPYING extras output x264.h
platform: X86_64
byte order: little-endian
system: CYGWIN
cli: yes
libx264: internal
shared: no
static: yes
asm: yes
interlaced: yes
avs: no
lavf: no
ffms: no
mp4: no
gpl: yes
thread: posix
opencl: no
filters: crop select_every
lto: no
debug: no
gprof: no
strip: no
PIC: yes
bit depth: all
chroma format: all

In other words, including wtypes.h seems to have the same effect as doing configure --disable-avs, and that's why the build then goes on to complete successfully. Any idea why including wtypes.h goes ahead and disables AVS/Avisynth anyway?

filler56789
7th March 2019, 21:54
Before qyot27 chimes in again, I have a question:

do you really have to use Cygwin? :confused:

Why not use MSYS2? :confused:

Kaos-Industries
7th March 2019, 22:24
Before qyot27 chimes in again, I have a question:

do you really have to use Cygwin? :confused:

Why not use MSYS2? :confused:

MSYS creates its own ecosystem isolated from the rest of the system. I already use Cygwin on Windows 7 and have for the last two years to good results. In fact, I already had a Windows binary installation of FFmpeg that Cygwin could also make use of, and did a lot of editing with that.

I'm building from source to get a build of FFmpeg that comes with the best codecs FFmpeg can make use of, such as lib_fdkaac and libopus, and one that's integrated into the rest of the Cygwin ecosystem unlike MSYS would be.

Rumbah
8th March 2019, 00:55
Did you try the media autobuild suite? ( https://github.com/jb-alvarado/media-autobuild_suite )
It does exactly what you want but with MSYS. You just configure what stuff you want in your ffmpeg build and it downloads, patches and compiles everything for you. Including its own independant MSYS environment.

Kaos-Industries
8th March 2019, 02:32
Did you try the media autobuild suite? ( https://github.com/jb-alvarado/media-autobuild_suite )
It does exactly what you want but with MSYS. You just configure what stuff you want in your ffmpeg build and it downloads, patches and compiles everything for you. Including its own independant MSYS environment.

See the post directly above yours for why that "independent MSYS environment" is the opposite of what I'm looking for. And yes, I have tried the Media Autobuild Suite, it's an even worse solution than MSYS on its own considering the bloat included in it and how long it takes to install.

qyot27
8th March 2019, 04:12
In other words, including wtypes.h seems to have the same effect as doing configure --disable-avs, and that's why the build then goes on to complete successfully. Any idea why including wtypes.h goes ahead and disables AVS/Avisynth anyway?
What's happening is that throwing wtypes.h into windows.h like that breaks the configure script's ability to correctly check for LoadLibraryW, which is what allows AviSynth to interface with x264.exe in the first place. The check fails, so it cannot enable AviSynth input.

Compare to MinGW-w64, where HMODULE is correctly enabled without wtypes.h being placed in windows.h or input/avs.c or checked for in the configure script. There's probably some place subtly different between MinGW-w64's and Cygwin's headers where wtypes.h does get included that explains this, but I wouldn't know exactly where.

MSYS creates its own ecosystem isolated from the rest of the system. I already use Cygwin on Windows 7 and have for the last two years to good results. In fact, I already had a Windows binary installation of FFmpeg that Cygwin could also make use of, and did a lot of editing with that.

I'm building from source to get a build of FFmpeg that comes with the best codecs FFmpeg can make use of, such as lib_fdkaac and libopus, and one that's integrated into the rest of the Cygwin ecosystem unlike MSYS would be.
That just sounds like path issues as it relates to installed defaults. Cygwin inherits the value of Windows' %PATH% variable by default; MSys2 doesn't by default, but that doesn't mean you can't tell it to do so. Just add the following block into the mingw32.ini, mingw64.ini, or msys.ini config files:
CHERE_INVOKING=1
MSYS2_PATH_TYPE=inherit
MSYSTEM=MINGW32
(MSYSTEM=MINGW64 for mingw64.ini, MSYSTEM=MSYS for msys.ini)

The reverse, accessing stuff installed to MSys' FHS in a normal Windows cmd.exe session, is just a matter of adding the Windows-style location of MSys' /usr/bin and /usr/local/bin to Windows' %PATH% variable. The same thing is true of Cygwin, and Cygwin's /usr/bin and /usr/local/bin.


Of course, most of that is inconsequential to the immediate discussion (aside from pacman, that's so much nicer to use than Cygwin's package management system, or that MSys2 has newer versions of GCC and MinGW-w64 than Cygwin does, or at least newer than some mirrors for Cygwin do), since Cygwin allows you to install MinGW-w64 and cross-compile such that these issues with HMODULE and wtypes.h would be moot. MinGW-w64 doesn't have that issue the way Cygwin's w32api system base does.

Going out on a limb, however, if you want the most recent stable versions of GCC and MinGW-w64, the steps for setting up a cross-environment on Linux probably map to Cygwin without much hassle (apart from figuring out the right package equivalents for the apt-get commands, using checkinstall at any point, and omitting Wine):
https://github.com/qyot27/mpv/blob/extra-new/DOCS/crosscompile-mingw-tedious.txt

(despite what the note says, --disable-lto does not cause a build error if you don't kill the GCC build process and try to reconfigure it without cleaning/deleting the temp files first; and --disable-lto is necessary to avoid the binutils 'too many file descriptors' issue that does hit FFmpeg in particular)

Kaos-Industries
10th March 2019, 01:58
What's happening is that throwing wtypes.h into windows.h like that breaks the configure script's ability to correctly check for LoadLibraryW, which is what allows AviSynth to interface with x264.exe in the first place. The check fails, so it cannot enable AviSynth input.

Compare to MinGW-w64, where HMODULE is correctly enabled without wtypes.h being placed in windows.h or input/avs.c or checked for in the configure script. There's probably some place subtly different between MinGW-w64's and Cygwin's headers where wtypes.h does get included that explains this, but I wouldn't know exactly where.

So is there nothing actually *wrong* per se with Cygwin's implementation? Is it intended behaviour to behave the way it does? I'm wondering how likely it is be able to get a fix implemented via the Mailing List if from their POV there's nothing to fix.



That just sounds like path issues as it relates to installed defaults. Cygwin inherits the value of Windows' %PATH% variable by default; MSys2 doesn't by default, but that doesn't mean you can't tell it to do so. Just add the following block into the mingw32.ini, mingw64.ini, or msys.ini config files:
CHERE_INVOKING=1
MSYS2_PATH_TYPE=inherit
MSYSTEM=MINGW32
(MSYSTEM=MINGW64 for mingw64.ini, MSYSTEM=MSYS for msys.ini)

The reverse, accessing stuff installed to MSys' FHS in a normal Windows cmd.exe session, is just a matter of adding the Windows-style location of MSys' /usr/bin and /usr/local/bin to Windows' %PATH% variable. The same thing is true of Cygwin, and Cygwin's /usr/bin and /usr/local/bin.


Definitely not path issues, when i say ecosystem, I'm referring to the installation paths. I'd rather add some packages to Cygwin or use a Windows cross-compiled binary as I normally would rather than go through the hassle of setting up a standalone MSYS environment just for the purpose of using FFmpeg.


Of course, most of that is inconsequential to the immediate discussion (aside from pacman, that's so much nicer to use than Cygwin's package management system, or that MSys2 has newer versions of GCC and MinGW-w64 than Cygwin does, or at least newer than some mirrors for Cygwin do), since Cygwin allows you to install MinGW-w64 and cross-compile such that these issues with HMODULE and wtypes.h would be moot. MinGW-w64 doesn't have that issue the way Cygwin's w32api system base does.

Going out on a limb, however, if you want the most recent stable versions of GCC and MinGW-w64, the steps for setting up a cross-environment on Linux probably map to Cygwin without much hassle (apart from figuring out the right package equivalents for the apt-get commands, using checkinstall at any point, and omitting Wine):
https://github.com/qyot27/mpv/blob/extra-new/DOCS/crosscompile-mingw-tedious.txt

(despite what the note says, --disable-lto does not cause a build error if you don't kill the GCC build process and try to reconfigure it without cleaning/deleting the temp files first; and --disable-lto is necessary to avoid the binutils 'too many file descriptors' issue that does hit FFmpeg in particular)

I use the apt-cyg package manager, which does the job pretty well thankfully and usually prevents needing to go through the Cygwin installer.

Regarding setting up MinGW-W64 via Cygwin, that was actually was what I had been trying to accomplish the day after I posted this thread. The furthest I got to was running this command:


cd /ffmpeg_sources && git -C x264 pull 2> /dev/null || git clone --depth 1 https://git.videolan.org/git/x264 && cd x264 && PATH="/usr/local/bin:$PATH"
PKG_CONFIG_PATH="/ffmpeg_build/lib/pkgconfig" ./configure --prefix="/ffmpeg_build" --host=x86_64-w64-mingw32 --bindir="/usr/local/bin" --enable-static --enable-pic


Although it does do away with the initial problems involving AVS and gets me a lot further through the make command, the output has hundreds of errors and warnings, and the point at which it fails is this:


hell32 -Wl,--image-base,0x140000000 -m64 -Wl,--high-entropy-va -Wl,--dynamicbase,--nxcompat,--tsaware
libx264.a(win32thread.o):win32thread.c:(.text+0x60): undefined reference to `_beginthreadex'
libx264.a(win32thread.o):win32thread.c:(.text+0x60): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_beginthreadex'
collect2: error: ld returned 1 exit status
make: *** [Makefile:258: x264.exe] Error 1

I also tried several of the possible solutions I found when Googling for the errors, including using --extra-cflags="-mcmodel=medium" and --extra-cflags="-mcmodel=large", but none worked.

qyot27
10th March 2019, 04:00
So is there nothing actually *wrong* per se with Cygwin's implementation? Is it intended behaviour to behave the way it does? I'm wondering how likely it is be able to get a fix implemented via the Mailing List if from their POV there's nothing to fix.
It's hard to say.

Definitely not path issues, when i say ecosystem, I'm referring to the installation paths. I'd rather add some packages to Cygwin or use a Windows cross-compiled binary as I normally would rather than go through the hassle of setting up a standalone MSYS environment just for the purpose of using FFmpeg.
You wouldn't need to. Almost nobody compiles things for MSys (requiring msys1.dll to be on the PATH), they only use MSys as a means to use MinGW-w64, which is why I mentioned that it was largely moot if you were already using MinGW-w64 through Cygwin.

I use the apt-cyg package manager, which does the job pretty well thankfully and usually prevents needing to go through the Cygwin installer.

Regarding setting up MinGW-W64 via Cygwin, that was actually was what I had been trying to accomplish the day after I posted this thread. The furthest I got to was running this command:


cd /ffmpeg_sources && git -C x264 pull 2> /dev/null || git clone --depth 1 https://git.videolan.org/git/x264 && cd x264 && PATH="/usr/local/bin:$PATH"
PKG_CONFIG_PATH="/ffmpeg_build/lib/pkgconfig" ./configure --prefix="/ffmpeg_build" --host=x86_64-w64-mingw32 --bindir="/usr/local/bin" --enable-static --enable-pic


Although it does do away with the initial problems involving AVS and gets me a lot further through the make command, the output has hundreds of errors and warnings, and the point at which it fails is this:


hell32 -Wl,--image-base,0x140000000 -m64 -Wl,--high-entropy-va -Wl,--dynamicbase,--nxcompat,--tsaware
libx264.a(win32thread.o):win32thread.c:(.text+0x60): undefined reference to `_beginthreadex'
libx264.a(win32thread.o):win32thread.c:(.text+0x60): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_beginthreadex'
collect2: error: ld returned 1 exit status
make: *** [Makefile:258: x264.exe] Error 1

I also tried several of the possible solutions I found when Googling for the errors, including using --extra-cflags="-mcmodel=medium" and --extra-cflags="-mcmodel=large", but none worked.
More than likely, Cygwin's build of MinGW-w64/GCC only supports pthreads; you're telling it to build with win32threads. You're also not specifying --cross-prefix, so it's questionable what the compiler thinks it's supposed to do.

Assuming you've installed the mingw64-amd64-gcc-g++ package:

cd x264 && \
mkdir -p x264-build/amd64 && \
../../configure --prefix=$HOME/x264_build --cross-prefix=x86_64-w64-mingw32- --enable-static --enable-strip --disable-win32thread --disable-opencl --host=x86_64-w64-mingw32 && \
make -j$(nproc) && \
make install

Kaos-Industries
11th March 2019, 20:17
More than likely, Cygwin's build of MinGW-w64/GCC only supports pthreads; you're telling it to build with win32threads. You're also not specifying --cross-prefix, so it's questionable what the compiler thinks it's supposed to do.



Interesting, I'd tried using both --disable-win32threads and --disable-thread, and had also come across --host, --build, and --target, but I'd never once come across --cross-prefix. So far this gives me the most complete build I have so far, although there are still problems.


Assuming you've installed the mingw64-amd64-gcc-g++ package:

cd x264 && \
mkdir -p x264-build/amd64 && \
../../configure --prefix=$HOME/x264_build --cross-prefix=x86_64-w64-mingw32- --enable-static --enable-strip --disable-win32thread --disable-opencl --host=x86_64-w64-mingw32 && \
make -j$(nproc) && \
make install


There are no packages with amd64 in the Cygwin package manager - the relevant packages I have are mingw64-x86_64-gcc-core and its required dependencies, which include the headers for it, the runtime and the package mingw64-x86_64-winpthreads, as well as the libgcc1 and libgccpp1 libraries.

When I run your command, I get a successful build of the x264 binary with no errors at all, but when I execute it, I get an error that says:

C:/cygwin64/usr/local/bin/x264.exe: error while loading shared libraries: libwinpthread-1.dll: cannot open shared object file: No such file or directory


However, when I replace --disable-win32thread in configure with --disable-thread, I get a fully working binary. Does disable-thread completely disable multithreading support, and if so, is there a way to make this work with just --disable-win32threads?

Also, as an aside and for my own working knowledge, I noticed that the --open-cl option does not seem to make a difference to whether the program compiles successfully or not - adding --disable-thread but leaving out --disable-opencl compiles a working binary. Is it needed or recommended here?

qyot27
11th March 2019, 21:44
Whoops, my mind tends to substitute 'amd64' into triplets, since i686 or amd64 are how I have my packages named when I cross-compile them on Ubuntu.

I believe the correct package for winpthreads is mingw64-x86_64-winpthreads. I'm not sure why that wouldn't have already been installed and be available for you to use, though.

Whether to enable the OpenCL module is just personal preference. I've never bothered trying to use the feature, and it relies on having hardware that can use OpenCL (most likely, your graphics card - not sure about how well it works with Intel's or AMD's integrated graphics stacks in the processors that come with them).

Kaos-Industries
11th March 2019, 22:06
Whoops, my mind tends to substitute 'amd64' into triplets, since i686 or amd64 are how I have my packages named when I cross-compile them on Ubuntu.

I believe the correct package for winpthreads is mingw64-x86_64-winpthreads. I'm not sure why that wouldn't have already been installed and be available for you to use, though.

It is installed and a required dependency, as mentioned in my post.

I did come across this:

https://github.com/HaxeFoundation/hxcpp/issues/339

...and judging by the last post in it I assume this means there's (still) no way to create a static version of any package with MinGW-64?

If not, then the answer seems to be that I'll just have to add "\usr\x86_64-w64-mingw32\sys-root\mingw\bin" to my PATH, which I wanted to avoid but that doesn't seem possible anymore.

qyot27
11th March 2019, 22:39
It's completely possible to do fully static packages. The build guide I maintain (and linked above) for cross-compiling for Windows from an Ubuntu host goes through the steps to enforce it through the cross-compile environment. The resulting builds don't require any external DLLs aside from ones they immediately require from their dependencies (like libbluray using the DLLs of libaacs and libbdplus rather than statically linking against them), or the basic Windows equivalents that building with MinGW is meant to mimic (msvcrt, etc.).

So you could sidestep the issue by building your own MinGW-w64/GCC cross-compile environment under Cygwin, and use that instead of the package(s) for them that Cygwin provides. But if you do that, you can't link to any of the MinGW-based dependencies provided by Cygwin (zlib, freetype, libass, or so on), because doing so will cause any program they're linked into to require the same .dlls they do. The only way to prevent that is to build all of it yourself all the way up the chain to avoid contaminating the end-product binaries of x264, FFmpeg, or whatever with needing libgcc-1.dll or libwinpthread-1.dll.

If that's too daunting and you're fine mixing the results of two GCC environments, an alternate solution to adding that directory to the PATH is to use LinkShellExtension, and simply create symbolic links of libwinpthread-1.dll and libgcc-1.dll in a location that's already on the PATH.

Kaos-Industries
11th March 2019, 23:59
It's completely possible to do fully static packages. The build guide I maintain (and linked above) for cross-compiling for Windows from an Ubuntu host goes through the steps to enforce it through the cross-compile environment. The resulting builds don't require any external DLLs aside from ones they immediately require from their dependencies (like libbluray using the DLLs of libaacs and libbdplus rather than statically linking against them), or the basic Windows equivalents that building with MinGW is meant to mimic (msvcrt, etc.).

So you could sidestep the issue by building your own MinGW-w64/GCC cross-compile environment under Cygwin, and use that instead of the package(s) for them that Cygwin provides. But if you do that, you can't link to any of the MinGW-based dependencies provided by Cygwin (zlib, freetype, libass, or so on), because doing so will cause any program they're linked into to require the same .dlls they do. The only way to prevent that is to build all of it yourself all the way up the chain to avoid contaminating the end-product binaries of x264, FFmpeg, or whatever with needing libgcc-1.dll or libwinpthread-1.dll.

If that's too daunting and you're fine mixing the results of two GCC environments, an alternate solution to adding that directory to the PATH is to use LinkShellExtension, and simply create symbolic links of libwinpthread-1.dll and libgcc-1.dll in a location that's already on the PATH.

What if I did add it to the PATH for this current package? Would I still be able to compile an "end-product binary" of FFmpeg that was static? Or is there pretty much no way with my current Cygwin/MinGW setup (i.e. without compiling all the dependencies from source) to compile binaries that don't rely on those DLLs?

qyot27
12th March 2019, 01:36
Keeping in mind that I don't mess with the normal/shared GCC builds, and therefore am just taking a stab in the dark, you *might* be able to do it if you pass -static to LDFLAGS/--extra-ldflags. The packages do seem to have the relevant static libgcc.a and libwinpthread.a installed to the right /lib directories.

Kaos-Industries
12th March 2019, 02:47
Keeping in mind that I don't mess with the normal/shared GCC builds, and therefore am just taking a stab in the dark, you *might* be able to do it if you pass -static to LDFLAGS/--extra-ldflags. The packages do seem to have the relevant static libgcc.a and libwinpthread.a installed to the right /lib directories.


Success! I managed to get a fully static and working binary of x264, and without adding anything to the PATH or passing extra flags to the linker. It turns out --disable-win32thread was getting in my way, and simply removing it works. This essentially means that the only thing I was missing was --cross-prefix, which I wasn't even aware I needed as I'd never come across it in my exhaustive searching despite how crucial it evidently seems to be for cross-compiling.

Kaos-Industries
12th March 2019, 03:05
Actually, now that I think about it, I remembered something I came across during my research for all this:

If you’ve come across --enable-win32thread, you’ll know the name is sweet but don’t ever use it!! (Not that you care.) You’ll lose multi-threading capability since we are not cross-compiling for windows; we are compiling for Cygwin.

(From https://koohiimaster.wordpress.com/2014/12/02/compiling-ffmpeg-with-libx264-and-libfdk_aac-under-cygwin-without-mingw32/)

I wonder if that applies here and the x264 binary I've built is crippled to work in single-threaded mode. Is there any way to determine whether a binary comes with multithreading support? If not, would anyone happen to have a sample AVS file I can easily use with x264 to test that it has multithreading support?

qyot27
12th March 2019, 03:24
No, you were cross-compiling if you were using mingw. Cygwin doesn't support the win32threads threading mode, and so trying to enable that when doing a native Cygwin build will fail and disable threading. If you're building for MinGW-w64, win32threads is supported.

Kaos-Industries
12th March 2019, 03:42
No, you were cross-compiling if you were using mingw. Cygwin doesn't support the win32threads threading mode, and so trying to enable that when doing a native Cygwin build will fail and disable threading. If you're building for MinGW-w64, win32threads is supported.

Perfect, so I suppose I have my solution? Thanks a lot for your help throughout this thread, it's been really appreciated. Time to get to work compiling everything else I need and then FFmpeg itself, here's to hoping it'll go a lot more smoothly.

nevcairiel
12th March 2019, 12:11
I would even go as far as saying that win32threads is what I would even recommend if you're building for windows/mingw, since pthreads for windows is also just a wrapper around windows-threads, so using windows-threads directly should be beneficial.

Groucho2004
12th March 2019, 12:20
I would even go as far as saying that win32threads is what I would even recommend if you're building for windows/mingw, since pthreads for windows is also just a wrapper around windows-threads, so using windows-threads directly should be beneficial.Exactly. I've been using win32threads in my own x264 builds for years. It's even slightly faster than pthreads.

masterkivat
13th March 2019, 02:04
Exactly. I've been using win32threads in my own x264 builds for years. It's even slightly faster than pthreads.

Hey Groucho2004, do you have plans to provide your x264 builds for "mere mortals" (like me :D) in the future? Would be interesting compare to other providers like LigH, jpsdr and the vanilla ones.

Groucho2004
13th March 2019, 10:42
Hey Groucho2004, do you have plans to provide your x264 builds for "mere mortals" (like me :D) in the future? Would be interesting compare to other providers like LigH, jpsdr and the vanilla ones.My builds are very barebone, no swscale, gpac, ffms, lsmash, etc. I only enable avs support. Apart from that, I think there are enough options around from which to pick.

Kaos-Industries
16th March 2019, 02:51
No, you were cross-compiling if you were using mingw. Cygwin doesn't support the win32threads threading mode, and so trying to enable that when doing a native Cygwin build will fail and disable threading. If you're building for MinGW-w64, win32threads is supported.

Hey there, me again. I managed to compile the rest of the packages pretty smoothly, surprisingly enough, but I'm now stuck at the final stage of compiling FFmpeg itself. I'm sorry to bother you with this again, but the officially-recommended avenue by the failed output of the compiler is the FFmpeg mailing list, and it was abrasive and unpleasant, so it looks like I'm stuck coming back to this forum.

After having successfully compiled the binaries and libraries for x264, x265, fdk_aac, libopus and AV1 (aom), and then running the following command to compile the all-important FFmpeg:

cd /ffmpeg_sources &&
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 &&
tar xjvf ffmpeg-snapshot.tar.bz2 &&
cd ffmpeg && PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" &&
./configure --arch=x86_64 --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32 \
--enable-cross-compile \
--extra-cflags="-I/usr/local/include" \
--extra-ldflags="-L/usr/local/lib" \
--prefix="/usr/local" \
--pkg-config-flags="--static" \
--extra-libs="-lpthread -lm" \
--enable-libaom \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libopus \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-libx265 \
--enable-gpl \
--enable-nonfree 2>&1 | tee "/ffmpeg_compile.txt" &&
make -j$(nproc) 2>&1 | tee -a "/ffmpeg_compile.txt" &&
make install 2>&1 | tee -a "/ffmpeg_compile.txt"

...I get the following output:

ERROR: aom >= 1.0.0 not found using pkg-config

If you think configure made a mistake, make sure you are using the latest
version from Git. If the latest version fails, report the problem to the
ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "ffbuild/config.log" produced by configure as this will help
solve the problem.
Makefile:160: /tests/Makefile: No such file or directory
make: *** No rule to make target '/tests/Makefile'. Stop.
Makefile:160: /tests/Makefile: No such file or directory
make: *** No rule to make target '/tests/Makefile'. Stop.

libaom has definitely been compiled, and its binaries, libraries and pkg-config files are in the relevant folders. When I skip the libaom package, I get the same error for libass, which was installed via Cygwin's package manager. Could this error possibly be caused by how each package was compiled? Not all of the packages that I compiled from source were compiled with the mingw64 compiler - if they didn't cause any problems, I tended to compile with Cygwin's own GCC. In retrospect, it occurred to me that this may have been what you meant earlier when you said:

So you could sidestep the issue by building your own MinGW-w64/GCC cross-compile environment under Cygwin, and use that instead of the package(s) for them that Cygwin provides. But if you do that, you can't link to any of the MinGW-based dependencies provided by Cygwin (zlib, freetype, libass, or so on), because doing so will cause any program they're linked into to require the same .dlls they do. The only way to prevent that is to build all of it yourself all the way up the chain to avoid contaminating the end-product binaries of x264, FFmpeg, or whatever with needing libgcc-1.dll or libwinpthread-1.dll.

It makes sense after the fact, but it didn't occur to me that when cross-compiling all dependencies must themselves be compiled with the same toolchain. Although libaom itself was one of the packages compiled with MinGW-w64, which is confusing. Then again, I suppose that rule applies to *all* dependencies used by the compiler process, such as those I installed from Cygwin's package repository.

Am I correct in thinking, then, that in order to get a successful MinGW-w64 cross-compilation under Cygwin I will need to either build every dependency it relies on from source specifically with the MinGW-w64 toolchain, or have it rely only on MinGW-w64 variants in Cygwin's package repository? These are the dependencies in question:

apt-cyg install \
autoconf \
automake \
binutils \
bc \ (?)
cmake \
cygport \
doxygen \
mingw64-x86_64-gcc-g++ \
gcc-core \
gcc_g++ \
git \
hg \
libass-devel \
libfreetype-devel \
libmp3lame-devel \
libogg-devel \
libopus-devel \
libSDL2-devel \
libtheora-devel \
libtool \
libvorbis-devel \
libvpx-devel \
make \
mingw64-x86_64-binutils \
mingw64-x86_64-gcc-core \
mingw64-x86_64-headers \
mingw64-x86_64-runtime \
mingw64-x86_64-winpthreads \
mingw64-x86_64-windows-default-manifest \
nasm \
pkg-config \
texinfo \
wget \
yasm


Or is it perhaps just the libraries that I need to find MinGW-64 variants for?

Or am I entirely jumping the gun here and could this error be entirely unrelated? I also have the config.log if that would help you.

Thank you once again.

qyot27
16th March 2019, 03:58
Well,

The --target-os should be just a plain 'mingw32'.

--enable-cross-compile probably shouldn't be used here; I'm not really sure what the use case for it actually is, but I've never had to use it while doing cross-compiles with MinGW-w64.

PKG_CONFIG_PATH in the command above is separated from configure with && rather than being passed to ./configure as a local environment variable; while this may be innocuous (having it as a separate command should have the effect of simply forcing it for the entire environment, until you exit the Cygwin shell), it's generally better practice to make sure that stuff like that is attached to the command it's meant to be paired with.

Kaos-Industries
16th March 2019, 20:16
Well,

The --target-os should be just a plain 'mingw32'.

--enable-cross-compile probably shouldn't be used here; I'm not really sure what the use case for it actually is, but I've never had to use it while doing cross-compiles with MinGW-w64.

PKG_CONFIG_PATH in the command above is separated from configure with && rather than being passed to ./configure as a local environment variable; while this may be innocuous (having it as a separate command should have the effect of simply forcing it for the entire environment, until you exit the Cygwin shell), it's generally better practice to make sure that stuff like that is attached to the command it's meant to be paired with.

My bad, the inclusion of the longer target OS value was a mistake that I was experimenting with, I can confirm that the output above was from using mingw32 as a target OS, I'll edit that now.

I'll try removing the --enable--cross-compile flag and putting PKG CONFIG in the right place and then report back. Do you not think the error is a result of using non-minGW-64 depednencies then?

qyot27
16th March 2019, 22:25
Without knowing the exact errors, I'd just be guessing. Considering that the libraries were built with at least three different build systems (handwritten for x264, autotools for several, CMake for x265), it could also have been in how some of those were configured as well. First-hand, cross-compiling with CMake is weird because of the need for a toolchain file - and if you used one of the build scripts that the x265 project provides, then you're up to the whims of said script. I was mostly going on how most chained dependencies act under normal circumstances; but it wouldn't surprise me if it actually is impossible to mix native-Cygwin and MinGW-w64 libraries, rather than simply causing the build to require extra .dlls. In which case, yeah, you'd have to choose to build the entire dependency chain¹ with either MinGW-w64 or Cygwin, not some with one and some with the other.

¹said dependency chain is the libraries themselves, not the build system components; in the list you gave, it would mean just the -devel packages that would need to be built with MinGW-w64. In that list, the only significantly problematic one is libass, because freetype2 and fontconfig both have a potential litany of their own dependencies to handle too (and I would recommend using fontconfig rather than libass' native ability to use Windows' DirectWrite functionality, especially if you either have lots of system fonts, and/or plan to use the FFmpeg libs to build a media player like mpv).

Due to how FFmpeg's configuration script works, the part of ffbuild/config.log that would be relevant to help troubleshoot is the very last portion, it should be clear where it executed the command that made configure fail.

Kaos-Industries
18th March 2019, 01:52
Without knowing the exact errors, I'd just be guessing. Considering that the libraries were built with at least three different build systems (handwritten for x264, autotools for several, CMake for x265), it could also have been in how some of those were configured as well. First-hand, cross-compiling with CMake is weird because of the need for a toolchain file - and if you used one of the build scripts that the x265 project provides, then you're up to the whims of said script. I was mostly going on how most chained dependencies act under normal circumstances; but it wouldn't surprise me if it actually is impossible to mix native-Cygwin and MinGW-w64 libraries, rather than simply causing the build to require extra .dlls. In which case, yeah, you'd have to choose to build the entire dependency chain¹ with either MinGW-w64 or Cygwin, not some with one and some with the other.

¹said dependency chain is the libraries themselves, not the build system components; in the list you gave, it would mean just the -devel packages that would need to be built with MinGW-w64. In that list, the only significantly problematic one is libass, because freetype2 and fontconfig both have a potential litany of their own dependencies to handle too (and I would recommend using fontconfig rather than libass' native ability to use Windows' DirectWrite functionality, especially if you either have lots of system fonts, and/or plan to use the FFmpeg libs to build a media player like mpv).

Due to how FFmpeg's configuration script works, the part of ffbuild/config.log that would be relevant to help troubleshoot is the very last portion, it should be clear where it executed the command that made configure fail.

Here are the last six "blocks" of the config.log. They don't mean anything to me, but maybe you can decode them. Let me know if you need more.

^
x86_64-w64-mingw32-gcc -L/usr/local/lib -Wl,--nxcompat,--dynamicbase -Wl,--high-entropy-va -Wl,--as-needed -Wl,--image-base,0x140000000 -o /tmp/ffconf.s2SqLWqy/test.exe /tmp/ffconf.s2SqLWqy/test.o -lm -lpthread -lm
check_mathfunc sinf 1 -lm
test_ld cc -lm
test_cc
BEGIN /tmp/ffconf.s2SqLWqy/test.c
1 #include <math.h>
2 float foo(float f, float g) { return sinf(f); }
3 int main(void){ return (int) foo; }
END /tmp/ffconf.s2SqLWqy/test.c
x86_64-w64-mingw32-gcc -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1 -D__printf__=__gnu_printf__ -D_WIN32_WINNT=0x0600 -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DPIC -I/usr/local/include -std=c11 -fomit-frame-pointer -c -o /tmp/ffconf.s2SqLWqy/test.o /tmp/ffconf.s2SqLWqy/test.c
/tmp/ffconf.s2SqLWqy/test.c: In function 'main':
/tmp/ffconf.s2SqLWqy/test.c:3:24: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
int main(void){ return (int) foo; }
^
x86_64-w64-mingw32-gcc -L/usr/local/lib -Wl,--nxcompat,--dynamicbase -Wl,--high-entropy-va -Wl,--as-needed -Wl,--image-base,0x140000000 -o /tmp/ffconf.s2SqLWqy/test.exe /tmp/ffconf.s2SqLWqy/test.o -lm -lpthread -lm
check_mathfunc trunc 1 -lm
test_ld cc -lm
test_cc
BEGIN /tmp/ffconf.s2SqLWqy/test.c
1 #include <math.h>
2 float foo(float f, float g) { return trunc(f); }
3 int main(void){ return (int) foo; }
END /tmp/ffconf.s2SqLWqy/test.c
x86_64-w64-mingw32-gcc -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1 -D__printf__=__gnu_printf__ -D_WIN32_WINNT=0x0600 -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DPIC -I/usr/local/include -std=c11 -fomit-frame-pointer -c -o /tmp/ffconf.s2SqLWqy/test.o /tmp/ffconf.s2SqLWqy/test.c
/tmp/ffconf.s2SqLWqy/test.c: In function 'main':
/tmp/ffconf.s2SqLWqy/test.c:3:24: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
int main(void){ return (int) foo; }
^
x86_64-w64-mingw32-gcc -L/usr/local/lib -Wl,--nxcompat,--dynamicbase -Wl,--high-entropy-va -Wl,--as-needed -Wl,--image-base,0x140000000 -o /tmp/ffconf.s2SqLWqy/test.exe /tmp/ffconf.s2SqLWqy/test.o -lm -lpthread -lm
check_mathfunc truncf 1 -lm
test_ld cc -lm
test_cc
BEGIN /tmp/ffconf.s2SqLWqy/test.c
1 #include <math.h>
2 float foo(float f, float g) { return truncf(f); }
3 int main(void){ return (int) foo; }
END /tmp/ffconf.s2SqLWqy/test.c
x86_64-w64-mingw32-gcc -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1 -D__printf__=__gnu_printf__ -D_WIN32_WINNT=0x0600 -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DPIC -I/usr/local/include -std=c11 -fomit-frame-pointer -c -o /tmp/ffconf.s2SqLWqy/test.o /tmp/ffconf.s2SqLWqy/test.c
/tmp/ffconf.s2SqLWqy/test.c: In function 'main':
/tmp/ffconf.s2SqLWqy/test.c:3:24: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
int main(void){ return (int) foo; }
^
x86_64-w64-mingw32-gcc -L/usr/local/lib -Wl,--nxcompat,--dynamicbase -Wl,--high-entropy-va -Wl,--as-needed -Wl,--image-base,0x140000000 -o /tmp/ffconf.s2SqLWqy/test.exe /tmp/ffconf.s2SqLWqy/test.o -lm -lpthread -lm
check_complexfunc cabs 1
test_ld cc
test_cc
BEGIN /tmp/ffconf.s2SqLWqy/test.c
1 #include <complex.h>
2 #include <math.h>
3 float foo(complex float f, complex float g) { return cabs(f * I); }
4 int main(void){ return (int) foo; }
END /tmp/ffconf.s2SqLWqy/test.c
x86_64-w64-mingw32-gcc -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1 -D__printf__=__gnu_printf__ -D_WIN32_WINNT=0x0600 -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DPIC -I/usr/local/include -std=c11 -fomit-frame-pointer -c -o /tmp/ffconf.s2SqLWqy/test.o /tmp/ffconf.s2SqLWqy/test.c
/tmp/ffconf.s2SqLWqy/test.c: In function 'main':
/tmp/ffconf.s2SqLWqy/test.c:4:24: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
int main(void){ return (int) foo; }
^
x86_64-w64-mingw32-gcc -L/usr/local/lib -Wl,--nxcompat,--dynamicbase -Wl,--high-entropy-va -Wl,--as-needed -Wl,--image-base,0x140000000 -o /tmp/ffconf.s2SqLWqy/test.exe /tmp/ffconf.s2SqLWqy/test.o -lpthread -lm
check_complexfunc cexp 1
test_ld cc
test_cc
BEGIN /tmp/ffconf.s2SqLWqy/test.c
1 #include <complex.h>
2 #include <math.h>
3 float foo(complex float f, complex float g) { return cexp(f * I); }
4 int main(void){ return (int) foo; }
END /tmp/ffconf.s2SqLWqy/test.c
x86_64-w64-mingw32-gcc -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1 -D__printf__=__gnu_printf__ -D_WIN32_WINNT=0x0600 -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DPIC -I/usr/local/include -std=c11 -fomit-frame-pointer -c -o /tmp/ffconf.s2SqLWqy/test.o /tmp/ffconf.s2SqLWqy/test.c
/tmp/ffconf.s2SqLWqy/test.c: In function 'main':
/tmp/ffconf.s2SqLWqy/test.c:4:24: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
int main(void){ return (int) foo; }
^
x86_64-w64-mingw32-gcc -L/usr/local/lib -Wl,--nxcompat,--dynamicbase -Wl,--high-entropy-va -Wl,--as-needed -Wl,--image-base,0x140000000 -o /tmp/ffconf.s2SqLWqy/test.exe /tmp/ffconf.s2SqLWqy/test.o -lpthread -lm
require_pkg_config libaom aom >= 1.0.0 aom/aom_codec.h aom_codec_version
check_pkg_config libaom aom >= 1.0.0 aom/aom_codec.h aom_codec_version
test_pkg_config libaom aom >= 1.0.0 aom/aom_codec.h aom_codec_version
false --exists --print-errors aom >= 1.0.0
ERROR: aom >= 1.0.0 not found using pkg-config


In the meantime, I'll see how far I get trying to re-build the libraries with MinGW-W64 and looking up the MinGW-w64 variants for the rest.

Kaos-Industries
18th March 2019, 06:52
I would even go as far as saying that win32threads is what I would even recommend if you're building for windows/mingw, since pthreads for windows is also just a wrapper around windows-threads, so using windows-threads directly should be beneficial.

Exactly. I've been using win32threads in my own x264 builds for years. It's even slightly faster than pthreads.

Thanks for your responses.

How would I build FFmpeg with win32threads? Is it as simple as making sure the compiled FFmpeg is enabled with it, or do all of the dependencies also somehow need the option enabled (although so far I haven't seen anything to indicate they're disabled by default)?

nevcairiel
18th March 2019, 10:07
If you are building FFmpeg with a cross-prefix, you need to ensure that either a prefixed pkg-config also exists (which is not typically the case for mingw), or you need to also pass --pkg-config=pkg-config to tell it which pkg-config to use.
It appears the error you are seeing comes from pkg-config not being found, which would be remedied passing the above option.

For win32threads, I would personally recommend to build as many dependencies with it as possible - however, for AOM thats really hard, so I wold skip that, and just do x264/x265 and ffmpeg itself. Its not really required to have dependencies use the same threading model, and they could use pthreads.

Kaos-Industries
18th March 2019, 17:49
If you are building FFmpeg with a cross-prefix, you need to ensure that either a prefixed pkg-config also exists (which is not typically the case for mingw), or you need to also pass --pkg-config=pkg-config to tell it which pkg-config to use.
It appears the error you are seeing comes from pkg-config not being found, which would be remedied passing the above option.

Thank you, I'll try this.



For win32threads, I would personally recommend to build as many dependencies with it as possible - however, for AOM thats really hard, so I wold skip that, and just do x264/x265 and ffmpeg itself. Its not really required to have dependencies use the same threading model, and they could use pthreads.

How would I do this? The only relevant options in x264's configure script are --disable-win32thread and --disable-thread, the latter of which's description is: disable multithreaded encoding, which to me sounds like it disables both pthreads and win32threads.

x265 has to be configured with CMake, so I'm not even sure how to go about finding what option I need to pass to it in order to enable win32thread. cmake --help returns nothing relevant.

nevcairiel
18th March 2019, 18:40
How would I do this? The only relevant options in x264's configure script are --disable-win32thread and --disable-thread, the latter of which's description is: disable multithreaded encoding, which to me sounds like it disables both pthreads and win32threads.

As far as I can tell, building without --disable-win32thread should be enough to use it.

For x265, I'm not sure, I haven't build that for a while.

Kaos-Industries
23rd March 2019, 00:00
To update where I am with this, I'm still getting the same error while building FFmpeg, even after compiling or sourcing only MinGW-w64 dependencies, although I have made some progress on the cause:

https://stackoverflow.com/questions/55307988/pkg-config-path-cant-be-seen-by-configure

Hopefully someone here can figure out what's going wrong here that I can't see and put me out of my misery.

Kaos-Industries
25th March 2019, 20:17
Without knowing the exact errors, I'd just be guessing. Considering that the libraries were built with at least three different build systems (handwritten for x264, autotools for several, CMake for x265), it could also have been in how some of those were configured as well. First-hand, cross-compiling with CMake is weird because of the need for a toolchain file - and if you used one of the build scripts that the x265 project provides, then you're up to the whims of said script. I was mostly going on how most chained dependencies act under normal circumstances; but it wouldn't surprise me if it actually is impossible to mix native-Cygwin and MinGW-w64 libraries, rather than simply causing the build to require extra .dlls. In which case, yeah, you'd have to choose to build the entire dependency chain¹ with either MinGW-w64 or Cygwin, not some with one and some with the other.

¹said dependency chain is the libraries themselves, not the build system components; in the list you gave, it would mean just the -devel packages that would need to be built with MinGW-w64. In that list, the only significantly problematic one is libass, because freetype2 and fontconfig both have a potential litany of their own dependencies to handle too (and I would recommend using fontconfig rather than libass' native ability to use Windows' DirectWrite functionality, especially if you either have lots of system fonts, and/or plan to use the FFmpeg libs to build a media player like mpv).

Due to how FFmpeg's configuration script works, the part of ffbuild/config.log that would be relevant to help troubleshoot is the very last portion, it should be clear where it executed the command that made configure fail.

Okay, so after a lot of testing and digging into directories, I've managed to figure out that the cause is that while pkg-config/configure is able to see all the packages that I compiled from source (located in /usr/bin/local/lib/pkgconfig), it isn't able to see the rest that I installed via Cygwin's package manager - which are located in /usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig.

So naturally it seemed that all I needed to do was add the latter path to PKG_CONFIG_LIBDIR (which I'm using in place of PKG_CONFIG_PATH because it doesn't include /usr/bin by default and therefore avoids potential conflicts between Cygwin and MinGW-w64 packages).

However, this still doesn't work to compile any of the packages in the mingw prefix folder,

This is the most working version of the command I currently have:

cd /ffmpeg_sources && rm -fr ffmpeg &&
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 &&
tar xjvf ffmpeg-snapshot.tar.bz2 1> /dev/null && rm -f ffmpeg-snapshot.tar.bz2 && cd ffmpeg &&
export PKG_CONFIG_LIBDIR="/usr/local/lib/pkgconfig:/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig" &&
./configure --arch=x86_64 --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32 \
--extra-cflags="-static -I/usr/local/include -I/usr/x86_64-w64-mingw32/sys-root/mingw/include" \
--extra-ldflags="-static -L/usr/local/lib -L/usr/x86_64-w64-mingw32/sys-root/mingw/lib" \
--extra-libs="-pthread -lm" \
--prefix="/usr/local" \
--pkg-config="pkg-config" \
--pkg-config-flags="--static" \
--enable-libaom \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libopus \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-libx265 \
--enable-gpl \
--enable-nonfree \
--enable-static \
--disable-shared &&
make -j$(nproc) &&
make install

Adding --sysinclude="/usr/x86_64-w64-mingw32/sys-root/mingw/lib" on its own makes no difference ot it, and adding --sysroot="/usr/x86_64-w64-mingw32/sys-root/mingw" seems to take everything into a completely different direction - instead of the usual pkg-config errors, I get an error that says:

x86_64-w64-mingw32-gcc is unable to create an executable file.

C compiler test failed.

I've made so much progress with this that I feel like I'm way too close to call it quits at this point, so any suggestions as to why pkg-config still refuses to see the packages in the sys-root folder would be appreciated.

Kaos-Industries
2nd April 2019, 18:14
An update on this: I finally managed to determine that the problem I was running into wasn't what I thought it was at all - that the packages installed through Cygwin's setup/package manager were unable to be seen by pkg-config or PKG_CONFIG_PATH while those I'd built from source could be seen fine. It turns out the only packages that were actually failing to build were three in particular - libvorbis, libass, and libfreetype. I realised this when I started removing --enable-package options and noticed that many of those installed from the Cygwin setup were working fine. I can only assume that the Cygwin version of these particular packages are broken in some way. The plan is now to build these three packages from source, and see whether that solves my issues.

qyot27
2nd April 2019, 22:11
Running into that was largely why I hadn't responded. The errors being emitted for libass indicated that it wasn't finding the other libraries* libass links against, even though several of them (in their mingw64- variants, of course) were installed. libvorbis only depends on libogg, IIRC. Freetype2 is part of the libass dependency chain, so all the things it needs would be covered by getting all the things libass needs.

*libass missing dependencies:
harfbuzz
glib-2.0
pcre
fontconfig
expat
freetype
png16

Some of those have questionable levels of necessity (harfbuzz, for example, is really only needed if you need to have the ability to render RTL-formatted subtitles, but the downside is that harfbuzz is also what calls in glib2, which I can tell you right now is a nightmare and something I avoided in my build guide because it's so easy to get stuck on; pcre is only needed by either harfbuzz or glib2). The proper order for the libass dependencies are libpng² (which might require zlib¹, so be prepared for that), then from the "Subtitle rendering" section of the guide³, iconv->enca->freetype2->c2man->fribidi->expat->json-c->fontconfig->uchardet->lua (likewise, json-c and uchardet might not actually be necessary for libass, its dependencies, or FFmpeg, but they're there for mpv's sake; lua is definitely just for mpv). c2man is something fribidi needs, and I think that's why I didn't bother with harfbuzz, since it and fribidi have some overlap (IIRC).

Also, libass doesn't have to use fontconfig; it can use Windows' own DirectWrite API, which could mean not having to compile a lot of those dependencies (although at this point I'm not sure which ones). The reason I don't recommend building libass to use DirectWrite is that if you have large (talking several hundred to over a thousand) numbers of fonts installed, you'll have a constant performance hit whenever invoking libass; with fontconfig, so long as you aren't constantly installing fonts, the only hiccup will be the first time it's called, since it has to cache the font list, but fontconfig's cache list is persistent, DirectWrite's is not.

¹https://github.com/qyot27/mpv/blob/extra-new/DOCS/crosscompile-mingw-tedious.txt#L391
²https://github.com/qyot27/mpv/blob/extra-new/DOCS/crosscompile-mingw-tedious.txt#L772
³https://github.com/qyot27/mpv/blob/extra-new/DOCS/crosscompile-mingw-tedious.txt#L1058

Kaos-Industries
3rd April 2019, 04:21
Running into that was largely why I hadn't responded. The errors being emitted for libass indicated that it wasn't finding the other libraries* libass links against, even though several of them (in their mingw64- variants, of course) were installed. libvorbis only depends on libogg, IIRC. Freetype2 is part of the libass dependency chain, so all the things it needs would be covered by getting all the things libass needs.

*libass missing dependencies:
harfbuzz
glib-2.0
pcre
fontconfig
expat
freetype
png16

Some of those have questionable levels of necessity (harfbuzz, for example, is really only needed if you need to have the ability to render RTL-formatted subtitles, but the downside is that harfbuzz is also what calls in glib2, which I can tell you right now is a nightmare and something I avoided in my build guide because it's so easy to get stuck on; pcre is only needed by either harfbuzz or glib2). The proper order for the libass dependencies are libpng² (which might require zlib¹, so be prepared for that), then from the "Subtitle rendering" section of the guide³, iconv->enca->freetype2->c2man->fribidi->expat->json-c->fontconfig->uchardet->lua (likewise, json-c and uchardet might not actually be necessary for libass, its dependencies, or FFmpeg, but they're there for mpv's sake; lua is definitely just for mpv). c2man is something fribidi needs, and I think that's why I didn't bother with harfbuzz, since it and fribidi have some overlap (IIRC).

Also, libass doesn't have to use fontconfig; it can use Windows' own DirectWrite API, which could mean not having to compile a lot of those dependencies (although at this point I'm not sure which ones). The reason I don't recommend building libass to use DirectWrite is that if you have large (talking several hundred to over a thousand) numbers of fonts installed, you'll have a constant performance hit whenever invoking libass; with fontconfig, so long as you aren't constantly installing fonts, the only hiccup will be the first time it's called, since it has to cache the font list, but fontconfig's cache list is persistent, DirectWrite's is not.

¹https://github.com/qyot27/mpv/blob/extra-new/DOCS/crosscompile-mingw-tedious.txt#L391
²https://github.com/qyot27/mpv/blob/extra-new/DOCS/crosscompile-mingw-tedious.txt#L772
³https://github.com/qyot27/mpv/blob/extra-new/DOCS/crosscompile-mingw-tedious.txt#L1058

Yeah, I came across the glib2 problem a lot while researching this stuff, that and harfbuzz and libass being in some weird dependency loop, so I'd definitely like to avoid the ones I don't need where I can.

So if I'm understanding you correctly, are you saying that I would need to cross-compile each package in those dependency chains from source?

And that those chains would be, in left-to-right order of compilation/install:

libogg > libvorbis

zlib (possibly) > libpng > iconv > enca > freetype2 > c2man > fribidi > expat > fontconfig > json-c (possibly) > uchardet (possibly) > libass

Correct me if I've misunderstood any of the above.

As for fontconfig, I don't have much use for it myself as I've never really seen a need to use FFmpeg's subtitle-generation feature, but part of my being so invested in this project at this point is that I've decided I'll be writing up a guide on how to accomplish this with Cygwin for anyone that comes after (seems a waste not to with the time I've spent on it), and I'm currently weighing up whether the extra packages are worth including that feature for others. Including libass without fontconfig might be a good compromise between making a more complete guide for others and making life easier on myself, but I suppose it ultimately depends on just how much more packages I'll need to compile from source for fontconfig vs libass. How would I find out exactly which dependencies fontconfig needs?