libvlc3.0.4在ubuntu16.04x64上的交叉編譯全過程記錄
週末折騰了好久,經過連續的出現問題,定位問題,解決問題,終於順利編譯通過了vlc的最新版本,中間嘗試了多個版本的編譯,比如vlc3.0.0,想著離2.x版本(2.x版本已經編譯通過,可以參考:ubuntu平臺,VLC/LibVLC交叉編譯,生成win32版本,以及LibVLC增加錄影介面)比較接近,應該容易編譯通過,沒成想也是一堆問題,其實主要還是版本導致的介面不對應問題,於是ubuntu的各種版本16.04x86,16.04x64,18.04x64等的嘗試,終於看到了成功的果實,就像是中了大獎一樣的心情。好吧,閒話不多說了,下面記錄一下編譯過程中的問題。
編譯環境是在win7系統的虛擬機器裡面安裝的ubuntu16.04x64 LTS版本,這個沒什麼好說的,不熟的可以自行搜尋。因為vlc3.x版本需要gcc/g++支援c++11,所以gcc/g++的版本不能太低,可以通過命令gcc --version檢視一下,我用的是4.9.3版本,大於4.9.0的版本都支援c++11。
官方的編譯文件雖然說照著做肯定編譯不過,但還是要參考一下的,最起碼知道每一步該怎麼去操作。
一、Mingw-w64環境
因為vlc主要用的還是32位版本,所以直接安裝x86交叉編譯環境:
sudo apt-get install gcc-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64-tools
二、開發工具集
vlc編譯過程所依賴的相關工具等,直接命令安裝即可。
sudo apt-get update
sudo apt-get install lua5.2 libtool automake autoconf autopoint make gettext pkg-config
sudo apt-get install qt4-dev-tools qt5-default git subversion cmake cvs
sudo apt-get install wine64-development-tools zip p7zip nsis bzip2
sudo apt-get install yasm ragel ant default-jdk protobuf-compiler dos2unix
sudo apt-get install gperf flex bison
安裝完成後,需要確認一下gettext的版本,gettext --version檢視,vlc-3.x 要求 gettext>=0.19.8,但是 ubuntu 官方源只更新到了 0.19.7,如果版本低的話,手動安裝一下即可。
wget ftp://ftp.gnu.org/gnu/gettext/gettext-0.19.8.tar.xz
tar -Jxvf gettext-0.19.8.tar.xz
cd gettext-0.19.8/
./configure --prefix=/usr
sudo make && sudo make install
三、安裝第三方庫
首先下載vlc3.0.4原始碼,建議手動去官方ftp目錄下載,git獲取的不一定是最新版本的。
解壓原始碼之後,進入vlc目錄,開始操作:
mkdir -p contrib/win32
cd contrib/win32
../bootstrap --host=HOST-TRIPLET
make fetch
make
如果提示HOST-TRIPLET無法識別之類的問題,可以直接改成i686-w64-mingw32。
這裡採用的是make fetch的方式,而沒有采用make prebuilt的方式,是因為prebuilt的庫檔案比較舊,需要等待一點時間。
四、編譯vlc
回到vlc目錄,開始操作
./bootstrap
mkdir win32
cd win32
export PKG_CONFIG_LIBDIR=$HOME/vlc/contrib/i686-w64-mingw32/lib/pkgconfig
export CFLAGS="-O2"
export CXXFLAGS="-O2"
../configure --host=i686-w64-mingw32
其中遇到了以下幾個問題:
1、cp ../../contrib/tarballs/dxgi1_2.idl dxgi12 && cd dxgi12 && patch -fp1 < ../../../contrib/src/d3d11/dxgi12.patch
patching file dxgi1_2.idl
mkdir -p -- "/home/vlc/vlc/contrib/i686-w64-mingw32/include/"
i686-w64-mingw32-widl -DBOOL=WINBOOL -I/usr/include/wine/windows/ -h -o /home/vlc/vlc/contrib/i686-w64-mingw32/include/dxgi1_2.h dxgi12/dxgi1_2.idl
dxgi12/dxgi1_2.idl:43: error: syntax error, unexpected aKNOWNTYPE, expecting tIMPORT
../../contrib/src/d3d11/rules.mak:63: recipe for target '/home/vlc/vlc/contrib/i686-w64-mingw32/include/dxgi1_2.h' failed
make: *** [/home/vlc/vlc/contrib/i686-w64-mingw32/include/dxgi1_2.h] Error 1
解決方案:
sudo apt-get install wine64-development-tools
修改 contib\src\d3d9\rules.mak 中的IDL_INC_PATH = /usr/include/wine/windows/ 為 IDL_INC_PATH = /usr/include/wine-development/windows/
修改 contrib\src\d3d11\rules.mak 中的IDL_INC_PATH = /usr/include/wine/windows/ 為 IDL_INC_PATH = /usr/include/wine-development/windows/
2、versioninfo.rc錯誤:
i686-w64-mingw32-windres: versioninfo.rc.in:21: syntax error
i686-w64-mingw32-windres: preprocessing failed.
Makefile:1224: recipe for target 'versioninfo.lo' failed
make[2]: *** [versioninfo.lo] Error 1
make[2]: Leaving directory '/home/d/vlc-3.0.0/contrib/win32/gcrypt/src'
Makefile:487: recipe for target 'install-recursive' failed
make[1]: *** [install-recursive] Error 1
make[1]: Leaving directory '/home/d/vlc-3.0.0/contrib/win32/gcrypt'
../../contrib/src/gcrypt/rules.mak:72: recipe for target '.gcrypt' failed
make: *** [.gcrypt] Error 2
解決方案:
修改 contrib/win32/gcrypt/configure.ac 第42行
修改前:m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r']))
修改後:m4_esyscmd([printf %x $(wc -l < debian/changelog)]))
3、../../contrib/src/protobuf/rules.mak:24: recipe for target '.protobuf' failed
make: *** [.protobuf] Error 2
解決方案:
通過protoc --version可檢視protobuf版本,需升級protobuf到3.0.1版本,這樣和contribute裡的版本保持一致,避免後面再次報錯
https://github.com/protocolbuffers/protobuf/releases/ (此地址可能需要FQ,我會把檔案放到網盤裡)
configure完成後,執行sudo make,報了以下幾個錯誤:
1、In file included from ../../modules/access/dshow/dshow.cpp:52:0:
../../modules/access/dshow/access.h:33:24: fatal error: wrl/client.h: No such file or directory
compilation terminated.
解決方案:
從 https://forum.videolan.org/viewtopic.php?f=32&t=137580&p=453684&hilit=roapi.h%3A80%3A25#p453684 下載 mingw-w64-mingw-w64
將mingw-w64-mingw-w64/mingw-w64-headers/include下的 wrl 資料夾整個拷貝到編譯包的contrib/i686-w64-mingw32/include下
2、/usr/share/mingw-w64/include/roapi.h:60:33: error: ‘Windows::Foundation::Initalize’ declared as an ‘inline’ variable
__inline HRESULT Initalize (RO_INIT_TYPE it
^
/usr/share/mingw-w64/include/roapi.h:60:33: error: ‘RO_INIT_TYPE’ was not declared in this scope
/usr/share/mingw-w64/include/roapi.h:64:7: error: expected ‘,’ or ‘;’ before ‘{’ token
) { return RoInitialize (it); }
^
/usr/share/mingw-w64/include/roapi.h: In function ‘void Windows::Foundation::Uninitialize()’:
/usr/share/mingw-w64/include/roapi.h:66:23: error: ‘RoUninitialize’ was not declared in this scope
{ RoUninitialize (); }
^
/usr/share/mingw-w64/include/roapi.h: At global scope:
/usr/share/mingw-w64/include/roapi.h:74:35: error: ‘ABI::Windows::Foundation::Initialze’ declared as an ‘inline’ variable
__inline HRESULT Initialze (RO_INIT_TYPE it
^
/usr/share/mingw-w64/include/roapi.h:74:35: error: ‘RO_INIT_TYPE’ was not declared in this scope
/usr/share/mingw-w64/include/roapi.h:78:9: error: expected ‘,’ or ‘;’ before ‘{’ token
) { return RoInitialize (it); }
^
/usr/share/mingw-w64/include/roapi.h: In function ‘void ABI::Windows::Foundation::Uninitialize()’:
/usr/share/mingw-w64/include/roapi.h:80:25: error: ‘RoUninitialize’ was not declared in this scope
{ RoUninitialize (); }
^
Makefile:25261: recipe for target 'access/dshow/dshow.lo' failed
make[4]: *** [access/dshow/dshow.lo] Error 1
解決方案:
將mingw-w64-mingw-w64/mingw-w64-headers/include中的roapi.h dwrite.h dwrite_1.h dwrite_2.h versionhelpers.h等檔案拷貝到contrib/i686-w64-mingw32/include/,這樣可以避免後面出現的許多錯誤
3、stream_out/chromecast/cast_channel.pb.h:12:2: error: #error This file was generated by a newer version of protoc which is
#error This file was generated by a newer version of protoc which is
^
stream_out/chromecast/cast_channel.pb.h:13:2: error: #error incompatible with your Protocol Buffer headers. Please update
#error incompatible with your Protocol Buffer headers. Please update
^
stream_out/chromecast/cast_channel.pb.h:14:2: error: #error your headers.
#error your headers.
^
In file included from stream_out/chromecast/cast_channel.pb.h:22:0,
from ../../modules/stream_out/chromecast/chromecast.h:45,
from ../../modules/stream_out/chromecast/cast.cpp:33:
/home/zqf/vlc/contrib/i686-w64-mingw32/include/google/protobuf/io/coded_stream.h:1362:5: warning: "_MSC_VER" is not defined [-Wundef]
#if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
^
In file included from ../../modules/stream_out/chromecast/chromecast.h:45:0,
from ../../modules/stream_out/chromecast/cast.cpp:33:
stream_out/chromecast/cast_channel.pb.h:25:60: fatal error: google/protobuf/generated_message_table_driven.h: No such file or directory
compilation terminated.
Makefile:25196: recipe for target 'stream_out/chromecast/libstream_out_chromecast_plugin_la-cast.lo' failed
make[4]: *** [stream_out/chromecast/libstream_out_chromecast_plugin_la-cast.lo] Error 1
解決方案:安裝protobuf3.0.1版本,上面已安裝的話,就應該不會報這個錯誤了
4、/home/zqf/vlc/contrib/i686-w64-mingw32/include/versionhelpers.h: In function ‘IsWindows8Point1OrGreater’:
/home/zqf/vlc/contrib/i686-w64-mingw32/include/versionhelpers.h:70:45: error: ‘_WIN32_WINNT_WINBLUE’ undeclared (first use in this function)
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0);
^
/home/zqf/vlc/contrib/i686-w64-mingw32/include/versionhelpers.h:70:45: note: each undeclared identifier is reported only once for each function it appears in
/home/zqf/vlc/contrib/i686-w64-mingw32/include/versionhelpers.h: In function ‘IsWindowsThresholdOrGreater’:
/home/zqf/vlc/contrib/i686-w64-mingw32/include/versionhelpers.h:74:45: error: ‘_WIN32_WINNT_WINTHRESHOLD’ undeclared (first use in this function)
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINTHRESHOLD), LOBYTE(_WIN32_WINNT_WINTHRESHOLD), 0);
解決方案:
修改拷貝到contrib/i686-w64-mingw32/include/下面的versionhelpers.h檔案,將_WIN32_WINNT_WINBLUE和_WIN32_WINNT_WINTHRESHOLD改成_WIN32_WINNT_WIN8
引申:下面是 Windows 10 版 SDKDDKVer.h(它對每個版本的 Windows 的值進行編碼)中的行:
// // _WIN32_WINNT version constants //
#define _WIN32_WINNT_NT4 0x0400 // Windows NT 4.0
#define _WIN32_WINNT_WIN2K 0x0500 // Windows 2000
#define _WIN32_WINNT_WINXP 0x0501 // Windows XP
#define _WIN32_WINNT_WS03 0x0502 // Windows Server 2003
#define _WIN32_WINNT_WIN6 0x0600 // Windows Vista
#define _WIN32_WINNT_VISTA 0x0600 // Windows Vista
#define _WIN32_WINNT_WS08 0x0600 // Windows Server 2008
#define _WIN32_WINNT_LONGHORN 0x0600 // Windows Vista
#define _WIN32_WINNT_WIN7 0x0601 // Windows 7
#define _WIN32_WINNT_WIN8 0x0602 // Windows 8
#define _WIN32_WINNT_WINBLUE 0x0603 // Windows 8.1
#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 // Windows 10
#define _WIN32_WINNT_WIN10 0x0A00 // Windows 10
make完成後,進行打包生成windows相關檔案的操作:
make package-win-common
第一次打包成功,無任何錯誤報出,第二次報出以下錯誤:
cp: cannot stat '../share/hrtfs': No such file or directory
Makefile:2389: recipe for target 'package-win-common' failed
make: *** [package-win-common] Error 1
解決方案:在vlc3.0.4根目錄的share資料夾下面手動建一個空檔案hrtfs
會在win32下面生成vlc-3.0.4資料夾,然後
cd vlc-3.0.4
find . -name "*.dll" -type f | xargs -i strip --strip-all {} 去掉除錯資訊
拷貝整個vlc-3.0.4資料夾到本地測試,播放檔案和網路流等一切正常。
最後分享一下用到的幾個檔案
連結:https://pan.baidu.com/s/1Pqu5dPW_8oEKxJmR_x09Jg
提取碼:134a
---------------------
作者:憑欄望月
來源:CSDN
原文:https://blog.csdn.net/zhuquanfu/article/details/83505531
版權宣告:本文為博主原創文章,轉載請附上博文連結!