| #!/usr/bin/python |
| # |
| # Copyright 2019 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Creates config files for building dav1d.""" |
| |
| from __future__ import print_function |
| |
| import os |
| import re |
| import shutil |
| import subprocess |
| import sys |
| import tempfile |
| |
| BASE_DIR = os.path.abspath(os.path.dirname(__file__)) |
| CHROMIUM_ROOT_DIR = os.path.abspath(os.path.join(BASE_DIR, '..', '..')) |
| |
| sys.path.append(os.path.join(CHROMIUM_ROOT_DIR, 'build')) |
| import gn_helpers |
| |
| MESON = ['meson.py'] |
| |
| DEFAULT_BUILD_ARGS = [ |
| '-Dbuild_tools=false', '-Dbuild_tests=false', '--buildtype', 'release' |
| ] |
| |
| WINDOWS_BUILD_ARGS = ['-Dc_winlibs='] |
| |
| |
| def PrintAndCheckCall(argv, *args, **kwargs): |
| print('\n-------------------------------------------------\nRunning %s' % |
| ' '.join(argv)) |
| c = subprocess.check_call(argv, *args, **kwargs) |
| |
| |
| def RewriteFile(path, search_replace): |
| with open(path) as f: |
| contents = f.read() |
| with open(path, 'w') as f: |
| for search, replace in search_replace: |
| contents = re.sub(search, replace, contents) |
| f.write(contents) |
| |
| |
| def SetupWindowsCrossCompileToolchain(target_arch): |
| # First retrieve various MSVC and Windows SDK paths. |
| output = subprocess.check_output([ |
| os.path.join(CHROMIUM_ROOT_DIR, 'build', 'vs_toolchain.py'), |
| 'get_toolchain_dir' |
| ]) |
| |
| # Turn this into a dictionary. |
| win_dirs = gn_helpers.FromGNArgs(output) |
| |
| # Use those paths with a second script which will tell us the proper include |
| # and lib paths to specify for cflags and ldflags respectively. |
| output = subprocess.check_output([ |
| 'python', |
| os.path.join(CHROMIUM_ROOT_DIR, 'build', 'toolchain', 'win', |
| 'setup_toolchain.py'), win_dirs['vs_path'], |
| win_dirs['sdk_path'], win_dirs['runtime_dirs'], 'win', target_arch, 'none' |
| ]) |
| |
| flags = gn_helpers.FromGNArgs(output) |
| cwd = os.getcwd() |
| |
| target_env = os.environ |
| |
| include_paths = [] |
| for cflag in flags['include_flags_imsvc'].split(' '): |
| # Apparently setup_toolchain prefers relative include paths, which |
| # may work for chrome, but it does not work for ffmpeg, so let's make |
| # them asbolute again. |
| include_path = cflag.strip('"') |
| if include_path.startswith('-imsvc'): |
| include_path = os.path.abspath(os.path.join(cwd, include_path[6:])) |
| include_paths.append(include_path) |
| |
| # TODO(dalecurtis): Why isn't the ucrt path printed? |
| flags['vc_lib_ucrt_path'] = flags['vc_lib_um_path'].replace('/um/', '/ucrt/') |
| |
| # Unlike the cflags, the lib include paths are each in a separate variable. |
| lib_paths = [] |
| for k in flags: |
| # libpath_flags is like cflags. Since it is also redundant, skip it. |
| if 'lib' in k and k != 'libpath_flags': |
| lib_paths.append(flags[k]) |
| |
| target_env = os.environ |
| target_env['INCLUDE'] = ';'.join(include_paths) |
| target_env['LIB'] = ';'.join(lib_paths) |
| return target_env |
| |
| |
| def CopyConfigsAndCleanup(config_dir, dest_dir): |
| if not os.path.exists(dest_dir): |
| os.makedirs(dest_dir) |
| |
| shutil.copy(os.path.join(config_dir, 'config.h'), dest_dir) |
| |
| # The .asm file will not be present for all configurations. |
| asm_file = os.path.join(config_dir, 'config.asm') |
| if os.path.exists(asm_file): |
| shutil.copy(asm_file, dest_dir) |
| |
| shutil.rmtree(config_dir) |
| |
| |
| def GenerateConfig(config_dir, env, special_args=[]): |
| temp_dir = tempfile.mkdtemp() |
| PrintAndCheckCall( |
| MESON + DEFAULT_BUILD_ARGS + special_args + [temp_dir], |
| cwd='libdav1d', |
| env=env) |
| |
| # We don't want non-visible log strings polluting the official binary. |
| RewriteFile( |
| os.path.join(temp_dir, 'config.h'), |
| [(r'(#define CONFIG_LOG .*)', |
| r'// \1 -- Logging is controlled by Chromium')]) |
| |
| # Clang LTO doesn't respect stack alignment, so we must use the platform's |
| # default stack alignment in that case; https://crbug.com/928743. |
| RewriteFile( |
| os.path.join(temp_dir, 'config.h'), |
| [(r'(#define STACK_ALIGNMENT \d{1,2})', |
| r'// \1 -- Stack alignment is controlled by Chromium')]) |
| if (os.path.exists(os.path.join(config_dir, 'config.asm'))): |
| RewriteFile( |
| os.path.join(temp_dir, 'config.asm'), |
| [(r'(%define STACK_ALIGNMENT \d{1,2})', |
| r'; \1 -- Stack alignment is controlled by Chromium')]) |
| |
| CopyConfigsAndCleanup(temp_dir, config_dir) |
| |
| |
| def main(): |
| linux_env = os.environ |
| linux_env['CC'] = 'clang' |
| |
| GenerateConfig('config/linux/x64', linux_env) |
| GenerateConfig('config/linux/x86', linux_env, |
| ['--cross-file', '../crossfiles/linux32.crossfile']) |
| GenerateConfig('config/linux-noasm/x64', linux_env, ['-Dbuild_asm=false']) |
| |
| win_x86_env = SetupWindowsCrossCompileToolchain('x86') |
| GenerateConfig( |
| 'config/win/x86', win_x86_env, |
| ['--cross-file', '../crossfiles/win32.crossfile'] + WINDOWS_BUILD_ARGS) |
| |
| win_x64_env = SetupWindowsCrossCompileToolchain('x64') |
| GenerateConfig( |
| 'config/win/x64', win_x64_env, |
| ['--cross-file', '../crossfiles/win64.crossfile'] + WINDOWS_BUILD_ARGS) |
| |
| |
| if __name__ == '__main__': |
| main() |