| Index: tools/gn/ninja_binary_target_writer_unittest.cc
|
| diff --git a/tools/gn/ninja_binary_target_writer_unittest.cc b/tools/gn/ninja_binary_target_writer_unittest.cc
|
| index 16f75893c03e776196767f7a148062dfe2219d24..4bb055337d31ff260d459c7c5a6492a0d5a393a2 100644
|
| --- a/tools/gn/ninja_binary_target_writer_unittest.cc
|
| +++ b/tools/gn/ninja_binary_target_writer_unittest.cc
|
| @@ -388,6 +388,17 @@ TEST(NinjaBinaryTargetWriter, WinPrecompiledHeaders) {
|
| "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
|
| cxx_tool->set_precompiled_header_type(Tool::PCH_MSVC);
|
| pch_toolchain.SetTool(Toolchain::TYPE_CXX, cxx_tool.Pass());
|
| +
|
| + // Add a C compiler as well.
|
| + scoped_ptr<Tool> cc_tool(new Tool);
|
| + TestWithScope::SetCommandForTool(
|
| + "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} "
|
| + "-o {{output}}",
|
| + cc_tool.get());
|
| + cc_tool->set_outputs(SubstitutionList::MakeForTest(
|
| + "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
|
| + cc_tool->set_precompiled_header_type(Tool::PCH_MSVC);
|
| + pch_toolchain.SetTool(Toolchain::TYPE_CC, cc_tool.Pass());
|
| pch_toolchain.ToolchainSetupComplete();
|
|
|
| // This target doesn't specify precompiled headers.
|
| @@ -397,6 +408,7 @@ TEST(NinjaBinaryTargetWriter, WinPrecompiledHeaders) {
|
| no_pch_target.set_output_type(Target::SOURCE_SET);
|
| no_pch_target.visibility().SetPublic();
|
| no_pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
|
| + no_pch_target.sources().push_back(SourceFile("//foo/input2.c"));
|
| no_pch_target.SetToolchain(&pch_toolchain);
|
| ASSERT_TRUE(no_pch_target.OnResolved(&err));
|
|
|
| @@ -408,14 +420,18 @@ TEST(NinjaBinaryTargetWriter, WinPrecompiledHeaders) {
|
| "defines =\n"
|
| "include_dirs =\n"
|
| "cflags =\n"
|
| + "cflags_c =\n"
|
| "cflags_cc =\n"
|
| "target_output_name = no_pch_target\n"
|
| "\n"
|
| "build withpch/obj/foo/no_pch_target.input1.o: "
|
| "withpch_cxx ../../foo/input1.cc\n"
|
| + "build withpch/obj/foo/no_pch_target.input2.o: "
|
| + "withpch_cc ../../foo/input2.c\n"
|
| "\n"
|
| "build withpch/obj/foo/no_pch_target.stamp: "
|
| - "withpch_stamp withpch/obj/foo/no_pch_target.input1.o\n";
|
| + "withpch_stamp withpch/obj/foo/no_pch_target.input1.o "
|
| + "withpch/obj/foo/no_pch_target.input2.o\n";
|
| EXPECT_EQ(no_pch_expected, out.str());
|
| }
|
|
|
| @@ -429,6 +445,7 @@ TEST(NinjaBinaryTargetWriter, WinPrecompiledHeaders) {
|
| pch_target.set_output_type(Target::SOURCE_SET);
|
| pch_target.visibility().SetPublic();
|
| pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
|
| + pch_target.sources().push_back(SourceFile("//foo/input2.c"));
|
| pch_target.SetToolchain(&pch_toolchain);
|
| ASSERT_TRUE(pch_target.OnResolved(&err));
|
|
|
| @@ -440,12 +457,18 @@ TEST(NinjaBinaryTargetWriter, WinPrecompiledHeaders) {
|
| "defines =\n"
|
| "include_dirs =\n"
|
| "cflags =\n"
|
| - // There should only be one .pch file created, for C++ files.
|
| + // It should output language-specific pch files.
|
| + "cflags_c = /Fpwithpch/obj/foo/pch_target_c.pch "
|
| + "/Yubuild/precompile.h\n"
|
| "cflags_cc = /Fpwithpch/obj/foo/pch_target_cc.pch "
|
| "/Yubuild/precompile.h\n"
|
| "target_output_name = pch_target\n"
|
| "\n"
|
| - // Compile the precompiled source file with /Yc.
|
| + // Compile the precompiled source files with /Yc.
|
| + "build withpch/obj/build/pch_target.precompile.c.o: "
|
| + "withpch_cc ../../build/precompile.cc\n"
|
| + " cflags_c = ${cflags_c} /Ycbuild/precompile.h\n"
|
| + "\n"
|
| "build withpch/obj/build/pch_target.precompile.cc.o: "
|
| "withpch_cxx ../../build/precompile.cc\n"
|
| " cflags_cc = ${cflags_cc} /Ycbuild/precompile.h\n"
|
| @@ -454,15 +477,145 @@ TEST(NinjaBinaryTargetWriter, WinPrecompiledHeaders) {
|
| "withpch_cxx ../../foo/input1.cc | "
|
| // Explicit dependency on the PCH build step.
|
| "withpch/obj/build/pch_target.precompile.cc.o\n"
|
| + "build withpch/obj/foo/pch_target.input2.o: "
|
| + "withpch_cc ../../foo/input2.c | "
|
| + // Explicit dependency on the PCH build step.
|
| + "withpch/obj/build/pch_target.precompile.c.o\n"
|
| "\n"
|
| - "build withpch/obj/foo/pch_target.stamp: "
|
| - "withpch_stamp withpch/obj/foo/pch_target.input1.o "
|
| - // The precompiled object file was added to the outputs.
|
| + "build withpch/obj/foo/pch_target.stamp: withpch_stamp "
|
| + "withpch/obj/foo/pch_target.input1.o "
|
| + "withpch/obj/foo/pch_target.input2.o "
|
| + // The precompiled object files were added to the outputs.
|
| + "withpch/obj/build/pch_target.precompile.c.o "
|
| "withpch/obj/build/pch_target.precompile.cc.o\n";
|
| EXPECT_EQ(pch_win_expected, out.str());
|
| }
|
| }
|
|
|
| +TEST(NinjaBinaryTargetWriter, GCCPrecompiledHeaders) {
|
| + Err err;
|
| +
|
| + // This setup's toolchain does not have precompiled headers defined.
|
| + TestWithScope setup;
|
| +
|
| + // A precompiled header toolchain.
|
| + Settings pch_settings(setup.build_settings(), "withpch/");
|
| + Toolchain pch_toolchain(&pch_settings,
|
| + Label(SourceDir("//toolchain/"), "withpch"));
|
| + pch_settings.set_toolchain_label(pch_toolchain.label());
|
| + pch_settings.set_default_toolchain_label(setup.toolchain()->label());
|
| +
|
| + // Declare a C++ compiler that supports PCH.
|
| + scoped_ptr<Tool> cxx_tool(new Tool);
|
| + TestWithScope::SetCommandForTool(
|
| + "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} "
|
| + "-o {{output}}",
|
| + cxx_tool.get());
|
| + cxx_tool->set_outputs(SubstitutionList::MakeForTest(
|
| + "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
|
| + cxx_tool->set_precompiled_header_type(Tool::PCH_GCC);
|
| + pch_toolchain.SetTool(Toolchain::TYPE_CXX, cxx_tool.Pass());
|
| + pch_toolchain.ToolchainSetupComplete();
|
| +
|
| + // Add a C compiler as well.
|
| + scoped_ptr<Tool> cc_tool(new Tool);
|
| + TestWithScope::SetCommandForTool(
|
| + "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} "
|
| + "-o {{output}}",
|
| + cc_tool.get());
|
| + cc_tool->set_outputs(SubstitutionList::MakeForTest(
|
| + "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
|
| + cc_tool->set_precompiled_header_type(Tool::PCH_GCC);
|
| + pch_toolchain.SetTool(Toolchain::TYPE_CC, cc_tool.Pass());
|
| + pch_toolchain.ToolchainSetupComplete();
|
| +
|
| + // This target doesn't specify precompiled headers.
|
| + {
|
| + Target no_pch_target(&pch_settings,
|
| + Label(SourceDir("//foo/"), "no_pch_target"));
|
| + no_pch_target.set_output_type(Target::SOURCE_SET);
|
| + no_pch_target.visibility().SetPublic();
|
| + no_pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
|
| + no_pch_target.sources().push_back(SourceFile("//foo/input2.c"));
|
| + no_pch_target.SetToolchain(&pch_toolchain);
|
| + ASSERT_TRUE(no_pch_target.OnResolved(&err));
|
| +
|
| + std::ostringstream out;
|
| + NinjaBinaryTargetWriter writer(&no_pch_target, out);
|
| + writer.Run();
|
| +
|
| + const char no_pch_expected[] =
|
| + "defines =\n"
|
| + "include_dirs =\n"
|
| + "cflags =\n"
|
| + "cflags_c =\n"
|
| + "cflags_cc =\n"
|
| + "target_output_name = no_pch_target\n"
|
| + "\n"
|
| + "build withpch/obj/foo/no_pch_target.input1.o: "
|
| + "withpch_cxx ../../foo/input1.cc\n"
|
| + "build withpch/obj/foo/no_pch_target.input2.o: "
|
| + "withpch_cc ../../foo/input2.c\n"
|
| + "\n"
|
| + "build withpch/obj/foo/no_pch_target.stamp: "
|
| + "withpch_stamp withpch/obj/foo/no_pch_target.input1.o "
|
| + "withpch/obj/foo/no_pch_target.input2.o\n";
|
| + EXPECT_EQ(no_pch_expected, out.str());
|
| + }
|
| +
|
| + // This target specifies PCH.
|
| + {
|
| + Target pch_target(&pch_settings,
|
| + Label(SourceDir("//foo/"), "pch_target"));
|
| + pch_target.config_values().set_precompiled_header("build/precompile.h");
|
| + pch_target.config_values().set_precompiled_source(
|
| + SourceFile("//build/precompile.h"));
|
| + pch_target.config_values().cflags_c().push_back("-std=c99");
|
| + pch_target.set_output_type(Target::SOURCE_SET);
|
| + pch_target.visibility().SetPublic();
|
| + pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
|
| + pch_target.sources().push_back(SourceFile("//foo/input2.c"));
|
| + pch_target.SetToolchain(&pch_toolchain);
|
| + ASSERT_TRUE(pch_target.OnResolved(&err));
|
| +
|
| + std::ostringstream out;
|
| + NinjaBinaryTargetWriter writer(&pch_target, out);
|
| + writer.Run();
|
| +
|
| + const char pch_gcc_expected[] =
|
| + "defines =\n"
|
| + "include_dirs =\n"
|
| + "cflags =\n"
|
| + "cflags_c = -std=c99 "
|
| + "-include withpch/obj/build/pch_target.precompile.h-c\n"
|
| + "cflags_cc = -include withpch/obj/build/pch_target.precompile.h-cc\n"
|
| + "target_output_name = pch_target\n"
|
| + "\n"
|
| + // Compile the precompiled sources with -x <lang>.
|
| + "build withpch/obj/build/pch_target.precompile.h-c.gch: "
|
| + "withpch_cc ../../build/precompile.h\n"
|
| + " cflags_c = -std=c99 -x c-header\n"
|
| + "\n"
|
| + "build withpch/obj/build/pch_target.precompile.h-cc.gch: "
|
| + "withpch_cxx ../../build/precompile.h\n"
|
| + " cflags_cc = -x c++-header\n"
|
| + "\n"
|
| + "build withpch/obj/foo/pch_target.input1.o: "
|
| + "withpch_cxx ../../foo/input1.cc | "
|
| + // Explicit dependency on the PCH build step.
|
| + "withpch/obj/build/pch_target.precompile.h-cc.gch\n"
|
| + "build withpch/obj/foo/pch_target.input2.o: "
|
| + "withpch_cc ../../foo/input2.c | "
|
| + // Explicit dependency on the PCH build step.
|
| + "withpch/obj/build/pch_target.precompile.h-c.gch\n"
|
| + "\n"
|
| + "build withpch/obj/foo/pch_target.stamp: "
|
| + "withpch_stamp withpch/obj/foo/pch_target.input1.o "
|
| + "withpch/obj/foo/pch_target.input2.o\n";
|
| + EXPECT_EQ(pch_gcc_expected, out.str());
|
| + }
|
| +}
|
| +
|
| // Should throw an error with the scheduler if a duplicate object file exists.
|
| // This is dependent on the toolchain's object file mapping.
|
| TEST(NinjaBinaryTargetWriter, DupeObjFileError) {
|
|
|