Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ubuntu 18.04下编译windows版本的VLC 3.0.8 #6

Open
kinzess opened this issue Apr 24, 2020 · 2 comments
Open

ubuntu 18.04下编译windows版本的VLC 3.0.8 #6

kinzess opened this issue Apr 24, 2020 · 2 comments
Labels

Comments

@kinzess
Copy link
Owner

kinzess commented Apr 24, 2020

第一次尝试在linux下编译windows的程序,踩了不少坑,特此记录一下。

VLC本身比较难编译,看了很多中文的教程,都吐槽说官方教程不靠谱,但我编译到最后,发现还是官方教程最靠谱。照着官方教程做下来,坑是最少的。
此处附上官方教程地址:
https://wiki.videolan.org/Win32Compile/

一开始使用的是ubuntu 16.04,发现很多依赖包版本太老,就换成了18.04。
安装的是Mingw-w64环境,编译64版本。
这里注意官方教程有一句话:

NB: you need mingw-w64 version 5.0.1 to compile it.

而18.04默认安装的mingw是5.0.3,但对应的gcc7.3,编译到后面会出现问题,建议先升级到19.04的6.0.0。
具体升级方法看后文。
如果不想浪费时间,一定要先升级!

此处可能把ubuntu换成19.04更好。但因为一开始不知道,ubuntu还是使用18.04,只是升级了mingw到19.04的版本。

首先编译第三方库,注意因为编译的是3.0.8版本的VLC,必须使用Manually built方式,不能使用Prebuilt方式。
一路安装下来,如果提示缺少包,直接apt安装即可。大部分依赖都可以用这种方式安装。
如果遇到提示安装meson的版本太低,则可以卸载apt安装的版本,然后用pip3安装即可。

一个比较坑的问题,是在编译gcrypt的时候,提示syntax error:

/bin/bash ../libtool --mode=compile --tag=RC x86_64-w64-mingw32-windres -DHAVE_CONFIG_H -I. -I../../src -I..     -i "versioninfo.rc" -o "versioninfo.lo"
libtool: compile:  x86_64-w64-mingw32-windres -DHAVE_CONFIG_H -I. -I../../src -I.. -i versioninfo.rc  -o .libs/versioninfo.o
x86_64-w64-mingw32-windres: versioninfo.rc.in:21: syntax error
Makefile:1240: recipe for target 'versioninfo.lo' failed
make[2]: *** [versioninfo.lo] Error 1

原因是configure.ac里,写死了一些git的操作。而vlc编译的源码,是tar包,没有git的相关信息,导致编译失败。具体可以参考https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=814954

--- a/configure.ac
+++ b/configure.ac
@@ -39,7 +39,7 @@
 m4_define(mym4_version,
           [mym4_version_major.mym4_version_minor.mym4_version_micro])
 m4_define([mym4_revision],
-          m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r']))
+          m4_esyscmd([printf %x $(wc -l < debian/changelog)]))
 m4_define([mym4_revision_dec],
           m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))]))
 m4_define([mym4_betastring],

修改configure.ac,跳过git操作即可。

另一个比较坑的问题,是在编译glew的时候,提示找不到依赖库:

x86_64-w64-mingw32-ld -o lib/glew32.dll src/glew.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
x86_64-w64-mingw32-ld: cannot find -lglu32
x86_64-w64-mingw32-ld: cannot find -lopengl32
x86_64-w64-mingw32-ld: cannot find -lgdi32
x86_64-w64-mingw32-ld: cannot find -luser32
x86_64-w64-mingw32-ld: cannot find -lkernel32
Makefile:101: recipe for target 'lib/glew32.dll' failed

查了很久才发现,是“-L/mingw/lib”的问题。在windows下用mingw编译,路径就是“/mingw/lib”,但是,在linux下编译,路径就不是这个了。
首先使用x86_64-w64-mingw32-ld命令,通过SEARCH_DIR确定mingw的lib路径:

$ x86_64-w64-mingw32-ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu")
SEARCH_DIR("=/lib/x86_64-linux-gnu")
SEARCH_DIR("=/usr/lib/x86_64-linux-gnu")
SEARCH_DIR("=/usr/local/lib")
SEARCH_DIR("=/lib")
SEARCH_DIR("=/usr/lib")
SEARCH_DIR("=/usr/x86_64-w64-mingw32/lib")

可以看到,路径是“/usr/x86_64-w64-mingw32/lib”。
查到路径后,修改glew/config/Makefile.mingw文件,把里面的“/mingw/lib”修改成“/usr/x86_64-w64-mingw32/lib”,就可以继续编译了。

编译完第三方库,按照教程,继续编译VLC。
但一部分插件会无法编译,错误如下:

CXXLD libdcp_plugin.la
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z35_txnal_cow_string_C1_for_exceptionsPvPKcS_+0x2c): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU1'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z35_txnal_cow_string_C1_for_exceptionsPvPKcS_+0x39): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `transaction clone for operator new[](unsigned long long)'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z35_txnal_cow_string_C1_for_exceptionsPvPKcS_+0x5d): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_memcpyRtWn'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z23_txnal_cow_string_c_strPKv+0x1): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU8'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z23_txnal_sso_string_c_strPKv+0x1): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU8'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z20_txnal_cow_string_D1Pv+0x5): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU8'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z20_txnal_cow_string_D1Pv+0x1e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_addUserCommitAction'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_ZGTtNSt11logic_errorC1EPKc+0x2e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_memcpyRnWt'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_ZGTtNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+0x2e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_memcpyRnWt'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_ZGTtNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+0x36): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU8'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_ZGTtNSt11logic_errorD0Ev+0x1a): additional relocation overflows omitted from the output
collect2: error: ld returned 1 exit status
Makefile:13212: recipe for target 'libdcp_plugin.la' failed

这是一个存在于6和7版本gcc的bug,gcc8已经修复。
详细信息可以查看论坛:https://forum.videolan.org/viewtopic.php?t=144693
而18.04安装的gcc版本是7.3,所以会碰到这个bug。
修复方法是升级gcc,或者修改libstdc++的os_defines.h文件,并重新编译工具链。
这里我采用的是升级gcc7到gcc8的方法。
卸载所有mingw的包,直接下载安装ubuntu 19.04的mingw安装包即可。
可以直接使用包名去搜索,很容易就能搜索到下载地址。此处不提供下载地址。
注意mingw的gcc包换了,那对应的mingw包也要换,不然头文件会冲突。

gcc-mingw-w64-base_8.3.0-6ubuntu1+21.1build2_amd64.deb
gcc-mingw-w64-x86-64_8.3.0-6ubuntu1+21.1build2_amd64.deb
g++-mingw-w64-x86-64_8.3.0-6ubuntu1+21.1build2_amd64.deb
mingw-w64-common_6.0.0-3_all.deb
mingw-w64-tools_6.0.0-3_amd64.deb
mingw-w64-x86-64-dev_6.0.0-3_all.deb

替换上述6个包后,必须从头开始,从第三方库开始编译,不然也会出现问题。T_T...
如果还需要编译32位的vlc,则还需要安装以下几个包:

gcc-mingw-w64-i686_8.3.0-6ubuntu1+21.1build2_amd64.deb
g++-mingw-w64-i686_8.3.0-6ubuntu1+21.1build2_amd64.deb
mingw-w64-i686-dev_6.0.0-3_all.deb

安装方法是:

$ sudo dpkg -i *.deb
$ sudo apt install -f

另外,在编译的时候,如果系统安装了protobuf,则需要检查是不是3.1.0版本,不然会出现以下问题:

make[4]: Entering directory 'vlc-3.0.8-win64-gcc8.3/win32/modules'
  CXX      stream_out/chromecast/libstream_out_chromecast_plugin_la-cast.lo
In file included from vlc-3.0.8-win64-gcc8.3/contrib/x86_64-w64-mingw32/include/google/protobuf/stubs/common.h:40,
                 from stream_out/chromecast/cast_channel.pb.h:9,
                 from ../../extras/package/win32/../../../modules/stream_out/chromecast/chromecast.h:45,
                 from ../../extras/package/win32/../../../modules/stream_out/chromecast/cast.cpp:33:
vlc-3.0.8-win64-gcc8.3/contrib/x86_64-w64-mingw32/include/google/protobuf/stubs/port.h:56:7: warning: "_MSC_VER" is not defined, evaluates to 0 [-Wundef]
   #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
       ^~~~~~~~
In file included from ../../extras/package/win32/../../../modules/stream_out/chromecast/chromecast.h:45,
                 from ../../extras/package/win32/../../../modules/stream_out/chromecast/cast.cpp:33:
stream_out/chromecast/cast_channel.pb.h:17:2: error: #error This file was generated by an older version of protoc which is
 #error This file was generated by an older version of protoc which is
  ^~~~~
stream_out/chromecast/cast_channel.pb.h:18:2: error: #error incompatible with your Protocol Buffer headers. Please
 #error incompatible with your Protocol Buffer headers.  Please
  ^~~~~
stream_out/chromecast/cast_channel.pb.h:19:2: error: #error regenerate this file with a newer version of protoc.
 #error regenerate this file with a newer version of protoc.
  ^~~~~
Makefile:25318: recipe for target 'stream_out/chromecast/libstream_out_chromecast_plugin_la-cast.lo' failed

就是vlc需要用到的protobuf版本和系统安装的版本不一致。
运行命令可以检查是否安装了其他版本的protobuf:

$ locate protobuf
$ dpkg -l |grep protobuf

检查后,系统的确安装了protobuf,需要卸载:
sudo apt autoremove libprotoc10 libprotobuf10 protobuf-compiler
注意这里会把protobuf-compiler卸载掉,会导致第三方库里的projectM无法编译。
需要自己编译安装protobuf的3.1.0版本,简单的方法是:

$ cd protobuf-3.1.0
$ ./autogen.sh
$ ./configure --prefix=/usr
$ make
$ make check
$ sudo make install

安装好之后,继续需要从头开始,从第三方库开始编译T_T...

一切顺利的话,vlc就编译好了。
然后打包:
$ make package-win-common
因为我的源码是直接下载的压缩包,里面没有hrtfs目录下的文件,所以不能打包。
从git下载后,放到对应目录,再运行打包命令就可以了。
打包完成后,里面多了一个目录vlc-3.0.8,比起直接安装的vlc,里面的dll都带了调试信息,也多了一个sdk的目录,里面包括头文件和lib文件。
这是用来二次开发的,如果不需要,可以运行其他打包命令。

至此,vlc算是编译完成了。
花了2天的时间才搞定,整体来说难度不小。
主要还是要沉下心来,遇到一个问题解决一个,才能编译成功。

后续还要进行二次开发,有问题再更新把。

@qdzhaozx
Copy link

哥们,牛逼

@HelloTodayWolrd
Copy link

帮了大忙,感谢!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants