Project

General

Profile

Feature #5130

Facilitate cross-compiling from sources (ARM) with configure

Added by virtual dj over 2 years ago. Updated over 1 year ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
non-x86
Target version:
-
Start date:
2018-06-16
Due date:
% Done:

0%

Estimated time:

Description

I'm trying to cross-compile TVHeadend from the source code on GitHub to make it work in a QNAP NAS using an ARM processor (soft-float). Normally I use an ARM QEMU VM with Debiam but is very very slow and takes more than 2 hours to build TVHeadend with ffmpeg, so I'm trying to experiment with cross-compiling.

I'm using the gcc-arm-linux-gnueabi package of Debian 9.3 and first I've compiled using gcc-arm-linux-gnueabi the required dependencies from sources into /root/tvheadend/out-armel prefix:
  • libdvbcsa
  • zlib
  • openssl
  • pcre2
  • uriparser

Than I configure TVHeadend with the following command line, basically disabling ffmpeg, hdhomerun, x264, x265, etc.:

[email protected]:~/tvheadend/tvheadend# PKG_CONFIG_PATH=/root/tvheadend/out-armel/lib/pkgconfig ./configure --prefix=/root/tvheadend/out-armel --cc=arm-linux-gnueabi-gcc --cflags='-msoft-float -I/root/tvheadend/out-armel/include -L/root/tvheadend/out-armel/lib' --ldflags='-msoft-float -Wl,-rpath,./,-rpath,../lib' \
--arch=armel --host=arm-linux-gnueabi \
--disable-avahi --enable-bundle --disable-dbus_1 \
--disable-hdhomerun_client --disable-hdhomerun_static \
--disable-libav --disable-ffmpeg --disable-ffmpeg_static \
--disable-libx264 --disable-libx264_static --disable-libx265 --disable-libx265_static \
--disable-libvpx --disable-libvpx_static --disable-libtheora --disable-libtheora_static \
--disable-libvorbis --disable-libvorbis_static --disable-libopus --disable-libopus_static \
--disable-libfdkaac --disable-libfdkaac_static
Checking support/features
  checking for cc execinfo.h ...                    ok
  checking for cc -mmmx ...                         fail
  checking for cc -msse2 ...                        fail
  checking for cc -Wunused-result ...               ok
  checking for cc getloadavg ...                    ok
  checking for cc atomic32 ...                      ok
  checking for cc atomic64 ...                      ok
  checking for cc atomic_time_t ...                 ok
  checking for cc atomic_ptr ...                    ok
  checking for cc bitops64 ...                      ok
  checking for cc lockowner ...                     ok
  checking for cc qsort_r ...                       ok
  checking for cc stime ...                         ok
  checking for cc gmtoff ...                        ok
  checking for cc recvmmsg ...                      ok
  checking for cc sendmmsg ...                      ok
  checking for cc libiconv ...                      fail
    ^ using build-in glibc iconv routines
  checking for cc ifnames ...                       ok
  checking for cc cclang_threadsan ...              fail
  checking for py module gzip ...                   ok
  checking for pkg-config ...                       ok
  checking for xgettext ...                         ok
  checking for msgmerge ...                         ok
  checking for gzip ...                             ok
  checking for bzip2 ...                            ok
  checking for pkg openssl  ...                     ok (detected 1.1.0h)
  checking for cc linux/dvb/version.h ...           ok
  checking for pkg zlib  ...                        ok (detected 1.2.11)
  checking for pkg libpcre2-8  ...                  ok (detected 10.31)
  checking for pkg liburiparser  ...                ok (detected 0.8.5)
  checking for cc sys/inotify.h ...                 ok
  checking for cc inotify_init1 ...                 ok
  checking for cc dvbcsa/dvbcsa.h ...               ok
  checking for cc -ldvbcsa ...                      ok
  fetching dvb-scan files ...                       ok
  checking for cc epoll_create1 ...                 ok

Compiler:
  Using C compiler:                        arm-linux-gnueabi-gcc
  Using C flags:                           -msoft-float -I/root/tvheadend/out-armel/include -L/root/tvheadend/out-armel/lib
  Using LD flags:                          -msoft-float -Wl,-rpath,./,-rpath,../lib -ldvbcsa
  Build for arch:                          armel

Binaries:
  Using PYTHON:                            python
  Using GZIP:                              gzip
  Using BZIP2:                             bzip2

Options:
  pie                                      yes
  ccdebug                                  no
  cardclient                               yes
  cwc                                      yes
  cccam                                    yes
  capmt                                    yes
  constcw                                  yes
  linuxdvb                                 yes
  satip_server                             yes
  satip_client                             yes
  hdhomerun_client                         no
  hdhomerun_static                         no
  iptv                                     yes
  tsfile                                   yes
  dvbscan                                  yes
  timeshift                                yes
  trace                                    yes
  imagecache                               yes
  avahi                                    no
  zlib                                     yes
  libav                                    no
  ffmpeg_static                            no
  libx264                                  no
  libx264_static                           no
  libx265                                  no
  libx265_static                           no
  libvpx                                   no
  libvpx_static                            no
  libtheora                                no
  libtheora_static                         no
  libvorbis                                no
  libvorbis_static                         no
  libfdkaac                                no
  libfdkaac_static                         no
  libopus                                  no
  libopus_static                           no
  nvenc                                    no
  vaapi                                    no
  mmal                                     no
  omx                                      no
  inotify                                  yes
  epoll                                    yes
  pcre                                     no
  pcre2                                    yes
  uriparser                                yes
  ccache                                   no
  tvhcsa                                   yes
  bundle                                   yes
  pngquant                                 no
  kqueue                                   no
  dbus_1                                   no
  android                                  no
  gtimer_check                             no
  slow_memoryinfo                          no
  libsystemd_daemon                        no
  bintray_cache                            yes
  ddci                                     yes
  cclang_threadsan                         no
  gperftools                               no
  execinfo                                 yes
  W_unused_result                          yes
  getloadavg                               yes
  atomic32                                 yes
  atomic64                                 yes
  atomic_time_t                            yes
  atomic_ptr                               yes
  bitops64                                 yes
  lockowner                                yes
  qsort_r                                  yes
  stime                                    yes
  gmtoff                                   yes
  recvmmsg                                 yes
  sendmmsg                                 yes
  ifnames                                  yes
  py_gzip                                  yes
  bin_pkg_config                           yes
  bin_xgettext                             yes
  bin_msgmerge                             yes
  bin_gzip                                 yes
  bin_bzip2                                yes
  ssl                                      yes
  linuxdvbapi                              yes
  linuxdvb_ca                              yes
  upnp                                     yes
  inotify_h                                yes
  inotify_init1                            yes
  dvbcsa                                   yes
  epoll_create1                            yes
  mpegts                                   yes
  mpegts_dvb                               yes

Packages:
  openssl                                  1.1.0h
  zlib                                     1.2.11
  libpcre2-8                               10.31
  liburiparser                             0.8.5

Installation paths:
  Prefix:                                  /root/tvheadend/out-armel
  Binaries:                                ${prefix}/bin
  Libraries:                               ${prefix}/lib
  Data files:                              ${prefix}/share
  Man pages:                               ${datadir}/man

Final Binary:
  /root/tvheadend/tvheadend/build.linux/tvheadend

Tvheadend Data Directory:
  /root/tvheadend/out-armel/share/tvheadend

I'm able to successfully build this without errors:
[email protected]:~/tvheadend/tvheadend# file build.linux/tvheadend 
build.linux/tvheadend: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=8d84607786323969fb2f24c72ea2b9d28c1e879e, not stripped
The problem is when I want to add hdhomerun_static or ffmpeg_static or any other video library such as libx264: the configure script doesn't seem to pass the required switches and CC to them, and they're built against the host architecture (x86_64).

Say for example I remove --disable-ffmpeg_static from the previous command line; I get:

... cut ...
 avahi                                    no
  zlib                                     yes
  libav                                    yes
  ffmpeg_static                            yes
  libx264                                  no
  libx264_static                           no
  libx265                                  no
  libx265_static                           no
  libvpx                                   no
  libvpx_static                            no
  libtheora                                no
  libtheora_static                         no
  libvorbis                                no
  libvorbis_static                         no
  libfdkaac                                no
  libfdkaac_static                         no
  libopus                                  no
  libopus_static                           no
  nvenc                                    no
... cut ...
CC              src/descrambler/algo/libaesdec.o
CC              src/descrambler/algo/libaes128dec.o
CC              src/descrambler/algo/libdesdec.o
MKBUNDLE        bundle.c
CC              src/docs.o
CC              build.o
CC              src/version.o
CC              timestamp.o
CC              src/tvh_locale.o
CC              bundle.o
CC              tvheadend
/root/tvheadend/tvheadend/build.linux/ffmpeg/build/ffmpeg/lib/libavfilter.a: error adding symbols: File format not recognized
collect2: error: ld returned 1 exit status
Makefile:699: recipe for target '/root/tvheadend/tvheadend/build.linux/tvheadend' failed
make: *** [/root/tvheadend/tvheadend/build.linux/tvheadend] Error 1
Or, if I remove --disable-hdhomerun_static only:
... cut ...
  satip_server                             yes
  satip_client                             yes
  hdhomerun_client                         yes
  hdhomerun_static                         yes
  iptv                                     yes
  tsfile                                   yes
  dvbscan                                  yes
  timeshift                                yes
  trace                                    yes
  imagecache                               yes
  avahi                                    no
  zlib                                     yes
  libav                                    no
  ffmpeg_static                            no
  libx264                                  no
  libx264_static                           no
  libx265                                  no
  libx265_static                           no
... cut ...
CC              src/descrambler/algo/libaesdec.o
CC              src/descrambler/algo/libaes128dec.o
CC              src/descrambler/algo/libdesdec.o
MKBUNDLE        bundle.c
CC              build.o
CC              src/docs.o
CC              src/tvh_locale.o
CC              src/version.o
CC              src/input/mpegts/tvhdhomerun/tvhdhomerun.o
CC              src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.o
CC              timestamp.o
CC              bundle.o
CC              tvheadend
/root/tvheadend/tvheadend/build.linux/hdhomerun/libhdhomerun/libhdhomerun.a: error adding symbols: File format not recognized
collect2: error: ld returned 1 exit status
Makefile:699: recipe for target '/root/tvheadend/tvheadend/build.linux/tvheadend' failed
make: *** [/root/tvheadend/tvheadend/build.linux/tvheadend] Error 1
So I'm asking if it's possible to fix the configure script to make it easier to cross-compile TVHeadend for other architectures without going crazy. I've tried experimenting myself but especially with ffmpeg it's not easy to guess which are the correct switches and then allow TVHeadend to link to them. :(


Files

Makefile.ffmpeg-BETA.patch (3.03 KB) Makefile.ffmpeg-BETA.patch Allows to cross-compile with ffmpeg (see post #6) virtual dj, 2019-03-23 13:45

History

#2

Updated by virtual dj over 2 years ago

saen acro wrote:

see this repo and ARM part build system and patches applied
https://github.com/Audioniek/buildsystem/blob/master/make/tvheadend.mk

Thanks for the links but if I understand well, they guy is actually compiling without hdhomerun and ffmpeg, see these lines:
https://github.com/Audioniek/buildsystem/blob/2154e774802589c5a761515fc2df3499411de573/make/tvheadend.mk#L64-L82

... so it does not help with my problem, unfortunately. As I've written before, I'm already able to build TVHeadend without them, the problem is to include HDHomerun and ffmpeg: the TVHeadend configure script doesn't seem to pass the switches to the sub-projects. :(

#3

Updated by Martin Walter over 2 years ago

virtual dj wrote:

Thanks for the links but if I understand well, they guy is actually compiling without hdhomerun and ffmpeg, see these lines:
https://github.com/Audioniek/buildsystem/blob/2154e774802589c5a761515fc2df3499411de573/make/tvheadend.mk#L64-L82

... so it does not help with my problem, unfortunately. As I've written before, I'm already able to build TVHeadend without them, the problem is to include HDHomerun and ffmpeg: the TVHeadend configure script doesn't seem to pass the switches to the sub-projects. :(

There were similar problems with Synology builds. It has been linked dynamically for some time now. Maybe you find some inspiration here:
https://github.com/SynoCommunity/spksrc/commit/52144d065a0276bada7a00ed73106c8dad4149db#diff-17fd1f05631a28ef3e72b18ad070f52a
It contains a patch that might help you as well...

#4

Updated by saen acro over 2 years ago

Why you need ffmpeg there is not enough power in cpu to do transcode.

#5

Updated by virtual dj over 1 year ago

I had some spare time this morning so I decided to retry with this issue, as the compile time on the QEMU armel VM really bothers me.

I had success with the second part, i.e. the HDHomerun static library, and I've created a PR for this here:
https://github.com/tvheadend/tvheadend/pull/1267

Just to summarize, in a x86_64 system when configuring for x86_64 in this way:

[email protected]:~/tvheadend2/tvheadend# ./configure --disable-tvhcsa --enable-hdhomerun_client --disable-dvbscan --disable-avahi --disable-libav --disable-ffmpeg_static --disable-libx264 --disable-libx265 --disable-libvpx --disable-libtheora --disable-libvorbis
after building I get an x86_64 executable:
[email protected]:~/tvheadend2/tvheadend# make
... cut ...
Markdown: docs/wizard/network.md
Markdown: docs/wizard/status.md
CC              src/docs.o
CC              tvheadend
[email protected]:~/tvheadend2/tvheadend# file build.linux/tvheadend 
build.linux/tvheadend: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=71a2d01207b9346b0b1b14206059649d5e34c9c5, not stripped

When cross-compiling on the same system for armel, instead, I configure in this way:
[email protected]:~/tvheadend2/tvheadend# PKG_CONFIG_PATH=/root/tvheadend/out-armel/lib/pkgconfig ./configure --prefix=/root/tvheadend/out-armel --cc=arm-linux-gnueabi-gcc --cflags='-msoft-float -I/root/tvheadend/out-armel/include -L/root/tvheadend/out-armel/lib' --ldflags='-msoft-float -Wl,-rpath,./,-rpath,../lib' --arch=armel --host=arm-linux-gnueabi --disable-tvhcsa --enable-hdhomerun_client --disable-dvbscan --disable-avahi --disable-libav --disable-ffmpeg_static --disable-libx264 --disable-libx265 --disable-libvpx --disable-libtheora --disable-libvorbis
but while TVHeadend correctly uses arm-linux-gnueabi-gcc the HDHomerun library, without the PR, uses gcc because of its Makefile:
https://github.com/Silicondust/libhdhomerun/blob/9719cbc7a562dfc3ae638ba1f3769f9451db5389/Makefile#L14-L15

... so I get errors when linking the library at the end:

[email protected]:~/tvheadend2/tvheadend# make
... cut ...
Markdown: docs/wizard/network.md
Markdown: docs/wizard/status.md
CC              src/docs.o
CC              build.o
CC              timestamp.o
CC              tvheadend
/root/tvheadend/tvheadend/build.linux/hdhomerun/libhdhomerun/libhdhomerun.a: error adding symbols: File format not recognized
collect2: error: ld returned 1 exit status
Makefile:699: recipe for target '/root/tvheadend/tvheadend/build.linux/tvheadend' failed
make: *** [/root/tvheadend/tvheadend/build.linux/tvheadend] Error 1
That's because it's linking an armel TVHeadend binary with a x86_64 HDHomerun library! With the PR, instead:
[email protected]:~/tvheadend2/tvheadend# make
... cut ...
Markdown: docs/wizard/network.md
Markdown: docs/wizard/status.md
CC              timestamp.o
CC              src/docs.o
CC              tvheadend
[email protected]:~/tvheadend2/tvheadend# file build.linux/tvheadend 
build.linux/tvheadend: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=8aecb101536cd59fc1244873e3d7eb57d5fdff7d, not stripped

Now I think I should do the same thing for ffmpeg...
Unfortunately it's a lot more difficult, but I will try! Help is needed, especially from Jaroslav ;)

#6

Updated by virtual dj over 1 year ago

I made some progresses with ffmpeg and now I'm able to cross-compile the original configuration almost correctly!
This is my current configuration:

[email protected]:~/tvheadend/tvheadend# PKG_CONFIG_PATH=/root/tvheadend/out-armel/lib/pkgconfig ./configure \
--prefix=/root/tvheadend/out-armel \
--cc=arm-linux-gnueabi-gcc \
--cflags='-msoft-float -I/root/tvheadend/out-armel/include -L/root/tvheadend/out-armel/lib' \
--ldflags='-msoft-float -Wl,-rpath,./,-rpath,../lib' \
--arch=armel \
--host=arm-linux-gnueabi \
--disable-tvhcsa \
--disable-hdhomerun_client --disable-hdhomerun_static \
--disable-avahi \
--enable-libfdkaac \
--disable-libx265

As you may notice, I'm disabling tvhcsa and hdhomerun, but they can be enabled without issues with my previous pull request (it's just a matter of speeding up the process here).

To cross-compile ffmpeg and the other audio/video libraries I needed to modify the Makefile.ffmpeg file with the attached patch. Of course the patch is not "correct" because it hardcodes arguments and paths in the Makefile, but as I basically don't know anything about makefiles, I have to study how to apply and pass the correct parameters to it from the TVHeadend configure script. I still ask for help about it, I'm sure the main developers or Jaroslav himself is able to understand what needs to be done.

To summarize, the issue is the TVHeadend configure script that doesn't pass the correct environment/arguments to the ffmpeg and libx*** libraries when cross-compiling.

Unfortunately I tried to enable libx265 too but it is even harder because it doesn't use gcc and Makefiles but cmake. When configuring without --disable-libx265 I get:

<command-line>:0:9: error: incompatible types in assignment of ‘void(pixel*, intptr_t, const pixel*, intptr_t, const pixel*, intptr_t, int) {aka void(unsigned char*, int, const unsigned char*, int, const unsigned char*, int, int)}’ to ‘void (* [2])(pixel*, intptr_t, const pixel*, intptr_t, const pixel*, intptr_t, int) {aka void (* [2])(unsigned char*, int, const unsigned char*, int, const unsigned char*, int, int)}’
/root/tvheadend/tvheadend/build.linux/ffmpeg/x265_2.9/source/common/cpu.h:30:28: note: in definition of macro ‘PFX3’
 #define PFX3(prefix, name) prefix ## _ ## name
                            ^~~~~~
/root/tvheadend/tvheadend/build.linux/ffmpeg/x265_2.9/source/common/cpu.h:32:28: note: in expansion of macro ‘PFX2’
 #define PFX(name)          PFX2(X265_NS, name)
                            ^~~~
/root/tvheadend/tvheadend/build.linux/ffmpeg/x265_2.9/source/common/cpu.h:32:33: note: in expansion of macro ‘X265_NS’
 #define PFX(name)          PFX2(X265_NS, name)
                                 ^~~~~~~
/root/tvheadend/tvheadend/build.linux/ffmpeg/x265_2.9/source/common/arm/asm-primitives.cpp:749:40: note: in expansion of macro ‘PFX’
         p.pu[LUMA_64x64].pixelavg_pp = PFX(pixel_avg_pp_64x64_neon);
                                        ^~~
common/CMakeFiles/common.dir/build.make:62: recipe for target 'common/CMakeFiles/common.dir/arm/asm-primitives.cpp.o' failed
make[4]: *** [common/CMakeFiles/common.dir/arm/asm-primitives.cpp.o] Error 1
make[4]: Leaving directory '/root/tvheadend/tvheadend/build.linux/ffmpeg/x265_2.9/build/linux'
CMakeFiles/Makefile2:279: recipe for target 'common/CMakeFiles/common.dir/all' failed
make[3]: *** [common/CMakeFiles/common.dir/all] Error 2
make[3]: Leaving directory '/root/tvheadend/tvheadend/build.linux/ffmpeg/x265_2.9/build/linux'
Makefile:127: recipe for target 'all' failed
make[2]: *** [all] Error 2
make[2]: Leaving directory '/root/tvheadend/tvheadend/build.linux/ffmpeg/x265_2.9/build/linux'
Makefile.ffmpeg:279: recipe for target '/root/tvheadend/tvheadend/build.linux/ffmpeg/x265_2.9/.tvh_build' failed
make[1]: *** [/root/tvheadend/tvheadend/build.linux/ffmpeg/x265_2.9/.tvh_build] Error 2
make[1]: Leaving directory '/root/tvheadend/tvheadend'
Makefile:849: recipe for target '/root/tvheadend/tvheadend/build.linux/ffmpeg/build/ffmpeg/lib/libavcodec.a' failed
make: *** [/root/tvheadend/tvheadend/build.linux/ffmpeg/build/ffmpeg/lib/libavcodec.a] Error 2
and I'm definitely unable to understand how to pass a different CC and CXX to cmake that x265 is using. :(
On a QEMU armel VM, TVHeadend with ffmpeg and libx265 builds correctly (even though it takes AGES) and this means it's only a matter of configuring the scripts correctly.
#7

Updated by Martin Walter over 1 year ago

Maybe this makes it a bit easier:
https://github.com/SynoCommunity/spksrc/blob/master/cross/ffmpeg/Makefile
https://github.com/SynoCommunity/spksrc/blob/master/cross/x265/Makefile
You will find cross-compilation configurations for ARM5, ARM7 and ARM8 platforms there. You will find some patches there as well, but not sure you'll need them...

Also available in: Atom PDF