CMakeLists: Generate Dawn headers separately from libdawn

libdawn will be one of the libraries produced but other libraries like
libdawn_native don't need to link against it. However they do need the
Dawn headers so we generate them separately.

This also makes all internal targets depend on the header generation and
have the include directories necessary for those headers.

Also has a small fix for setting compile flags only for C++ files.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d6ac0c2..dc532ef 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,6 +15,9 @@
 cmake_minimum_required(VERSION 2.8)
 project(dawn C CXX)
 
+# List TARGET_OBJECTS in SOURCES target property.
+cmake_policy(SET CMP0051 NEW)
+
 if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
     message(FATAL_ERROR
         "In-source builds are unsupported. Use another directory, like build/, "
@@ -113,9 +116,9 @@
     endif()
 else()
     # Activate C++14 only on C++ files, not C files.
-    list(APPEND DAWN_FLAGS "$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:-std=c++14>")
+    list(APPEND DAWN_FLAGS "$<$<COMPILE_LANGUAGE:CXX>:-std=c++14>")
     # enable -Wold-style-cast on C++
-    list(APPEND DAWN_FLAGS "$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:-Wold-style-cast>")
+    list(APPEND DAWN_FLAGS "$<$<COMPILE_LANGUAGE:CXX>:-Wold-style-cast>")
     list(APPEND DAWN_FLAGS "-fPIC")
 
     list(APPEND DAWN_INTERNAL_FLAGS "-Wall" "-Wextra")
@@ -153,6 +156,12 @@
     set_property(TARGET ${target} APPEND PROPERTY COMPILE_OPTIONS ${DAWN_INTERNAL_FLAGS})
     set_property(TARGET ${target} APPEND PROPERTY COMPILE_DEFINITIONS ${DAWN_INTERNAL_DEFS})
 
+    # Common include directories shared by all internal targets
+    target_include_directories(${target} PRIVATE ${SRC_DIR} ${GENERATED_DIR} ${INCLUDE_DIR})
+
+    # All internal targets require the headers to have been generated
+    add_dependencies(${target} dawn_headers)
+
     # Group the target sources by folder to have folders show in Visual Studio
     if (MSVC)
         get_target_property(targetSources ${target} SOURCES)
@@ -183,26 +192,39 @@
 
 add_subdirectory(generator)
 
+# Dawn header generation is in its own target so that it can be set as a build dependency for all
+# internal targets
 Generate(
-    LIB_NAME dawn
-    LIB_TYPE STATIC
-    PRINT_NAME libDawn
+    LIB_NAME dawn_headers
+    LIB_TYPE OBJECT
+    FOLDER ""
+    PRINT_NAME "Dawn headers"
     COMMAND_LINE_ARGS
         ${GENERATOR_COMMON_ARGS}
-        -T dawn
+        -T dawn_headers
 )
-target_include_directories(dawn PUBLIC ${GENERATED_DIR})
+# Older versions of CMake aren't able to know which linker to use without this and fail.
+set_property(TARGET dawn_headers PROPERTY LINKER_LANGUAGE "CXX")
 
+# libdawn.so/dll/dylib which contains the static proctable C interface and its C++ wrapper
 Generate(
-    LIB_NAME dawncpp
-    LIB_TYPE STATIC
-    PRINT_NAME libDawn++
+    LIB_NAME libdawn_autogen
+    LIB_TYPE OBJECT
+    FOLDER "libdawn"
+    PRINT_NAME "libdawn"
     COMMAND_LINE_ARGS
         ${GENERATOR_COMMON_ARGS}
-        -T dawncpp
+        -T libdawn
 )
-target_include_directories(dawncpp PUBLIC ${GENERATED_DIR} PUBLIC ${INCLUDE_DIR})
-target_link_libraries(dawncpp dawn)
+
+add_library(libdawn STATIC
+    $<TARGET_OBJECTS:libdawn_autogen>
+    ${INCLUDE_DIR}/dawn/dawn_wsi.h
+    ${INCLUDE_DIR}/dawn/EnumClassBitmasks.h
+)
+set_property(TARGET libdawn PROPERTY OUTPUT_NAME "dawn")
+target_include_directories(libdawn PUBLIC ${GENERATED_DIR} ${INCLUDE_DIR})
+DawnInternalTarget("libdawn" libdawn)
 
 ################################################################################
 # Call to other CMakeLists.txt
diff --git a/generator/main.py b/generator/main.py
index 37b2f1a..60d3571 100644
--- a/generator/main.py
+++ b/generator/main.py
@@ -389,7 +389,7 @@
     print(text)
 
 def main():
-    targets = ['dawn', 'dawncpp', 'mock_dawn', 'opengl', 'metal', 'd3d12', 'null', 'wire', "dawn_native_utils"]
+    targets = ['dawn_headers', 'libdawn', 'mock_dawn', 'opengl', 'metal', 'd3d12', 'null', 'wire', "dawn_native_utils"]
 
     parser = argparse.ArgumentParser(
         description = 'Generates code for various target for Dawn.',
@@ -437,16 +437,17 @@
     renders = []
 
     c_params = {'native_methods': lambda typ: c_native_methods(api_params['types'], typ)}
+    cpp_params = {'native_methods': lambda typ: cpp_native_methods(api_params['types'], typ)}
 
-    if 'dawn' in targets:
+    if 'dawn_headers' in targets:
         renders.append(FileRender('api.h', 'dawn/dawn.h', [base_params, api_params, c_params]))
-        renders.append(FileRender('api.c', 'dawn/dawn.c', [base_params, api_params, c_params]))
+        renders.append(FileRender('apicpp.h', 'dawn/dawncpp.h', [base_params, api_params, cpp_params]))
+        renders.append(FileRender('apicpp_traits.h', 'dawn/dawncpp_traits.h', [base_params, api_params, cpp_params]))
 
-    if 'dawncpp' in targets:
+    if 'libdawn' in targets:
         additional_params = {'native_methods': lambda typ: cpp_native_methods(api_params['types'], typ)}
-        renders.append(FileRender('apicpp.h', 'dawn/dawncpp.h', [base_params, api_params, additional_params]))
-        renders.append(FileRender('apicpp.cpp', 'dawn/dawncpp.cpp', [base_params, api_params, additional_params]))
-        renders.append(FileRender('apicpp_traits.h', 'dawn/dawncpp_traits.h', [base_params, api_params, additional_params]))
+        renders.append(FileRender('api.c', 'dawn/dawn.c', [base_params, api_params, c_params]))
+        renders.append(FileRender('apicpp.cpp', 'dawn/dawncpp.cpp', [base_params, api_params, cpp_params]))
 
     if 'mock_dawn' in targets:
         renders.append(FileRender('mock_api.h', 'mock/mock_dawn.h', [base_params, api_params, c_params]))
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 8c94f61..8423961 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -34,5 +34,4 @@
 )
 
 add_library(dawn_common STATIC ${COMMON_SOURCES})
-target_include_directories(dawn_common PUBLIC ${SRC_DIR})
 DawnInternalTarget("" dawn_common)
diff --git a/src/dawn_native/CMakeLists.txt b/src/dawn_native/CMakeLists.txt
index 454279f..9aca791 100644
--- a/src/dawn_native/CMakeLists.txt
+++ b/src/dawn_native/CMakeLists.txt
@@ -28,9 +28,7 @@
         ${GENERATOR_COMMON_ARGS}
         -T dawn_native_utils
 )
-target_link_libraries(dawn_native_utils_autogen dawncpp)
-target_include_directories(dawn_native_utils_autogen PUBLIC ${GENERATED_DIR})
-target_include_directories(dawn_native_utils_autogen PRIVATE ${SRC_DIR})
+target_link_libraries(dawn_native_utils_autogen)
 
 function(GenerateProcTable backend)
     Generate(
@@ -42,9 +40,7 @@
             ${GENERATOR_COMMON_ARGS}
             -T ${backend}
     )
-    target_link_libraries(${backend}_autogen dawncpp dawn_native_utils_autogen)
-    target_include_directories(${backend}_autogen PRIVATE ${SRC_DIR})
-    target_include_directories(${backend}_autogen PUBLIC ${GENERATED_DIR})
+    target_link_libraries(${backend}_autogen dawn_native_utils_autogen)
 endfunction()
 
 ################################################################################
@@ -388,22 +384,22 @@
     ${DAWN_NATIVE_DIR}/ToBackend.h
 )
 
-add_library(lib_dawn_native STATIC ${DAWN_NATIVE_SOURCES})
-DawnInternalTarget("dawn_native" lib_dawn_native)
-target_link_libraries(lib_dawn_native dawn_common glfw glad spirv_cross)
+add_library(libdawn_native STATIC ${DAWN_NATIVE_SOURCES})
+DawnInternalTarget("dawn_native" libdawn_native)
+target_link_libraries(libdawn_native dawn_common glfw glad spirv_cross)
 
 if (DAWN_ENABLE_D3D12)
-    target_link_libraries(lib_dawn_native d3d12_autogen)
+    target_link_libraries(libdawn_native d3d12_autogen)
 endif()
 if (DAWN_ENABLE_METAL)
-    target_link_libraries(lib_dawn_native metal_autogen)
+    target_link_libraries(libdawn_native metal_autogen)
 endif()
 if (DAWN_ENABLE_NULL)
-    target_link_libraries(lib_dawn_native null_autogen)
+    target_link_libraries(libdawn_native null_autogen)
 endif()
 if (DAWN_ENABLE_OPENGL)
-    target_link_libraries(lib_dawn_native opengl_autogen)
+    target_link_libraries(libdawn_native opengl_autogen)
 endif()
 if (DAWN_ENABLE_VULKAN)
-    target_link_libraries(lib_dawn_native vulkan_autogen)
+    target_link_libraries(libdawn_native vulkan_autogen)
 endif()
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index f4b67da..c7a726e 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -21,8 +21,7 @@
         ${GENERATOR_COMMON_ARGS}
         -T mock_dawn
 )
-target_include_directories(mock_dawn PUBLIC ${GENERATED_DIR})
-target_link_libraries(mock_dawn dawn gtest)
+target_link_libraries(mock_dawn gtest)
 
 set(TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 set(UNITTESTS_DIR ${TESTS_DIR}/unittests)
@@ -67,7 +66,7 @@
 endif()
 
 add_executable(dawn_unittests ${UNITTEST_SOURCES})
-target_link_libraries(dawn_unittests dawn_common gtest lib_dawn_native mock_dawn dawn_wire utils)
+target_link_libraries(dawn_unittests dawn_common gtest libdawn_native mock_dawn dawn_wire utils)
 DawnInternalTarget("tests" dawn_unittests)
 
 add_executable(dawn_end2end_tests
diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt
index 237315e..06d81dd 100644
--- a/src/utils/CMakeLists.txt
+++ b/src/utils/CMakeLists.txt
@@ -54,7 +54,7 @@
 endif()
 
 add_library(utils STATIC ${UTILS_SOURCES})
-target_link_libraries(utils lib_dawn_native shaderc_shared dawncpp dawn)
+target_link_libraries(utils libdawn_native shaderc_shared libdawn)
 target_include_directories(utils PUBLIC ${SRC_DIR})
 DawnInternalTarget("" utils)
 if(NOT MSVC)
diff --git a/src/wire/CMakeLists.txt b/src/wire/CMakeLists.txt
index 497ce2c..6c99c06 100644
--- a/src/wire/CMakeLists.txt
+++ b/src/wire/CMakeLists.txt
@@ -13,28 +13,23 @@
 # limitations under the License.
 
 set(WIRE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
-set(TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests)
 
 Generate(
-    LIB_NAME wire_autogen
+    LIB_NAME dawn_wire_autogen
     LIB_TYPE STATIC
     FOLDER "wire"
     PRINT_NAME "Wire serialization/deserialization autogenerated files"
-    EXTRA_DEPS dawn
     COMMAND_LINE_ARGS
         ${GENERATOR_COMMON_ARGS}
         -T wire
     EXTRA_SOURCES
         ${WIRE_DIR}/WireCmd.h
 )
-target_include_directories(wire_autogen PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
-target_include_directories(wire_autogen PUBLIC ${GENERATED_DIR})
-target_link_libraries(wire_autogen dawn dawn_common)
 
 add_library(dawn_wire STATIC
     ${WIRE_DIR}/TerribleCommandBuffer.cpp
     ${WIRE_DIR}/TerribleCommandBuffer.h
     ${WIRE_DIR}/Wire.h
 )
-target_link_libraries(dawn_wire wire_autogen)
+target_link_libraries(dawn_wire dawn_wire_autogen dawn_common)
 DawnInternalTarget("wire" dawn_wire)