Merge "Cmake refactor."
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ad7bea4..f6a2dd6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,173 +8,29 @@
 cmake_minimum_required(VERSION 3.2)
 project(LIBWEBM CXX)
 
+include("${CMAKE_CURRENT_SOURCE_DIR}/build/cxx_flags.cmake")
 include("${CMAKE_CURRENT_SOURCE_DIR}/build/msvc_runtime.cmake")
 
 set(LIBWEBM_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
 
-# Build/test configuration flags. Defined here for visibility.
+# Build/test configuration flags.
 option(ENABLE_WEBMTS "Enables WebM PES/TS support." ON)
 option(ENABLE_WEBMINFO "Enables building webm_info." ON)
 option(ENABLE_TESTS "Enables tests." OFF)
 option(ENABLE_IWYU "Enables include-what-you-use support." OFF)
 option(ENABLE_WERROR "Enable warnings as errors." OFF)
 option(ENABLE_WEBM_PARSER "Enables new parser API." OFF)
-set(GTEST_SRC_DIR "${LIBWEBM_SRC_DIR}/../googletest" CACHE PATH
-    "Path to Googletest git repository.")
 
-# This directory is where libwebm will build googletest dependencies.
-set(GTEST_BUILD_DIR "${CMAKE_BINARY_DIR}/googletest_build")
-
-include("${CMAKE_CURRENT_SOURCE_DIR}/build/cxx_flags.cmake")
 if (ENABLE_TESTS OR ENABLE_WEBMTS OR ENABLE_WEBMINFO OR ENABLE_WEBM_PARSER)
-  include("${CMAKE_CURRENT_SOURCE_DIR}/build/cxx11_tests.cmake")
-
-  if (NOT HAVE_CXX11)
-    message(WARNING
-            "C++11 feature(s) not supported: tests, webmts and "
-            "webm_parser disabled.")
-    set(ENABLE_TESTS OFF)
-    set(ENABLE_WEBMTS OFF)
-    set(ENABLE_WEBM_PARSER OFF)
-  endif ()
+  require_cxx_flag_nomsvc("-std=c++11")
 endif ()
 
-set(CMAKE_CXX_FLAGS "-D__STDC_CONSTANT_MACROS ${CMAKE_CXX_FLAGS}")
-set(CMAKE_CXX_FLAGS "-D__STDC_FORMAT_MACROS ${CMAKE_CXX_FLAGS}")
-set(CMAKE_CXX_FLAGS "-D__STDC_LIMIT_MACROS ${CMAKE_CXX_FLAGS}")
+add_cxx_preproc_definition("__STDC_CONSTANT_MACROS")
+add_cxx_preproc_definition("__STDC_FORMAT_MACROS")
+add_cxx_preproc_definition("__STDC_LIMIT_MACROS")
 
-# mkvmuxer section.
-# TODO(tomfinegan): move to mkvmuxer/CMakeLists.txt
-add_library(mkvmuxer STATIC
-            "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxer.cc"
-            "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxer.h"
-            "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxertypes.h"
-            "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxerutil.cc"
-            "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxerutil.h"
-            "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvwriter.cc"
-            "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvwriter.h"
-            "${LIBWEBM_SRC_DIR}/common/webmids.h")
-
-# mkvparser section.
-# TODO(tomfinegan): move to mkvparser/CMakeLists.txt.
-add_library(mkvparser STATIC
-            "${LIBWEBM_SRC_DIR}/mkvparser/mkvparser.cc"
-            "${LIBWEBM_SRC_DIR}/mkvparser/mkvparser.h"
-            "${LIBWEBM_SRC_DIR}/mkvparser/mkvreader.cc"
-            "${LIBWEBM_SRC_DIR}/mkvparser/mkvreader.h"
-            "${LIBWEBM_SRC_DIR}/common/webmids.h")
-
-
-# webm_parser section.
-# TODO(tomfinegan): move to webm_parser/CMakeLists.txt.
-# TODO(tomfinegan): add fuzzing target.
-# TODO(tomfinegan): add doxygen generation target.
-if (ENABLE_WEBM_PARSER)
-include_directories(webm_parser webm_parser/include)
-add_library(webm_parser STATIC
-            "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/buffer_reader.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/callback.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/dom_types.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/element.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/file_reader.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/id.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/istream_reader.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/reader.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/status.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/webm_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/ancestory.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/ancestory.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/audio_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/bit_utils.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/bit_utils.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/block_additions_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/block_group_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/block_header_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/block_header_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/block_more_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/block_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/block_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/bool_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/buffer_reader.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/byte_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/callback.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/chapter_atom_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/chapter_display_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/chapters_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/cluster_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/colour_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/content_enc_aes_settings_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/content_encoding_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/content_encodings_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/content_encryption_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/cue_point_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/cue_track_positions_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/cues_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/date_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/date_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/ebml_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/edition_entry_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/element_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/file_reader.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/float_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/float_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/id_element_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/id_element_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/id_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/id_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/info_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/int_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/istream_reader.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/master_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/master_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/master_value_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/mastering_metadata_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/parser_utils.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/parser_utils.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/projection_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/recursive_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/seek_head_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/seek_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/segment_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/segment_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/simple_tag_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/size_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/size_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/skip_callback.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/skip_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/skip_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/slices_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/tag_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/tags_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/targets_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/time_slice_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/track_entry_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/tracks_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/unknown_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/unknown_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/var_int_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/var_int_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/video_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/virtual_block_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/virtual_block_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/void_parser.cc"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/void_parser.h"
-            "${LIBWEBM_SRC_DIR}/webm_parser/src/webm_parser.cc")
-endif()
-
-# Libwebm section.
-add_library(webm STATIC
-            "${LIBWEBM_SRC_DIR}/common/file_util.cc"
-            "${LIBWEBM_SRC_DIR}/common/file_util.h"
-            "${LIBWEBM_SRC_DIR}/common/hdr_util.cc"
-            "${LIBWEBM_SRC_DIR}/common/hdr_util.h"
-            "${LIBWEBM_SRC_DIR}/common/webmids.h")
-target_link_libraries(webm LINK_PUBLIC mkvmuxer mkvparser)
-if (ENABLE_WEBM_PARSER)
-  target_link_libraries(webm LINK_PUBLIC webm_parser)
-endif ()
-
+# Set up compiler flags and build properties.
+include_directories("${LIBWEBM_SRC_DIR}")
 if (WIN32)
   # Use libwebm and libwebm.lib for project and library name on Windows (instead
   # webm and webm.lib).
@@ -182,204 +38,366 @@
   set_target_properties(webm PROPERTIES PREFIX lib)
 endif ()
 
-include_directories("${LIBWEBM_SRC_DIR}")
+if (MSVC)
+  add_cxx_flag_if_supported("/W4")
+  # Disable MSVC warnings that suggest making code non-portable.
+  add_cxx_flag_if_supported("/wd4996")
+  if (ENABLE_WERROR)
+    add_cxx_flag_if_supported("/WX")
+  endif ()
+else ()
+  add_cxx_flag_if_supported("-Wall")
+  add_cxx_flag_if_supported("-Wextra")
+  add_cxx_flag_if_supported("-Wnarrowing")
+  add_cxx_flag_if_supported("-Wno-deprecated")
+  add_cxx_flag_if_supported("-Wshorten-64-to-32")
+  if (ENABLE_WERROR)
+    add_cxx_flag_if_supported("-Werror")
+  endif ()
+endif ()
 
-# mkvparser_sample section.
-add_executable(mkvparser_sample
-               "${LIBWEBM_SRC_DIR}/mkvparser_sample.cc")
+# Source list variables.
+set(dumpvtt_sources "${LIBWEBM_SRC_DIR}/dumpvtt.cc")
+
+set(libwebm_common_sources
+    "${LIBWEBM_SRC_DIR}/common/file_util.cc"
+    "${LIBWEBM_SRC_DIR}/common/file_util.h"
+    "${LIBWEBM_SRC_DIR}/common/hdr_util.cc"
+    "${LIBWEBM_SRC_DIR}/common/hdr_util.h"
+    "${LIBWEBM_SRC_DIR}/common/webmids.h")
+
+set(mkvmuxer_sources
+    "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxer.cc"
+    "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxer.h"
+    "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxertypes.h"
+    "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxerutil.cc"
+    "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxerutil.h"
+    "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvwriter.cc"
+    "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvwriter.h"
+    "${LIBWEBM_SRC_DIR}/common/webmids.h")
+
+set(mkvmuxer_sample_sources
+    "${LIBWEBM_SRC_DIR}/mkvmuxer_sample.cc"
+    "${LIBWEBM_SRC_DIR}/sample_muxer_metadata.cc"
+    "${LIBWEBM_SRC_DIR}/sample_muxer_metadata.h")
+
+set(mkvmuxer_tests_sources
+    "${LIBWEBM_SRC_DIR}/testing/mkvmuxer_tests.cc"
+    "${LIBWEBM_SRC_DIR}/testing/test_util.cc"
+    "${LIBWEBM_SRC_DIR}/testing/test_util.h")
+
+set(mkvparser_sources
+    "${LIBWEBM_SRC_DIR}/mkvparser/mkvparser.cc"
+    "${LIBWEBM_SRC_DIR}/mkvparser/mkvparser.h"
+    "${LIBWEBM_SRC_DIR}/mkvparser/mkvreader.cc"
+    "${LIBWEBM_SRC_DIR}/mkvparser/mkvreader.h"
+    "${LIBWEBM_SRC_DIR}/common/webmids.h")
+
+set(mkvparser_sample_sources "${LIBWEBM_SRC_DIR}/mkvparser_sample.cc")
+set(mkvparser_tests_sources
+    "${LIBWEBM_SRC_DIR}/testing/mkvparser_tests.cc"
+    "${LIBWEBM_SRC_DIR}/testing/test_util.cc"
+    "${LIBWEBM_SRC_DIR}/testing/test_util.h")
+
+set(vp9_header_parser_tests_sources
+    "${LIBWEBM_SRC_DIR}/common/vp9_header_parser_tests.cc"
+    "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.cc"
+    "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.h"
+    "${LIBWEBM_SRC_DIR}/testing/test_util.cc"
+    "${LIBWEBM_SRC_DIR}/testing/test_util.h")
+
+set(vp9_level_stats_tests_sources
+    "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.cc"
+    "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.h"
+    "${LIBWEBM_SRC_DIR}/common/vp9_level_stats_tests.cc"
+    "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.cc"
+    "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.h"
+    "${LIBWEBM_SRC_DIR}/testing/test_util.cc"
+    "${LIBWEBM_SRC_DIR}/testing/test_util.h")
+
+set(vttdemux_sources
+    "${LIBWEBM_SRC_DIR}/vttdemux.cc"
+    "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.cc"
+    "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.h")
+
+set(webm_parser_sources
+    "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/buffer_reader.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/callback.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/dom_types.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/element.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/file_reader.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/id.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/istream_reader.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/reader.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/status.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/webm_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/ancestory.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/ancestory.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/audio_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/bit_utils.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/bit_utils.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/block_additions_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/block_group_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/block_header_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/block_header_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/block_more_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/block_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/block_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/bool_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/buffer_reader.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/byte_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/callback.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/chapter_atom_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/chapter_display_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/chapters_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/cluster_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/colour_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/content_enc_aes_settings_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/content_encoding_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/content_encodings_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/content_encryption_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/cue_point_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/cue_track_positions_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/cues_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/date_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/date_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/ebml_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/edition_entry_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/element_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/file_reader.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/float_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/float_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/id_element_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/id_element_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/id_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/id_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/info_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/int_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/istream_reader.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/master_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/master_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/master_value_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/mastering_metadata_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/parser_utils.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/parser_utils.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/projection_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/recursive_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/seek_head_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/seek_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/segment_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/segment_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/simple_tag_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/size_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/size_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/skip_callback.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/skip_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/skip_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/slices_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/tag_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/tags_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/targets_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/time_slice_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/track_entry_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/tracks_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/unknown_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/unknown_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/var_int_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/var_int_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/video_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/virtual_block_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/virtual_block_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/void_parser.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/void_parser.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/src/webm_parser.cc")
+
+set(webm_parser_demo_sources "${LIBWEBM_SRC_DIR}/webm_parser/demo/demo.cc")
+set(webm_parser_tests_sources
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/audio_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/bit_utils_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_additions_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_group_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_header_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_more_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/bool_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/buffer_reader_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/byte_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/callback_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/chapter_atom_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/chapter_display_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/chapters_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/cluster_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/colour_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_enc_aes_settings_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_encoding_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_encodings_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_encryption_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/cue_point_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/cue_track_positions_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/cues_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/date_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/ebml_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/edition_entry_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/element_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/float_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/id_element_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/id_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/info_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/int_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/istream_reader_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/limited_reader_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/master_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/master_value_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/mastering_metadata_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/parser_utils_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/projection_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/recursive_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/seek_head_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/seek_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/segment_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/simple_tag_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/size_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/skip_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/slices_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/tag_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/tags_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/targets_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/time_slice_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/track_entry_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/tracks_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/unknown_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/var_int_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/video_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/virtual_block_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/void_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/webm_parser_test.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/element_parser_test.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/limited_reader.cc"
+    "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/limited_reader.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/mock_callback.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/parser_test.h"
+    "${LIBWEBM_SRC_DIR}/webm_parser/tests/webm_parser_tests.cc")
+
+set(webm_info_sources
+    "${LIBWEBM_SRC_DIR}/common/indent.cc"
+    "${LIBWEBM_SRC_DIR}/common/indent.h"
+    "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.cc"
+    "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.h"
+    "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.cc"
+    "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.h"
+    "${LIBWEBM_SRC_DIR}/common/webm_constants.h"
+    "${LIBWEBM_SRC_DIR}/common/webm_endian.cc"
+    "${LIBWEBM_SRC_DIR}/common/webm_endian.h"
+    "${LIBWEBM_SRC_DIR}/webm_info.cc")
+
+set(webmts_sources
+    "${LIBWEBM_SRC_DIR}/common/libwebm_util.cc"
+    "${LIBWEBM_SRC_DIR}/common/libwebm_util.h"
+    "${LIBWEBM_SRC_DIR}/common/video_frame.cc"
+    "${LIBWEBM_SRC_DIR}/common/video_frame.h"
+    "${LIBWEBM_SRC_DIR}/m2ts/vpxpes2ts.cc"
+    "${LIBWEBM_SRC_DIR}/m2ts/vpxpes2ts.h"
+    "${LIBWEBM_SRC_DIR}/m2ts/vpxpes_parser.cc"
+    "${LIBWEBM_SRC_DIR}/m2ts/vpxpes_parser.h"
+    "${LIBWEBM_SRC_DIR}/m2ts/webm2pes.cc"
+    "${LIBWEBM_SRC_DIR}/m2ts/webm2pes.h")
+
+set(webm2pes_sources "${LIBWEBM_SRC_DIR}/m2ts/webm2pes_main.cc")
+set(webm2pes_tests_sources
+    "${LIBWEBM_SRC_DIR}/testing/test_util.cc"
+    "${LIBWEBM_SRC_DIR}/testing/test_util.h"
+    "${LIBWEBM_SRC_DIR}/testing/video_frame_tests.cc"
+    "${LIBWEBM_SRC_DIR}/m2ts/tests/webm2pes_tests.cc")
+set(webm2ts_sources "${LIBWEBM_SRC_DIR}/m2ts/vpxpes2ts_main.cc")
+
+set(webvtt_common_sources
+    "${LIBWEBM_SRC_DIR}/webvtt/vttreader.cc"
+    "${LIBWEBM_SRC_DIR}/webvtt/vttreader.h"
+    "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.cc"
+    "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.h")
+
+# Targets.
+add_library(mkvmuxer OBJECT ${mkvmuxer_sources})
+add_library(mkvparser OBJECT ${mkvparser_sources})
+add_library(webvtt_common OBJECT ${webvtt_common_sources})
+
+add_library(webm STATIC ${libwebm_common_sources}
+            $<TARGET_OBJECTS:mkvmuxer>
+            $<TARGET_OBJECTS:mkvparser>)
+
+add_executable(mkvparser_sample ${mkvparser_sample_sources})
 target_link_libraries(mkvparser_sample LINK_PUBLIC webm)
 
-# mkvmuxer_sample section.
-add_executable(mkvmuxer_sample
-               "${LIBWEBM_SRC_DIR}/mkvmuxer_sample.cc"
-               "${LIBWEBM_SRC_DIR}/sample_muxer_metadata.cc"
-               "${LIBWEBM_SRC_DIR}/sample_muxer_metadata.h"
-               "${LIBWEBM_SRC_DIR}/webvtt/vttreader.cc"
-               "${LIBWEBM_SRC_DIR}/webvtt/vttreader.h"
-               "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.cc"
-               "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.h")
+add_executable(mkvmuxer_sample ${mkvmuxer_sample_sources}
+               $<TARGET_OBJECTS:webvtt_common>)
 target_link_libraries(mkvmuxer_sample LINK_PUBLIC webm)
 
-# Dumpvtt section.
-add_executable(dumpvtt
-               "${LIBWEBM_SRC_DIR}/dumpvtt.cc"
-               "${LIBWEBM_SRC_DIR}/webvtt/vttreader.cc"
-               "${LIBWEBM_SRC_DIR}/webvtt/vttreader.h"
-               "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.cc"
-               "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.h")
+add_executable(dumpvtt ${dumpvtt_sources} $<TARGET_OBJECTS:webvtt_common>)
 target_link_libraries(dumpvtt LINK_PUBLIC webm)
 
-# Vttdemux section.
-add_executable(vttdemux
-               "${LIBWEBM_SRC_DIR}/vttdemux.cc"
-               "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.cc"
-               "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.h")
+add_executable(vttdemux ${vttdemux_sources})
 target_link_libraries(vttdemux LINK_PUBLIC webm)
 
 if (ENABLE_WEBMINFO)
-# Webm_info section.
-add_executable(webm_info
-               "${LIBWEBM_SRC_DIR}/common/indent.cc"
-               "${LIBWEBM_SRC_DIR}/common/indent.h"
-               "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.cc"
-               "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.h"
-               "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.cc"
-               "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.h"
-               "${LIBWEBM_SRC_DIR}/common/webm_constants.h"
-               "${LIBWEBM_SRC_DIR}/common/webm_endian.cc"
-               "${LIBWEBM_SRC_DIR}/common/webm_endian.h"
-               "${LIBWEBM_SRC_DIR}/webm_info.cc")
-target_link_libraries(webm_info LINK_PUBLIC webm)
+  add_executable(webm_info ${webm_info_sources})
+  target_link_libraries(webm_info LINK_PUBLIC webm)
 endif ()
 
 if (ENABLE_WEBM_PARSER)
-# webm_parser_demo section.
-add_executable(webm_parser_demo
-               "${LIBWEBM_SRC_DIR}/webm_parser/demo/demo.cc")
-target_link_libraries(webm_parser_demo LINK_PUBLIC webm)
+  include_directories(webm_parser webm_parser/include)
+  add_library(webm_parser OBJECT ${webm_parser_sources})
+  target_sources(webm PUBLIC $<TARGET_OBJECTS:webm_parser>)
+
+  add_executable(webm_parser_demo ${webm_parser_demo_sources})
+  target_link_libraries(webm_parser_demo LINK_PUBLIC webm)
 endif ()
 
 if (ENABLE_WEBMTS)
-  # webmts (PES/TS support) library section.
-  add_library(webmts
-              "${LIBWEBM_SRC_DIR}/common/libwebm_util.cc"
-              "${LIBWEBM_SRC_DIR}/common/libwebm_util.h"
-              "${LIBWEBM_SRC_DIR}/common/video_frame.cc"
-              "${LIBWEBM_SRC_DIR}/common/video_frame.h"
-              "${LIBWEBM_SRC_DIR}/m2ts/vpxpes2ts.cc"
-              "${LIBWEBM_SRC_DIR}/m2ts/vpxpes2ts.h"
-              "${LIBWEBM_SRC_DIR}/m2ts/vpxpes_parser.cc"
-              "${LIBWEBM_SRC_DIR}/m2ts/vpxpes_parser.h"
-              "${LIBWEBM_SRC_DIR}/m2ts/webm2pes.cc"
-              "${LIBWEBM_SRC_DIR}/m2ts/webm2pes.h")
+  add_library(webmts OBJECT ${webmts_sources})
 
-  # webm2pes section.
-  add_executable(webm2pes
-                "${LIBWEBM_SRC_DIR}/m2ts/webm2pes_main.cc")
-  target_link_libraries(webm2pes LINK_PUBLIC webm webmts)
+  add_executable(webm2pes ${webm2pes_sources} $<TARGET_OBJECTS:webmts>)
+  target_link_libraries(webm2pes LINK_PUBLIC webm)
 
-  # webm2ts section.
-  add_executable(webm2ts "${LIBWEBM_SRC_DIR}/m2ts/vpxpes2ts_main.cc")
-  target_link_libraries(webm2ts LINK_PUBLIC webm webmts)
+  add_executable(webm2ts ${webm2ts_sources} $<TARGET_OBJECTS:webmts>)
+  target_link_libraries(webm2ts LINK_PUBLIC webm)
 endif ()
 
 if (ENABLE_TESTS)
+  set(GTEST_SRC_DIR "${LIBWEBM_SRC_DIR}/../googletest" CACHE PATH
+      "Path to Googletest git repository.")
+  # This directory is where libwebm will build googletest dependencies.
+  set(GTEST_BUILD_DIR "${CMAKE_BINARY_DIR}/googletest_build")
+
   add_subdirectory("${GTEST_SRC_DIR}" "${GTEST_BUILD_DIR}")
   include_directories("${GTEST_SRC_DIR}/googletest/include")
 
-  add_executable(mkvmuxer_tests
-                 "${LIBWEBM_SRC_DIR}/testing/mkvmuxer_tests.cc"
-                 "${LIBWEBM_SRC_DIR}/testing/test_util.cc"
-                 "${LIBWEBM_SRC_DIR}/testing/test_util.h")
+  add_executable(mkvmuxer_tests ${mkvmuxer_tests_sources})
   target_link_libraries(mkvmuxer_tests LINK_PUBLIC gtest webm)
 
-  add_executable(mkvparser_tests
-                 "${LIBWEBM_SRC_DIR}/testing/mkvparser_tests.cc"
-                 "${LIBWEBM_SRC_DIR}/testing/test_util.cc"
-                 "${LIBWEBM_SRC_DIR}/testing/test_util.h")
+  add_executable(mkvparser_tests ${mkvparser_tests_sources})
   target_link_libraries(mkvparser_tests LINK_PUBLIC gtest webm)
 
-  add_executable(vp9_header_parser_tests
-                 "${LIBWEBM_SRC_DIR}/common/vp9_header_parser_tests.cc"
-                 "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.cc"
-                 "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.h"
-                 "${LIBWEBM_SRC_DIR}/testing/test_util.cc"
-                 "${LIBWEBM_SRC_DIR}/testing/test_util.h")
+  add_executable(vp9_header_parser_tests ${vp9_header_parser_tests_sources})
   target_link_libraries(vp9_header_parser_tests LINK_PUBLIC gtest webm)
 
-  add_executable(vp9_level_stats_tests
-                 "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.cc"
-                 "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.h"
-                 "${LIBWEBM_SRC_DIR}/common/vp9_level_stats_tests.cc"
-                 "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.cc"
-                 "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.h"
-                 "${LIBWEBM_SRC_DIR}/testing/test_util.cc"
-                 "${LIBWEBM_SRC_DIR}/testing/test_util.h")
+  add_executable(vp9_level_stats_tests ${vp9_level_stats_tests_sources})
   target_link_libraries(vp9_level_stats_tests LINK_PUBLIC gtest webm)
 
   if (ENABLE_WEBMTS)
-    add_executable(webm2pes_tests
-                  "${LIBWEBM_SRC_DIR}/testing/test_util.cc"
-                  "${LIBWEBM_SRC_DIR}/testing/test_util.h"
-                  "${LIBWEBM_SRC_DIR}/testing/video_frame_tests.cc"
-                  "${LIBWEBM_SRC_DIR}/m2ts/tests/webm2pes_tests.cc")
-    target_link_libraries(webm2pes_tests LINK_PUBLIC gtest webm webmts)
+    add_executable(webm2pes_tests ${webm2pes_tests_sources}
+                   $<TARGET_OBJECTS:webmts>)
+    target_link_libraries(webm2pes_tests LINK_PUBLIC gtest webm)
   endif ()
 
-  # TODO(tomfinegan): Move to webm_parser/CMakeLists.txt.
   if (ENABLE_WEBM_PARSER)
     include_directories("${GTEST_SRC_DIR}/googlemock/include")
-    add_executable(webm_parser_tests
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/audio_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/bit_utils_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_additions_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_group_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_header_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_more_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/bool_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/buffer_reader_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/byte_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/callback_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/chapter_atom_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/chapter_display_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/chapters_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/cluster_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/colour_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_enc_aes_settings_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_encoding_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_encodings_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_encryption_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/cue_point_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/cue_track_positions_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/cues_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/date_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/ebml_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/edition_entry_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/element_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/float_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/id_element_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/id_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/info_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/int_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/istream_reader_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/limited_reader_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/master_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/master_value_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/mastering_metadata_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/parser_utils_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/projection_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/recursive_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/seek_head_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/seek_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/segment_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/simple_tag_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/size_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/skip_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/slices_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/tag_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/tags_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/targets_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/time_slice_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/track_entry_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/tracks_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/unknown_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/var_int_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/video_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/virtual_block_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/void_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/webm_parser_test.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/element_parser_test.h"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/limited_reader.cc"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/limited_reader.h"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/mock_callback.h"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/parser_test.h"
-                   "${LIBWEBM_SRC_DIR}/webm_parser/tests/webm_parser_tests.cc")
+    add_executable(webm_parser_tests ${webm_parser_tests_sources})
     target_link_libraries(webm_parser_tests LINK_PUBLIC gmock gtest webm)
   endif ()
 endif ()
 
-# Include-what-you-use section.
+# Include-what-you-use.
 if (ENABLE_IWYU)
   # Make sure all the tools necessary for IWYU are present.
   find_program(iwyu_path NAMES include-what-you-use)
diff --git a/build/cxx11_tests.cmake b/build/cxx11_tests.cmake
deleted file mode 100644
index 0ec80dc..0000000
--- a/build/cxx11_tests.cmake
+++ /dev/null
@@ -1,140 +0,0 @@
-##  Copyright (c) 2016 The WebM project authors. All Rights Reserved.
-##
-##  Use of this source code is governed by a BSD-style license
-##  that can be found in the LICENSE file in the root of the source
-##  tree. An additional intellectual property rights grant can be found
-##  in the file PATENTS.  All contributing project authors may
-##  be found in the AUTHORS file in the root of the source tree.
-cmake_minimum_required(VERSION 3.2)
-
-include(CheckCXXCompilerFlag)
-include(CheckCXXSourceCompiles)
-
-if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR
-    CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR
-    CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-  CHECK_CXX_COMPILER_FLAG("-std=c++11" HAVE_CXX11)
-  if (HAVE_CXX11)
-    set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}" CACHE STRING "" FORCE)
-  endif ()
-endif ()
-
-if (MSVC)
-  set(HAVE_CXX11 ON)
-endif ()
-
-# C++11 compile tests.
-if (HAVE_CXX11)
-  # std::unique_ptr
-  check_cxx_source_compiles("
-      #include <memory>
-      int main() {
-        std::unique_ptr<int> ptr;
-        (void)ptr;
-        return 0;
-      }"
-      HAVE_UNIQUE_PTR)
-
-  # default member values
-  check_cxx_source_compiles("
-      struct Foo {
-        int a = 0;
-      };
-      int main() {
-        Foo bar;
-        (void)bar;
-        return 0;
-      }"
-      HAVE_DEFAULT_MEMBER_VALUES)
-
-  # defaulted methods
-  check_cxx_source_compiles("
-      struct Foo {
-        Foo() = default;
-        ~Foo() = default;
-      };
-      int main() {
-        Foo bar;
-        (void)bar;
-        return 0;
-      }"
-      HAVE_DEFAULTED_MEMBER_FUNCTIONS)
-
-  # deleted methods
-  check_cxx_source_compiles("
-      struct Foo {
-        Foo() {}
-        Foo(const Foo&) = delete;
-      };
-      int main() {
-        Foo bar;
-        (void)bar;
-        return 0;
-      }"
-      HAVE_DELETED_MEMBER_FUNCTIONS)
-
-  # auto&
-  check_cxx_source_compiles("
-      int main() {
-        int a;
-        auto& b = a;
-        (void)b;
-        return 0;
-      }"
-      HAVE_AUTO_REF)
-
-  # ranged for
-  check_cxx_source_compiles("
-      int main() {
-        int a[4];
-        for (int& b : a) {
-          b = 0;
-        }
-        return 0;
-      }"
-      HAVE_RANGED_FOR)
-
-  # move constructors
-  check_cxx_source_compiles("
-      struct Foo {
-        Foo() {}
-        Foo(Foo&&) = default;
-        Foo(const Foo&) = delete;
-      };
-      int main() {
-        Foo bar;
-        (void)bar;
-        return 0;
-      }"
-      HAVE_MOVE_CONSTRUCTORS)
-
-  # member initializers
-  check_cxx_source_compiles("
-      struct Foo {
-        Foo() {}
-        Foo(int a_val, int b_val) : a(a_val), b(b_val) {}
-        int a;
-        int b;
-      };
-      struct Bar {
-        Bar() {}
-        Foo f = Foo(1, 2);
-      };
-      int main() {
-        Bar bar;
-        (void)bar;
-        return 0;
-      }"
-      HAVE_MEMBER_INITIALIZERS)
-endif ()
-
-if (NOT HAVE_UNIQUE_PTR
-    OR NOT HAVE_DEFAULT_MEMBER_VALUES
-    OR NOT HAVE_DEFAULTED_MEMBER_FUNCTIONS
-    OR NOT HAVE_DELETED_MEMBER_FUNCTIONS
-    OR NOT HAVE_AUTO_REF
-    OR NOT HAVE_RANGED_FOR
-    OR NOT HAVE_MOVE_CONSTRUCTORS
-    OR NOT HAVE_MEMBER_INITIALIZERS)
-  set(HAVE_CXX11 OFF)
-endif ()
diff --git a/build/cxx_flags.cmake b/build/cxx_flags.cmake
index f72f53f..8cb9bd0 100644
--- a/build/cxx_flags.cmake
+++ b/build/cxx_flags.cmake
@@ -35,20 +35,39 @@
   endif ()
 endfunction ()
 
-if (MSVC)
-  add_cxx_flag_if_supported("/W4")
-  # Disable MSVC warnings that suggest making code non-portable.
-  add_cxx_flag_if_supported("/wd4996")
-  if (ENABLE_WERROR)
-    add_cxx_flag_if_supported("/WX")
+# Checks CXX compiler for support of $cxx_flag and terminates generation when
+# support is not present.
+function (require_cxx_flag cxx_flag)
+  unset(CXX_FLAG_FOUND CACHE)
+  string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FOUND)
+
+  if (${CXX_FLAG_FOUND} EQUAL -1)
+    unset(LIBWEBM_HAVE_CXX_FLAG)
+    message("Checking CXX compiler flag support for: " ${cxx_flag})
+    check_cxx_compiler_flag("${cxx_flag}" LIBWEBM_HAVE_CXX_FLAG)
+    if (NOT LIBWEBM_HAVE_CXX_FLAG)
+      message(FATAL_ERROR
+              "${PROJECT_NAME} requires support for CXX flag: ${flag}.")
+    endif ()
+    set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}" CACHE STRING "" FORCE)
   endif ()
-else ()
-  add_cxx_flag_if_supported("-Wall")
-  add_cxx_flag_if_supported("-Wextra")
-  add_cxx_flag_if_supported("-Wnarrowing")
-  add_cxx_flag_if_supported("-Wno-deprecated")
-  add_cxx_flag_if_supported("-Wshorten-64-to-32")
-  if (ENABLE_WERROR)
-    add_cxx_flag_if_supported("-Werror")
+endfunction ()
+
+# Checks only non-MSVC targets for support of $cxx_flag.
+function (require_cxx_flag_nomsvc cxx_flag)
+  if (NOT MSVC)
+    require_cxx_flag(${cxx_flag})
   endif ()
-endif ()
+endfunction ()
+
+# Adds $preproc_def to CXX compiler command line (as -D$preproc_def) if not
+# already present.
+function (add_cxx_preproc_definition preproc_def)
+  unset(PREPROC_DEF_FOUND CACHE)
+  string(FIND "${CMAKE_CXX_FLAGS}" "${preproc_def}" PREPROC_DEF_FOUND)
+
+  if (${PREPROC_DEF_FOUND} EQUAL -1)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${preproc_def}" CACHE STRING ""
+        FORCE)
+  endif ()
+endfunction ()