# Copyright 2014 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. import("ffmpeg_generated.gni") import("ffmpeg_options.gni") import("//build/buildflag_header.gni") import("//build/config/compiler/compiler.gni") import("//build/config/sanitizers/sanitizers.gni") # Path to platform configuration files. platform_config_root = "chromium/config/$ffmpeg_branding/$os_config/$ffmpeg_arch" has_nasm_deps = ffmpeg_asm_sources != [] && (current_cpu == "x86" || current_cpu == "x64") && os_config != "linux-noasm" if (has_nasm_deps) { import("//third_party/nasm/nasm_assemble.gni") # x86inc.asm ignores the PIC flag when compiling for x86 which unfortunately # causes text relocations in the object files generated by the assembler. We # must disable the warning to allow linking with lld. Unlike gold, ld which # will silently allow text relocations, lld support must be explicit. # # See https://crbug.com/911658#c19 for more information. Tracked upstream at # https://trac.ffmpeg.org/ticket/7878 config("fix_textrels") { ldflags = [ "-Wl,-z,notext" ] } nasm_assemble("ffmpeg_nasm") { sources = ffmpeg_asm_sources # Ensure the architecture defines go in the command line before the -P # file below, so don't use defines. nasm_flags = [] if (current_cpu == "x86") { nasm_flags += [ "-DARCH_X86_32" ] } else if (current_cpu == "x64") { nasm_flags += [ "-DARCH_X86_64" ] } inputs = [ # Sets visibility hidden for cglobal functions. Explicitly included # to avoid overlooking changes to this file in incremental builds. "libavutil/x86/x86inc.asm", ] defines = [ "PIC" ] include_dirs = [ platform_config_root, "libavcodec/x86", "libavutil/x86", ".", ] nasm_flags += [ "-W+error=all", "-P" + rebase_path("$platform_config_root/config.asm", root_build_dir), ] if (is_mac) { # Necessary to ensure symbols end up with a _ prefix; added by # yasm_assemble.gni for Windows, but not Mac. defines += [ "PREFIX" ] } # See comments on fix_textrels config. if (use_lld && current_cpu == "x86" && !is_win) { all_dependent_configs = [ ":fix_textrels" ] } } } config("ffmpeg_dependent_config") { include_dirs = [ platform_config_root, ".", ] } if (is_win) { # Stub generator script and signatures of all functions used by Chrome. generate_stubs_script = "//tools/generate_stubs/generate_stubs.py" # Used by ffmpeg_generate_stubs and ffmpeg_generate_def sig_files = [ "chromium/ffmpeg.sigs" ] action("ffmpeg_generate_def") { script = generate_stubs_script sources = sig_files outputs = [ "$target_gen_dir/ffmpeg.def", ] args = [ "-i", rebase_path(target_out_dir, root_build_dir), "-o", rebase_path(target_gen_dir, root_build_dir), "-t", "windows_def", "-m", "ffmpeg.dll", ] + rebase_path(sources, root_build_dir) } } # gn orders flags on a target before flags from configs. The default config # adds -Wall, and these flags have to be after -Wall -- so they need to come # from a config and can't be on the target directly. config("ffmpeg_warnings") { if (is_clang) { cflags = [ "-Wno-absolute-value", # ffmpeg uses its own deprecated functions. "-Wno-deprecated-declarations", # ffmpeg doesn't care about pointer constness. "-Wno-incompatible-pointer-types", # ffmpeg doesn't follow usual parentheses conventions. "-Wno-logical-op-parentheses", # ffmpeg doesn't care about pointer signedness. "-Wno-parentheses", # ffmpeg doesn't care about pointer signedness. "-Wno-pointer-sign", # ffmpeg doesn't believe in exhaustive switch statements. "-Wno-switch", # matroskadec.c has a "failed:" label that's only used if some # CONFIG_ flags we don't set are set. "-Wno-unused-label", # ffmpeg has a lot of unused variables. "-Wno-unused-variable", # This fires on `av_assert0(!"valid element size")` in utils.c "-Wno-string-conversion", # This fires on `pos_min` and `pos_max` in # autorename_libavformat_utils.c "-Wno-sometimes-uninitialized", # clock_gettime is marked as 10.12+ in the 10.12 SDK, but ffmpeg does # correctly check for that before calling. "-Wno-unguarded-availability", # ffmpeg contains static functions in header files, which lead # to unused function warnings. There are a few legit unused # functions too. "-Wno-unused-function", # vp3data.h's vp31_inter_dequant stores '128' in an int8_t array. "-Wno-constant-conversion", # utils.c does # `return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;` # while -Wstring-plus-int wants &FFMPEG_LICENSE[sizeof(LICENSE_PREFIX)-1] "-Wno-string-plus-int", ] if (target_cpu == "arm" || target_cpu == "arm64") { # ffmpeg uses ARM instructions that clang deems deprecated. cflags += [ "-Wno-inline-asm" ] } if (is_win) { # This corresponds to /wd4273 below. cflags += [ "-Wno-inconsistent-dllimport" ] } } } buildflag_header("ffmpeg_features") { header = "ffmpeg_features.h" flags = [ "USE_SYSTEM_FFMPEG=false" ] } if (is_component_ffmpeg) { link_target_type = "source_set" } else { # This must be a static_library in non-component builds to avoid pulling # in many large global arrays (and associated code) into chrome.dll. link_target_type = "static_library" } target(link_target_type, "ffmpeg_internal") { sources = ffmpeg_c_sources + ffmpeg_gas_sources + [ "$platform_config_root/config.h", "$platform_config_root/libavutil/avconfig.h", ] include_dirs = [ platform_config_root, ".", ] defines = [ "HAVE_AV_CONFIG_H", "_POSIX_C_SOURCE=200112", "_XOPEN_SOURCE=600", "PIC", "FFMPEG_CONFIGURATION=NULL", ] if (is_component_ffmpeg) { configs += [ "//build/config/sanitizers:cfi_icall_disable" ] } # Disable internal ffmpeg logs in the official build; this saves ~158kb. if (is_official_build) { defines += [ "CHROMIUM_NO_LOGGING" ] } # So we can append below and assume they're defined. cflags = [] ldflags = [] libs = [] deps = [ ":ffmpeg_features", "//third_party/opus", ] configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code", # These must be after no_chromium_code for warning flags to be ordered # correctly. "//build/config/compiler:no_incompatible_pointer_warnings", ":ffmpeg_warnings", ] # Since we are not often debugging FFmpeg, and performance is # unacceptable without optimization, freeze the optimizations to -O2. # If someone really wants -O1 , they can change these in their checkout. # If you want -O0, see the Gotchas in README.Chromium for why that # won't work. # # In addition to the above reasons, /Od optimization won't remove symbols # that are under "if (0)" style sections. Which lead to link time errors # when for example it tries to link an ARM symbol on X86. configs -= [ "//build/config/compiler:default_optimization" ] configs += [ "//build/config/compiler:optimize_max" ] if (ffmpeg_use_atomics_fallback) { if (is_posix || is_fuchsia) { include_dirs += [ "compat/atomics/gcc" ] } else if (is_win) { include_dirs += [ "compat/atomics/win32" ] } } # On x86, sanitizers will fail to compiler the H264 CABAC code due to # insufficient registers unless we disable EBP usage. https://crbug.com/786760 # # Windows builds can't compile without EBP because we can't omit frame # pointers like we do on posix. if (current_cpu == "x86") { if (using_sanitizer || is_win || use_lld) { defines += [ "HAVE_EBP_AVAILABLE=0" ] } else { defines += [ "HAVE_EBP_AVAILABLE=1" ] } # Despite the name, this isn't fixing any bugs with the linker. It's just # preventing ffmpeg from silently emitting text relocations. See discussion # https://crbug.com/911658#c19 and https://trac.ffmpeg.org/ticket/7878 if (use_lld && !is_win) { defines += [ "BROKEN_RELOCATIONS=1" ] } } if (is_fuchsia || is_posix) { cflags += [ "-fPIC", # ffmpeg uses its own deprecated functions. "-Wno-deprecated-declarations", ] if (!(is_android && use_call_graph)) { # Remove default stack frames config so we can force -fomit-frame-pointer. configs -= [ "//build/config/compiler:default_stack_frames" ] cflags += [ "-fomit-frame-pointer", ] } if (!is_clang) { # gcc doesn't have flags for specific warnings, so disable them # all. cflags += [ "-w" ] } if (current_cpu == "arm" || current_cpu == "arm64") { asmflags = [] if (arm_float_abi == "hard") { asmflags += [ "-DHAVE_VFP_ARGS=1" ] } else { asmflags += [ "-DHAVE_VFP_ARGS=0" ] } } } if (is_fuchsia || (is_posix && !is_mac)) { defines += [ "_ISOC99_SOURCE", "_LARGEFILE_SOURCE", ] cflags += [ "-std=c99", "-pthread", "-fno-math-errno", "-fno-signed-zeros", "-fno-tree-vectorize", ] ldflags = [ "-L", rebase_path(target_gen_dir, root_build_dir), ] if (!is_android && !is_fuchsia) { # OS=android requires that both -lz and -lm occur after # -lc++_shared on the link command line. Android link rules # already include -lm, and we get -lz as a transitive dependency # of libandroid.so, so simply moving both to the non-Android # section solves the problem. # # The root cause of this problem is certain system libraries # (libm starting with MNC and libz before MNC, among others) # re-export the libgcc unwinder, and libc++ exports the # libc++abi unwinder. As we build against libc++ headers, libc++ # must be the first in the runtime symbol lookup order (among # all unwinder-providing libraries). # librt for clock_gettime on precise libs += [ "m", "z", "rt", ] } if (is_component_ffmpeg) { # Export all symbols when building as component. configs -= [ "//build/config/gcc:symbol_visibility_hidden" ] configs += [ "//build/config/gcc:symbol_visibility_default" ] } } if (is_mac) { if (is_component_ffmpeg) { # Export all symbols when building as component. configs -= [ "//build/config/gcc:symbol_visibility_hidden" ] configs += [ "//build/config/gcc:symbol_visibility_default" ] } defines += [ "_DARWIN_C_SOURCE" ] } else if (is_win) { defines += [ "_ISOC99_SOURCE", "_LARGEFILE_SOURCE", "HAVE_AV_CONFIG_H", ] if (is_component_ffmpeg) { # Required to avoid 4049 and 4217 errors around redundant imports. cflags += [ "/FIcompat/msvcrt/snprintf.h", "/FIcompat/msvcrt/strtod.h", ] } # TODO(dalecurtis): We should fix these. http://crbug.com/154421 cflags += [ "/wd4996", # 'function': was declared deprecated "/wd4018", # 'expression': signed/unsigned mismatch "/wd4090", # 'operation' : different 'modifier' qualifiers "/wd4305", # 'identifier': truncation from 'type1' to 'type2' "/wd4133", # 'type' : incompatible types - from 'type1' to 'type2' "/wd4146", # unary minus operator applied to unsigned type, result # still unsigned "/wd4554", # 'operator' : check operator precedence for possible # error; use parentheses to clarify precedence "/wd4028", # formal parameter 'number' different from declaration "/wd4334", # 'operator' : result of 32-bit shift implicitly # converted to 64 bits (was 64-bit shift intended?) "/wd4101", # 'identifier' : unreferenced local variable "/wd4102", # 'label' : unreferenced label "/wd4116", # unnamed type definition in parentheses "/wd4307", # 'operator' : integral constant overflow "/wd4273", # 'function' : inconsistent DLL linkage "/wd4005", # 'identifier' : macro redefinition "/wd4056", # overflow in floating point constant arithmetic "/wd4756", # overflow in constant arithmetic ] if (current_cpu == "x64") { # TODO(wolenetz): We should fix this. http://crbug.com/171009 cflags += [ "/wd4267" ] # Conversion from size_t to 'type'. } } if (has_nasm_deps) { deps += [ ":ffmpeg_nasm" ] } } if (is_component_ffmpeg) { shared_library("ffmpeg") { if (is_android) { configs -= [ "//build/config/android:hide_all_but_jni_onload" ] } public_configs = [ ":ffmpeg_dependent_config" ] deps = [ ":ffmpeg_internal", ] # So we can append below and assume they're defined. ldflags = [] if (is_fuchsia || (is_posix && !is_mac)) { # Fixes warnings PIC relocation when building as component. ldflags += [ "-Wl,-Bsymbolic", "-L", rebase_path(target_gen_dir, root_build_dir), ] } else if (is_win) { # Windows component build needs the .def file to export ffmpeg symbols. deps += [ ":ffmpeg_generate_def" ] sources = [ "$target_gen_dir/ffmpeg.def", ] } if (is_mac && !is_component_build) { ldflags += [ "-Wl,-install_name,@rpath/libffmpeg.dylib" ] } } } else { source_set("ffmpeg") { public_configs = [ ":ffmpeg_dependent_config" ] deps = [ ":ffmpeg_internal", ] } }