2016-05-30 15:10:57 +02:00
#!/usr/bin/python
2016-10-17 17:15:14 +02:00
import re
import os
import platform
import sys
import getopt
import shutil
import io
import argparse
import json
import urllib2
import subprocess
import textwrap
2016-10-18 12:27:12 +02:00
import traceback
2016-10-28 11:26:29 +02:00
import zipfile
2016-05-30 15:10:57 +02:00
2016-10-18 18:17:09 +02:00
from subprocess import *
2016-10-28 12:29:44 +02:00
PATH_BASE = os . path . abspath ( os . path . dirname ( sys . argv [ 0 ] ) )
PATH_BUILD = os . path . join ( PATH_BASE , ' build ' )
PATH_DEPOT_TOOLS = os . path . join ( PATH_BUILD , ' depot_tools ' )
PATH_SRC = os . path . join ( PATH_BASE , ' build ' , ' src ' )
PATH_SRC_BUILD = os . path . join ( PATH_SRC , ' build ' )
PATH_THIRD_PARTY_FFMPEG = os . path . join ( PATH_SRC , ' third_party ' , ' ffmpeg ' )
PATH_OUT = os . path . join ( PATH_SRC , ' out ' )
PATH_LIBRARY_OUT = os . path . join ( PATH_OUT , ' nw ' )
PATH_RELEASES = os . path . join ( PATH_BASE , ' releases ' )
2016-10-11 13:31:10 +02:00
2016-10-28 18:23:40 +02:00
COLOR_ERROR = ' \033 [91m '
COLOR_OK = ' \033 [92m '
COLOR_WARNING = ' \033 [93m '
COLOR_INFO = ' \033 [94m '
COLOR_NORMAL = ' \033 [0m '
COLOR_NORMAL_WINDOWS = 7
COLOR_OK_WINDOWS = 10
COLOR_INFO_WINDOWS = 11
COLOR_ERROR_WINDOWS = 12
COLOR_WARNING_WINDOWS = 14
2016-10-18 09:58:35 +02:00
def main ( ) :
2016-10-28 12:29:44 +02:00
proprietary_codecs = False
2016-10-18 09:58:35 +02:00
nw_version = get_latest_stable_nwjs ( )
host_platform = get_host_platform ( )
target_arch = get_host_architecture ( )
2016-11-02 22:37:44 +01:00
target_cpu = target_arch
platform_release_name = get_platform_release_name ( host_platform )
2017-04-04 23:19:51 +02:00
if platform . system ( ) == ' Linux ' :
2017-04-05 12:04:43 +02:00
os . environ [ " LLVM_DOWNLOAD_GOLD_PLUGIN " ] = " 1 "
2017-04-04 23:19:51 +02:00
2016-10-18 09:58:35 +02:00
try :
args = parse_args ( )
if args . clean :
response = raw_input ( ' Are you sure you want to delete your workspace? (y/n): ' ) . lower ( )
if response == ' y ' :
2016-10-28 18:23:40 +02:00
print_info ( ' Cleaning workspace... ' )
2016-10-18 09:58:35 +02:00
shutil . rmtree ( ' build ' , ignore_errors = True )
else :
2016-10-28 18:23:40 +02:00
print_info ( ' Skipping workspace cleaning... ' )
2016-05-30 15:10:57 +02:00
2016-10-18 09:58:35 +02:00
if args . nw_version :
2016-10-28 18:23:40 +02:00
print_info ( ' Setting nw version to ' + args . nw_version )
2016-11-02 22:37:44 +01:00
nw_version = args . nw_version
2016-10-17 17:15:14 +02:00
2016-10-21 20:28:18 +02:00
if args . target_arch :
target_arch = args . target_arch
2016-10-18 09:58:35 +02:00
if target_arch == ' ia32 ' :
target_cpu = ' x86 '
2016-10-11 17:08:32 +02:00
2016-10-18 09:58:35 +02:00
proprietary_codecs = args . proprietary_codecs
2016-10-21 20:28:18 +02:00
if proprietary_codecs and platform . system ( ) == ' Windows ' and not ' CYGWIN_NT ' in platform . system ( ) :
2016-10-28 18:23:40 +02:00
print_warning ( ' Script needs to be executed under CygWin to build FFmpeg \n with proprietary codecs on Windows environments, \n read https://github.com/iteufel/nwjs-ffmpeg-prebuilt/blob/master/guides/build_windows.md \n Exiting... ' )
2016-10-21 20:28:18 +02:00
sys . exit ( 1 )
2016-10-18 09:58:35 +02:00
2016-10-28 18:23:40 +02:00
print_info ( ' Building ffmpeg for {0} on {1} for {2} , proprietary_codecs = {3} ' . format ( nw_version , host_platform , target_cpu , proprietary_codecs ) )
2016-10-18 09:58:35 +02:00
2016-10-28 12:29:44 +02:00
create_directory ( PATH_BUILD )
2016-10-18 09:58:35 +02:00
clean_output_directory ( )
2016-10-17 17:15:14 +02:00
2016-10-28 09:42:01 +02:00
setup_chromium_depot_tools ( nw_version )
2016-10-18 09:58:35 +02:00
2016-10-28 09:42:01 +02:00
clone_chromium_source_code ( nw_version )
2016-10-18 09:58:35 +02:00
2016-10-28 09:42:01 +02:00
reset_chromium_src_to_nw_version ( nw_version )
2016-10-18 09:58:35 +02:00
generate_build_and_deps_files ( )
install_build_deps ( )
2016-10-28 12:29:44 +02:00
gclient_sync ( )
2016-10-18 09:58:35 +02:00
2016-10-28 09:42:01 +02:00
check_build_with_proprietary_codecs ( proprietary_codecs , host_platform , target_arch )
2016-10-18 09:58:35 +02:00
2018-08-24 10:39:40 +02:00
patch_linux_sanitizer_ia32 ( target_cpu )
2016-10-28 12:29:44 +02:00
build ( target_cpu )
2016-10-23 19:44:35 +02:00
2016-12-19 14:13:36 +01:00
zip_release_output_library ( nw_version , platform_release_name , target_arch , proprietary_codecs , get_out_library_path ( host_platform ) , PATH_RELEASES )
2016-10-28 11:26:29 +02:00
2016-10-28 18:23:40 +02:00
print_ok ( ' DONE!! ' )
2016-10-28 11:26:29 +02:00
2016-10-18 18:17:09 +02:00
except KeyboardInterrupt :
2016-10-28 18:23:40 +02:00
print ' \n \n Shutdown requested... \x1b [0;31;40m ' + ' exiting ' + ' \x1b [0m '
2016-10-23 21:05:44 +02:00
except Exception :
2016-10-28 18:23:40 +02:00
print_error ( traceback . format_exc ( ) )
2016-10-23 21:05:44 +02:00
sys . exit ( 1 )
2016-10-18 09:58:35 +02:00
2018-08-24 10:39:40 +02:00
def patch_linux_sanitizer_ia32 ( target_cpu ) :
host_platform = get_host_platform ( )
if host_platform == ' linux ' :
oldpath = os . getcwd ( )
os . chdir ( PATH_THIRD_PARTY_FFMPEG )
os . system ( ' git reset --hard ' )
if target_cpu == ' x86 ' :
shutil . copy ( os . path . join ( PATH_BASE , ' patch ' , host_platform , ' sanitizer_ia32.patch ' ) , os . getcwd ( ) )
os . system ( ' git apply --ignore-space-change --ignore-whitespace sanitizer_ia32.patch ' )
os . chdir ( oldpath )
2016-10-18 09:58:35 +02:00
def parse_args ( ) :
parser = argparse . ArgumentParser ( description = ' ffmpeg builder script. ' )
parser . add_argument ( ' -c ' , ' --clean ' , help = ' Clean the workspace, removes downloaded source code ' , required = False , action = ' store_true ' )
parser . add_argument ( ' -nw ' , ' --nw_version ' , help = ' Build ffmpeg for the specified Nw.js version ' , required = False )
parser . add_argument ( ' -ta ' , ' --target_arch ' , help = ' Target architecture, ia32, x64 ' , required = False )
parser . add_argument ( ' -pc ' , ' --proprietary_codecs ' , help = ' Build ffmpeg with proprietary codecs ' , required = False , action = ' store_true ' )
return parser . parse_args ( )
2016-10-17 17:15:14 +02:00
def grep_dep ( reg , repo , dir , deps_str ) :
pat = re . compile ( reg )
found = re . search ( pat , deps_str )
if found is None :
return None
head = found . group ( 1 )
return textwrap . dedent ( '''
' %s ' :
( Var ( \" chromium_git \" )) + ' %s @ %s ' ,
''' ) % (dir, repo, head)
def get_host_platform ( ) :
2016-10-23 21:00:59 +02:00
if platform . system ( ) == ' Windows ' or ' CYGWIN_NT ' in platform . system ( ) :
2016-10-17 17:15:14 +02:00
host_platform = ' win '
2016-10-23 21:00:59 +02:00
elif platform . system ( ) == ' Linux ' :
2016-10-17 17:15:14 +02:00
host_platform = ' linux '
2016-10-23 21:00:59 +02:00
elif platform . system ( ) == ' Darwin ' :
2016-10-17 17:15:14 +02:00
host_platform = ' mac '
return host_platform
def get_host_architecture ( ) :
if re . match ( r ' i.86 ' , platform . machine ( ) ) :
host_arch = ' ia32 '
elif platform . machine ( ) == ' x86_64 ' or platform . machine ( ) == ' AMD64 ' :
host_arch = ' x64 '
elif platform . machine ( ) == ' aarch64 ' :
host_arch = ' arm64 '
elif platform . machine ( ) . startswith ( ' arm ' ) :
host_arch = ' arm '
else :
2016-10-28 18:23:40 +02:00
print_error ( ' Unexpected host machine architecture, exiting... ' )
2016-10-17 17:15:14 +02:00
sys . exit ( 1 )
return host_arch
2016-10-28 12:29:44 +02:00
2016-11-02 22:37:44 +01:00
def get_out_library_path ( host_platform ) :
2016-10-28 11:26:29 +02:00
if host_platform == ' win ' or ' CYGWIN_NT ' in platform . system ( ) :
2016-11-02 22:37:44 +01:00
out_library_path = os . path . join ( PATH_LIBRARY_OUT , ' ffmpeg.dll ' )
2016-10-28 11:26:29 +02:00
elif host_platform == ' linux ' :
2016-11-02 22:37:44 +01:00
out_library_path = os . path . join ( PATH_LIBRARY_OUT , ' lib ' , ' libffmpeg.so ' )
2016-10-28 11:26:29 +02:00
elif host_platform == ' mac ' :
2016-11-02 22:37:44 +01:00
out_library_path = os . path . join ( PATH_LIBRARY_OUT , ' libffmpeg.dylib ' )
2016-10-28 11:26:29 +02:00
2016-11-02 22:37:44 +01:00
return out_library_path
def get_platform_release_name ( host_platform ) :
if host_platform == ' mac ' :
platform_release_name = ' osx '
else :
platform_release_name = host_platform
return platform_release_name
2016-10-28 11:26:29 +02:00
2016-10-17 17:15:14 +02:00
def get_latest_stable_nwjs ( ) :
# We always build ffmpeg for the latest stable
2017-02-23 09:36:10 +01:00
nwjs_io_url = ' https://nwjs.io/versions.json '
2016-10-17 17:15:14 +02:00
try :
versions = json . load ( urllib2 . urlopen ( nwjs_io_url ) )
2016-12-03 16:07:52 +01:00
nw_version = versions [ ' stable ' ] [ 1 : ]
2016-10-17 17:15:14 +02:00
except URLError :
2016-11-02 22:43:59 +01:00
print_error ( ' Error fetching ' + nwjs_io_url + ' URL, please, set the desired NW.js version for building FFmepg using the argument -nw or --nw_version ' )
sys . exit ( 1 )
2016-10-17 17:15:14 +02:00
return nw_version
2016-10-28 11:26:29 +02:00
def create_directory ( directory ) :
print ' Creating {0} directory... ' . format ( directory )
2016-10-17 17:15:14 +02:00
try :
2016-10-28 11:26:29 +02:00
os . mkdir ( directory )
2016-10-17 17:15:14 +02:00
except OSError :
2016-10-28 18:23:40 +02:00
print_warning ( ' {0} directory already exists, skipping... ' . format ( directory ) )
2016-10-17 17:15:14 +02:00
def clean_output_directory ( ) :
2016-10-28 18:23:40 +02:00
print_info ( ' Cleaning output directory... ' )
2016-10-28 12:29:44 +02:00
shutil . rmtree ( PATH_OUT , ignore_errors = True )
2016-10-17 17:15:14 +02:00
2016-10-28 09:42:01 +02:00
def setup_chromium_depot_tools ( nw_version ) :
2016-10-28 12:29:44 +02:00
os . chdir ( PATH_BUILD )
if not os . path . isdir ( os . path . join ( PATH_DEPOT_TOOLS , ' .git ' ) ) :
2016-10-28 18:23:40 +02:00
print_info ( ' Cloning Chromium depot tools in {0} ... ' . format ( os . getcwd ( ) ) )
2016-10-17 17:15:14 +02:00
os . system ( ' git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git ' )
2016-10-28 12:29:44 +02:00
sys . path . append ( PATH_DEPOT_TOOLS )
2016-10-17 17:15:14 +02:00
# fix for gclient not found, seems like sys.path.append does not work but
# path is added
2016-10-28 12:29:44 +02:00
os . environ [ " PATH " ] + = os . pathsep + PATH_DEPOT_TOOLS
2016-10-17 17:15:14 +02:00
if platform . system ( ) == ' Windows ' or ' CYGWIN_NT ' in platform . system ( ) :
os . environ [ " DEPOT_TOOLS_WIN_TOOLCHAIN " ] = ' 0 '
2018-05-03 17:42:13 +02:00
os . environ [ " GYP_MSVS_VERSION " ] = ' 2017 '
2016-10-17 17:15:14 +02:00
2016-10-28 18:23:40 +02:00
print_info ( ' Creating .gclient file... ' )
2018-08-22 08:35:26 +02:00
subprocess . check_call ( ' gclient config --unmanaged --name=src https://github.com/nwjs/chromium.src.git@tags/nw-v {0} ' . format ( nw_version ) , shell = True )
2016-10-17 17:15:14 +02:00
2016-10-28 09:42:01 +02:00
def clone_chromium_source_code ( nw_version ) :
2016-10-28 12:29:44 +02:00
os . chdir ( PATH_BUILD )
2018-08-22 08:35:26 +02:00
print_info ( ' Cloning Chromium source code for nw- {0} in {1} ' . format ( nw_version , os . getcwd ( ) ) )
os . system ( ' git clone --depth=1 -b nw-v {0} --single-branch {1} src ' . format (
2016-10-17 17:15:14 +02:00
nw_version , ' https://github.com/nwjs/chromium.src.git ' ) )
2016-10-28 09:42:01 +02:00
def reset_chromium_src_to_nw_version ( nw_version ) :
2016-10-28 12:29:44 +02:00
os . chdir ( PATH_SRC )
2016-10-28 18:23:40 +02:00
print_info ( ' Hard source code reset to nw {0} specified version ' . format ( nw_version ) )
2018-08-22 08:35:26 +02:00
os . system ( ' git reset --hard tags/nw-v {0} ' . format ( nw_version ) )
2016-10-17 17:15:14 +02:00
def get_min_deps ( deps_str ) :
# deps
deps_list = {
2018-04-21 14:40:30 +02:00
' buildtools ' : {
2018-08-12 19:43:36 +02:00
' reg ' : ur " buildtools_revision ' : \ s* ' (.+) ' " ,
2018-04-21 14:40:30 +02:00
' repo ' : ' /chromium/buildtools.git ' ,
' path ' : ' src/buildtools '
} ,
2016-10-17 17:15:14 +02:00
' gyp ' : {
2018-08-12 19:43:36 +02:00
' reg ' : ur " gyp.git.+@ ' .+ ' (.+) ' " ,
2016-10-17 17:15:14 +02:00
' repo ' : ' /external/gyp.git ' ,
' path ' : ' src/tools/gyp '
} ,
' patched-yasm ' : {
2018-08-12 19:43:36 +02:00
' reg ' : ur " patched-yasm.git.+@ ' .+ ' (.+) ' " ,
2016-10-17 17:15:14 +02:00
' repo ' : ' /chromium/deps/yasm/patched-yasm.git ' ,
' path ' : ' src/third_party/yasm/source/patched-yasm '
} ,
' ffmpeg ' : {
2018-08-12 19:43:36 +02:00
' reg ' : ur " ffmpeg.git.+@ ' .+ ' (.+) ' " ,
2016-10-17 17:15:14 +02:00
' repo ' : ' /chromium/third_party/ffmpeg ' ,
' path ' : ' src/third_party/ffmpeg '
} ,
2018-04-21 14:40:30 +02:00
' angle ' : {
2018-08-12 19:43:36 +02:00
' reg ' : ur " angle_revision ' : \ s* ' (.+) ' " ,
2018-04-21 14:40:30 +02:00
' repo ' : ' /angle/angle.git ' ,
' path ' : ' src/third_party/angle '
} ,
2018-10-06 22:03:38 +02:00
' android_tools ' : {
' reg ' : ur " android_tools.git ' .* ' (.+) ' " ,
' repo ' : ' /android_tools.git ' ,
' path ' : ' src/third_party/android_tools '
}
2016-10-17 17:15:14 +02:00
}
min_deps_list = [ ]
for k , v in deps_list . items ( ) :
dep = grep_dep ( v [ ' reg ' ] , v [ ' repo ' ] , v [ ' path ' ] , deps_str )
if dep is None :
raise Exception ( " ` %s ` is not found in DEPS " % k )
min_deps_list . append ( dep )
return textwrap . dedent ( '''
deps = {
% s
}
''' ) % " \n " .join(min_deps_list)
2018-10-06 22:03:38 +02:00
def get_min_vars ( deps_str ) :
2016-10-17 17:15:14 +02:00
# vars
2018-10-06 22:03:38 +02:00
regex = r " (.+?)deps \ s+= "
matches = re . search ( regex , deps_str , re . MULTILINE | re . IGNORECASE | re . DOTALL )
return textwrap . dedent ( matches . group ( 1 ) )
2016-10-17 17:15:14 +02:00
def get_min_hooks ( ) :
# hooks
# copied from DEPS
return textwrap . dedent ( '''
hooks = [
{
' action ' : [
' python ' ,
' src/build/linux/sysroot_scripts/install-sysroot.py ' ,
2018-04-21 14:40:30 +02:00
' --arch=x86 '
] ,
' pattern ' :
' . ' ,
' name ' :
' sysroot_x86 ' ,
' condition ' :
' checkout_linux and (checkout_x86 or checkout_x64) '
} ,
{
' action ' : [
' python ' ,
' src/build/linux/sysroot_scripts/install-sysroot.py ' ,
' --arch=x64 '
2016-10-17 17:15:14 +02:00
] ,
' pattern ' :
' . ' ,
' name ' :
2018-04-21 14:40:30 +02:00
' sysroot_x64 ' ,
' condition ' :
' checkout_linux and checkout_x64 '
2016-10-17 17:15:14 +02:00
} ,
{
' action ' : [
' python ' ,
' src/build/mac_toolchain.py '
] ,
' pattern ' :
' . ' ,
' name ' :
2018-04-21 14:40:30 +02:00
' mac_toolchain ' ,
' condition ' :
' checkout_ios or checkout_mac '
2016-10-17 17:15:14 +02:00
} ,
{
' action ' : [
' python ' ,
' src/tools/clang/scripts/update.py ' ,
' --if-needed '
] ,
' pattern ' :
' . ' ,
' name ' :
' clang '
} ,
2018-08-22 09:15:52 +02:00
{
' action ' : [
' python ' ,
' src/chrome/android/profiles/update_afdo_profile.py '
] ,
2018-10-06 22:03:38 +02:00
' pattern ' : ' . ' ,
' condition ' : ' checkout_android or checkout_linux ' ,
' name ' : ' Fetch Android AFDO profile '
2018-08-22 09:15:52 +02:00
} ,
2016-10-17 17:15:14 +02:00
{
' action ' : [
' download_from_google_storage ' ,
' --no_resume ' ,
' --no_auth ' ,
' --bucket ' ,
' chromium-gn ' ,
' -s ' ,
' src/buildtools/win/gn.exe.sha1 '
] ,
' pattern ' :
' . ' ,
' name ' :
2018-04-21 14:40:30 +02:00
' gn_win ' ,
' condition ' :
' host_os == " win " '
2016-10-17 17:15:14 +02:00
} ,
{
' action ' : [
' download_from_google_storage ' ,
' --no_resume ' ,
' --no_auth ' ,
' --bucket ' ,
' chromium-gn ' ,
' -s ' ,
' src/buildtools/mac/gn.sha1 '
] ,
' pattern ' :
' . ' ,
' name ' :
2018-04-21 14:40:30 +02:00
' gn_mac ' ,
' condition ' :
' host_os == " mac " '
2016-10-17 17:15:14 +02:00
} ,
{
' action ' : [
' download_from_google_storage ' ,
' --no_resume ' ,
' --no_auth ' ,
' --bucket ' ,
' chromium-gn ' ,
' -s ' ,
' src/buildtools/linux64/gn.sha1 '
] ,
' pattern ' :
' . ' ,
' name ' :
2018-04-21 14:40:30 +02:00
' gn_linux64 ' ,
' condition ' :
' host_os == " linux " '
2016-10-17 17:15:14 +02:00
} ,
]
2018-01-31 13:47:00 +01:00
recursedeps = [
' src/buildtools '
]
2016-10-17 17:15:14 +02:00
''' )
def install_build_deps ( ) :
2016-10-28 12:29:44 +02:00
os . chdir ( PATH_SRC_BUILD )
2016-10-17 17:15:14 +02:00
if platform . system ( ) == ' Linux ' and not os . path . isfile ( ' buid_deps.ok ' ) :
2016-10-28 18:23:40 +02:00
print_info ( ' Installing build dependencies... ' )
2016-10-28 12:29:44 +02:00
os . system ( ' ./install-build-deps.sh --no-prompt --no-nacl --no-chromeos-fonts --no-syms ' )
2016-10-17 17:15:14 +02:00
with io . FileIO ( ' buid_deps.ok ' , ' w ' ) as file :
file . write ( ' Build dependencies already installed ' )
2016-10-28 12:29:44 +02:00
def gclient_sync ( ) :
os . chdir ( PATH_SRC )
2016-10-28 18:23:40 +02:00
print_info ( ' Syncing with gclient... ' )
2016-10-28 12:29:44 +02:00
os . system ( ' gclient sync --no-history ' )
def build ( target_cpu ) :
os . chdir ( PATH_SRC )
2016-10-28 18:23:40 +02:00
print_info ( ' Generating ninja files... ' )
2016-10-28 12:29:44 +02:00
subprocess . check_call ( ' gn gen //out/nw " --args=is_debug=false is_component_ffmpeg=true target_cpu= \\ \" %s \\ \" is_official_build=true ffmpeg_branding= \\ \" Chrome \\ \" " ' % target_cpu , shell = True )
2016-10-28 18:23:40 +02:00
print_info ( ' Starting ninja for building ffmpeg... ' )
2016-10-28 12:29:44 +02:00
subprocess . check_call ( ' ninja -C out/nw ffmpeg ' , shell = True )
2016-10-17 17:15:14 +02:00
def delete_file ( file_name ) :
if os . path . exists ( file_name ) :
try :
os . remove ( file_name )
except OSError as e :
2016-10-28 18:23:40 +02:00
print_error ( " %s - %s . " % ( e . filename , e . strerror ) )
2016-10-17 17:15:14 +02:00
def generate_build_and_deps_files ( ) :
2016-10-28 12:29:44 +02:00
os . chdir ( PATH_SRC )
2016-10-28 18:23:40 +02:00
print_info ( ' Cleaning previous DEPS and BUILD.gn backup files... ' )
2016-10-17 17:15:14 +02:00
delete_file ( " DEPS.bak " )
delete_file ( " BUILD.gn.bak " )
with open ( ' DEPS ' , ' r ' ) as f :
deps_str = f . read ( )
2016-10-28 18:23:40 +02:00
print_info ( ' Backing up and overwriting DEPS... ' )
2016-10-17 17:15:14 +02:00
shutil . move ( ' DEPS ' , ' DEPS.bak ' )
with open ( ' DEPS ' , ' w ' ) as f :
2018-10-06 22:03:38 +02:00
f . write ( " %s \n %s \n %s " % ( get_min_vars ( deps_str ) , get_min_deps ( deps_str ) , get_min_hooks ( ) ) )
2016-10-17 17:15:14 +02:00
2016-10-28 18:23:40 +02:00
print_info ( ' Backing up and overwriting BUILD.gn... ' )
2016-10-17 17:15:14 +02:00
shutil . move ( ' BUILD.gn ' , ' BUILD.gn.bak ' )
BUILD_gn = textwrap . dedent ( '''
group ( " dummy " ) {
deps = [
" //third_party/ffmpeg "
]
}
''' )
with open ( ' BUILD.gn ' , ' w ' ) as f :
f . write ( BUILD_gn )
2016-10-24 09:27:37 +02:00
def cygwin_linking_setup ( ) :
if ' CYGWIN_NT ' in platform . system ( ) :
if os . path . isfile ( ' /usr/bin/link.exe ' ) :
2016-10-28 18:23:40 +02:00
print_info ( ' Overriding CygWin linker with MSVC linker... ' )
2016-10-24 09:27:37 +02:00
shutil . move ( ' /usr/bin/link.exe ' , ' /usr/bin/link.exe.1 ' )
if not os . path . isfile ( ' /usr/local/bin/cygwin-wrapper ' ) :
2016-10-28 18:23:40 +02:00
print_info ( ' Copying Cygwin wrapper... ' )
2016-10-24 09:27:37 +02:00
shutil . copy ( os . getcwd ( ) + ' /chromium/scripts/cygwin-wrapper ' , ' /usr/local/bin/cygwin-wrapper ' )
2016-10-28 09:42:01 +02:00
def check_build_with_proprietary_codecs ( proprietary_codecs , host_platform , target_arch ) :
2016-10-17 17:15:14 +02:00
# going to ffmpeg folder
2016-10-28 12:29:44 +02:00
os . chdir ( PATH_THIRD_PARTY_FFMPEG )
2016-10-11 12:29:48 +02:00
2016-10-17 18:40:44 +02:00
if proprietary_codecs :
2016-10-28 18:23:40 +02:00
print_info ( ' Building ffmpeg with proprietary codecs... ' )
2016-10-24 17:40:43 +02:00
if not os . path . isfile ( ' build_ffmpeg_proprietary_codecs.patch ' ) :
2016-10-28 18:23:40 +02:00
print_info ( ' Applying codecs patch with ac3 for {0} ... ' . format ( host_platform ) )
2016-10-28 12:29:44 +02:00
# os.path.join
shutil . copy ( os . path . join ( PATH_BASE , ' patch ' , host_platform , ' build_ffmpeg_proprietary_codecs.patch ' ) , os . getcwd ( ) )
2016-10-17 18:40:44 +02:00
# apply codecs patch
os . system ( ' git apply --ignore-space-change --ignore-whitespace build_ffmpeg_proprietary_codecs.patch ' )
2016-10-24 09:27:37 +02:00
cygwin_linking_setup ( )
2016-10-21 20:28:18 +02:00
2016-10-28 18:23:40 +02:00
print_info ( ' Starting build... ' )
2016-10-21 20:28:18 +02:00
2016-10-17 18:40:44 +02:00
# build ffmpeg
subprocess . check_call ( ' ./chromium/scripts/build_ffmpeg.py {0} {1} ' . format ( host_platform , target_arch ) , shell = True )
# copy the new generated ffmpeg config
2016-10-28 18:23:40 +02:00
print_info ( ' Copying new ffmpeg configuration... ' )
2016-10-17 18:40:44 +02:00
subprocess . call ( ' ./chromium/scripts/copy_config.sh ' , shell = True )
2016-10-28 18:23:40 +02:00
print_info ( ' Creating a GYP include file for building FFmpeg from source... ' )
2016-10-17 18:40:44 +02:00
# generate the ffmpeg configuration
2016-12-04 11:18:46 +01:00
subprocess . check_call ( ' ./chromium/scripts/generate_gn.py ' , shell = True )
2016-10-23 21:06:47 +02:00
2016-10-24 09:16:49 +02:00
if ' CYGWIN_NT ' in platform . system ( ) :
2016-10-28 18:23:40 +02:00
print_info ( ' Applying fix for error LNK2001: unresolved external symbol _ff_w64_guid_data ' )
2016-10-23 21:06:47 +02:00
fix_external_symbol_ff_w64_guid_data ( )
2016-10-17 18:40:44 +02:00
else :
2016-10-24 17:40:43 +02:00
if os . path . isfile ( ' build_ffmpeg_proprietary_codecs.patch ' ) :
2016-10-28 18:23:40 +02:00
print_info ( ' Restoring ffmpeg configuration to defaults... ' )
2016-10-17 18:40:44 +02:00
os . system ( ' git clean -df ' )
os . system ( ' git checkout -- . ' )
2016-10-11 12:29:48 +02:00
2016-10-17 17:15:14 +02:00
2016-10-21 20:28:18 +02:00
def replace_in_file ( file_name , search_string , replace_string ) :
filedata = None
with open ( file_name , ' r ' ) as file :
filedata = file . read ( )
filedata = filedata . replace ( search_string , replace_string )
with open ( file_name , ' w ' ) as file :
file . write ( filedata )
def fix_external_symbol_ff_w64_guid_data ( ) :
# https://bugs.chromium.org/p/chromium/issues/detail?id=264459
shutil . copyfile ( ' ffmpeg_generated.gni ' , ' ffmpeg_generated.gni.bak ' )
replace = ''' " libavformat/vorbiscomment.c " ,
" libavformat/w64.c " , '''
replace_in_file ( ' ffmpeg_generated.gni ' , ' " libavformat/vorbiscomment.c " , ' , replace )
2016-10-17 18:40:44 +02:00
2016-12-19 14:13:36 +01:00
def zip_release_output_library ( nw_version , platform_release_name , target_arch , proprietary_codecs , out_library_path , output_release_path ) :
2016-10-28 12:29:44 +02:00
create_directory ( output_release_path )
2016-10-28 18:23:40 +02:00
print_info ( ' Creating release zip... ' )
2016-12-19 14:13:36 +01:00
pc = ' '
if proprietary_codecs :
pc = ' -custom '
2016-11-02 22:37:44 +01:00
if os . path . isfile ( out_library_path ) :
2016-12-19 14:13:36 +01:00
with zipfile . ZipFile ( os . path . join ( output_release_path , ' {0} - {1} - {2} {3} .zip ' . format ( nw_version , platform_release_name , target_arch , pc ) ) , ' w ' , zipfile . ZIP_DEFLATED ) as release_zip :
2016-11-02 22:37:44 +01:00
release_zip . write ( out_library_path , os . path . basename ( out_library_path ) )
2016-10-28 11:26:29 +02:00
release_zip . close ( )
else :
2016-11-02 22:37:44 +01:00
print_warning ( ' There is no release file library in {0} ... ' . format ( out_library_path ) )
2016-10-28 18:23:40 +02:00
#following from Python cookbook, #475186
def has_colours ( stream ) :
if not hasattr ( stream , " isatty " ) :
return False
if not stream . isatty ( ) :
return False # auto color only on TTYs
try :
import curses
curses . setupterm ( )
return curses . tigetnum ( " colors " ) > 2
except :
# guess false in case of error
return False
def print_message ( color , message_type , message ) :
if has_colours ( sys . stdout ) :
print ( color + message_type + COLOR_NORMAL + message )
2017-04-05 12:38:06 +02:00
elif get_host_platform ( ) == " win " :
2016-10-28 18:23:40 +02:00
if color == COLOR_OK :
windows_color = COLOR_OK_WINDOWS
elif color == COLOR_ERROR :
windows_color = COLOR_ERROR_WINDOWS
elif color == COLOR_INFO :
windows_color = COLOR_INFO_WINDOWS
elif color == COLOR_WARNING :
windows_color = COLOR_WARNING_WINDOWS
print_windows_message ( windows_color , message_type + message )
2017-04-05 12:38:06 +02:00
else :
print ( message_type + message )
2016-10-28 18:23:40 +02:00
def print_windows_message ( colour , message ) :
import ctypes
ctypes . windll . Kernel32 . GetStdHandle . restype = ctypes . c_ulong
h = ctypes . windll . Kernel32 . GetStdHandle ( ctypes . c_ulong ( 0xfffffff5 ) )
def colorize ( colour ) :
ctypes . windll . Kernel32 . SetConsoleTextAttribute ( h , colour )
colorize ( colour )
print message
colorize ( COLOR_NORMAL_WINDOWS )
def print_ok ( message ) :
print_message ( COLOR_OK , message , ' ' )
def print_error ( message ) :
print_message ( COLOR_ERROR , ' ERROR: ' , message )
def print_info ( message ) :
print_message ( COLOR_INFO , ' INFO: ' , message )
def print_warning ( message ) :
print_message ( COLOR_WARNING , ' WARNING: ' , message )
2016-10-28 11:26:29 +02:00
2016-10-18 09:58:35 +02:00
if __name__ == ' __main__ ' :
sys . exit ( main ( ) )