Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Side by Side Diff: tools/gn/ninja_binary_target_writer_unittest.cc

Issue 1292983004: [GN]: Precompiled header support for GCC. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/ninja_binary_target_writer.cc ('k') | tools/gn/substitution_type.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <sstream> 5 #include <sstream>
6 6
7 #include "testing/gtest/include/gtest/gtest.h" 7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "tools/gn/ninja_binary_target_writer.h" 8 #include "tools/gn/ninja_binary_target_writer.h"
9 #include "tools/gn/scheduler.h" 9 #include "tools/gn/scheduler.h"
10 #include "tools/gn/target.h" 10 #include "tools/gn/target.h"
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 // Declare a C++ compiler that supports PCH. 381 // Declare a C++ compiler that supports PCH.
382 scoped_ptr<Tool> cxx_tool(new Tool); 382 scoped_ptr<Tool> cxx_tool(new Tool);
383 TestWithScope::SetCommandForTool( 383 TestWithScope::SetCommandForTool(
384 "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} " 384 "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} "
385 "-o {{output}}", 385 "-o {{output}}",
386 cxx_tool.get()); 386 cxx_tool.get());
387 cxx_tool->set_outputs(SubstitutionList::MakeForTest( 387 cxx_tool->set_outputs(SubstitutionList::MakeForTest(
388 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o")); 388 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
389 cxx_tool->set_precompiled_header_type(Tool::PCH_MSVC); 389 cxx_tool->set_precompiled_header_type(Tool::PCH_MSVC);
390 pch_toolchain.SetTool(Toolchain::TYPE_CXX, cxx_tool.Pass()); 390 pch_toolchain.SetTool(Toolchain::TYPE_CXX, cxx_tool.Pass());
391
392 // Add a C compiler as well.
393 scoped_ptr<Tool> cc_tool(new Tool);
394 TestWithScope::SetCommandForTool(
395 "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} "
396 "-o {{output}}",
397 cc_tool.get());
398 cc_tool->set_outputs(SubstitutionList::MakeForTest(
399 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
400 cc_tool->set_precompiled_header_type(Tool::PCH_MSVC);
401 pch_toolchain.SetTool(Toolchain::TYPE_CC, cc_tool.Pass());
391 pch_toolchain.ToolchainSetupComplete(); 402 pch_toolchain.ToolchainSetupComplete();
392 403
393 // This target doesn't specify precompiled headers. 404 // This target doesn't specify precompiled headers.
394 { 405 {
395 Target no_pch_target(&pch_settings, 406 Target no_pch_target(&pch_settings,
396 Label(SourceDir("//foo/"), "no_pch_target")); 407 Label(SourceDir("//foo/"), "no_pch_target"));
397 no_pch_target.set_output_type(Target::SOURCE_SET); 408 no_pch_target.set_output_type(Target::SOURCE_SET);
398 no_pch_target.visibility().SetPublic(); 409 no_pch_target.visibility().SetPublic();
399 no_pch_target.sources().push_back(SourceFile("//foo/input1.cc")); 410 no_pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
411 no_pch_target.sources().push_back(SourceFile("//foo/input2.c"));
400 no_pch_target.SetToolchain(&pch_toolchain); 412 no_pch_target.SetToolchain(&pch_toolchain);
401 ASSERT_TRUE(no_pch_target.OnResolved(&err)); 413 ASSERT_TRUE(no_pch_target.OnResolved(&err));
402 414
403 std::ostringstream out; 415 std::ostringstream out;
404 NinjaBinaryTargetWriter writer(&no_pch_target, out); 416 NinjaBinaryTargetWriter writer(&no_pch_target, out);
405 writer.Run(); 417 writer.Run();
406 418
407 const char no_pch_expected[] = 419 const char no_pch_expected[] =
408 "defines =\n" 420 "defines =\n"
409 "include_dirs =\n" 421 "include_dirs =\n"
410 "cflags =\n" 422 "cflags =\n"
423 "cflags_c =\n"
411 "cflags_cc =\n" 424 "cflags_cc =\n"
412 "target_output_name = no_pch_target\n" 425 "target_output_name = no_pch_target\n"
413 "\n" 426 "\n"
414 "build withpch/obj/foo/no_pch_target.input1.o: " 427 "build withpch/obj/foo/no_pch_target.input1.o: "
415 "withpch_cxx ../../foo/input1.cc\n" 428 "withpch_cxx ../../foo/input1.cc\n"
429 "build withpch/obj/foo/no_pch_target.input2.o: "
430 "withpch_cc ../../foo/input2.c\n"
416 "\n" 431 "\n"
417 "build withpch/obj/foo/no_pch_target.stamp: " 432 "build withpch/obj/foo/no_pch_target.stamp: "
418 "withpch_stamp withpch/obj/foo/no_pch_target.input1.o\n"; 433 "withpch_stamp withpch/obj/foo/no_pch_target.input1.o "
434 "withpch/obj/foo/no_pch_target.input2.o\n";
419 EXPECT_EQ(no_pch_expected, out.str()); 435 EXPECT_EQ(no_pch_expected, out.str());
420 } 436 }
421 437
422 // This target specifies PCH. 438 // This target specifies PCH.
423 { 439 {
424 Target pch_target(&pch_settings, 440 Target pch_target(&pch_settings,
425 Label(SourceDir("//foo/"), "pch_target")); 441 Label(SourceDir("//foo/"), "pch_target"));
426 pch_target.config_values().set_precompiled_header("build/precompile.h"); 442 pch_target.config_values().set_precompiled_header("build/precompile.h");
427 pch_target.config_values().set_precompiled_source( 443 pch_target.config_values().set_precompiled_source(
428 SourceFile("//build/precompile.cc")); 444 SourceFile("//build/precompile.cc"));
429 pch_target.set_output_type(Target::SOURCE_SET); 445 pch_target.set_output_type(Target::SOURCE_SET);
430 pch_target.visibility().SetPublic(); 446 pch_target.visibility().SetPublic();
431 pch_target.sources().push_back(SourceFile("//foo/input1.cc")); 447 pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
448 pch_target.sources().push_back(SourceFile("//foo/input2.c"));
432 pch_target.SetToolchain(&pch_toolchain); 449 pch_target.SetToolchain(&pch_toolchain);
433 ASSERT_TRUE(pch_target.OnResolved(&err)); 450 ASSERT_TRUE(pch_target.OnResolved(&err));
434 451
435 std::ostringstream out; 452 std::ostringstream out;
436 NinjaBinaryTargetWriter writer(&pch_target, out); 453 NinjaBinaryTargetWriter writer(&pch_target, out);
437 writer.Run(); 454 writer.Run();
438 455
439 const char pch_win_expected[] = 456 const char pch_win_expected[] =
440 "defines =\n" 457 "defines =\n"
441 "include_dirs =\n" 458 "include_dirs =\n"
442 "cflags =\n" 459 "cflags =\n"
443 // There should only be one .pch file created, for C++ files. 460 // It should output language-specific pch files.
461 "cflags_c = /Fpwithpch/obj/foo/pch_target_c.pch "
462 "/Yubuild/precompile.h\n"
444 "cflags_cc = /Fpwithpch/obj/foo/pch_target_cc.pch " 463 "cflags_cc = /Fpwithpch/obj/foo/pch_target_cc.pch "
445 "/Yubuild/precompile.h\n" 464 "/Yubuild/precompile.h\n"
446 "target_output_name = pch_target\n" 465 "target_output_name = pch_target\n"
447 "\n" 466 "\n"
448 // Compile the precompiled source file with /Yc. 467 // Compile the precompiled source files with /Yc.
468 "build withpch/obj/build/pch_target.precompile.c.o: "
469 "withpch_cc ../../build/precompile.cc\n"
470 " cflags_c = ${cflags_c} /Ycbuild/precompile.h\n"
471 "\n"
449 "build withpch/obj/build/pch_target.precompile.cc.o: " 472 "build withpch/obj/build/pch_target.precompile.cc.o: "
450 "withpch_cxx ../../build/precompile.cc\n" 473 "withpch_cxx ../../build/precompile.cc\n"
451 " cflags_cc = ${cflags_cc} /Ycbuild/precompile.h\n" 474 " cflags_cc = ${cflags_cc} /Ycbuild/precompile.h\n"
452 "\n" 475 "\n"
453 "build withpch/obj/foo/pch_target.input1.o: " 476 "build withpch/obj/foo/pch_target.input1.o: "
454 "withpch_cxx ../../foo/input1.cc | " 477 "withpch_cxx ../../foo/input1.cc | "
455 // Explicit dependency on the PCH build step. 478 // Explicit dependency on the PCH build step.
456 "withpch/obj/build/pch_target.precompile.cc.o\n" 479 "withpch/obj/build/pch_target.precompile.cc.o\n"
480 "build withpch/obj/foo/pch_target.input2.o: "
481 "withpch_cc ../../foo/input2.c | "
482 // Explicit dependency on the PCH build step.
483 "withpch/obj/build/pch_target.precompile.c.o\n"
484 "\n"
485 "build withpch/obj/foo/pch_target.stamp: withpch_stamp "
486 "withpch/obj/foo/pch_target.input1.o "
487 "withpch/obj/foo/pch_target.input2.o "
488 // The precompiled object files were added to the outputs.
489 "withpch/obj/build/pch_target.precompile.c.o "
490 "withpch/obj/build/pch_target.precompile.cc.o\n";
491 EXPECT_EQ(pch_win_expected, out.str());
492 }
493 }
494
495 TEST(NinjaBinaryTargetWriter, GCCPrecompiledHeaders) {
496 Err err;
497
498 // This setup's toolchain does not have precompiled headers defined.
499 TestWithScope setup;
500
501 // A precompiled header toolchain.
502 Settings pch_settings(setup.build_settings(), "withpch/");
503 Toolchain pch_toolchain(&pch_settings,
504 Label(SourceDir("//toolchain/"), "withpch"));
505 pch_settings.set_toolchain_label(pch_toolchain.label());
506 pch_settings.set_default_toolchain_label(setup.toolchain()->label());
507
508 // Declare a C++ compiler that supports PCH.
509 scoped_ptr<Tool> cxx_tool(new Tool);
510 TestWithScope::SetCommandForTool(
511 "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} "
512 "-o {{output}}",
513 cxx_tool.get());
514 cxx_tool->set_outputs(SubstitutionList::MakeForTest(
515 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
516 cxx_tool->set_precompiled_header_type(Tool::PCH_GCC);
517 pch_toolchain.SetTool(Toolchain::TYPE_CXX, cxx_tool.Pass());
518 pch_toolchain.ToolchainSetupComplete();
519
520 // Add a C compiler as well.
521 scoped_ptr<Tool> cc_tool(new Tool);
522 TestWithScope::SetCommandForTool(
523 "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} "
524 "-o {{output}}",
525 cc_tool.get());
526 cc_tool->set_outputs(SubstitutionList::MakeForTest(
527 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
528 cc_tool->set_precompiled_header_type(Tool::PCH_GCC);
529 pch_toolchain.SetTool(Toolchain::TYPE_CC, cc_tool.Pass());
530 pch_toolchain.ToolchainSetupComplete();
531
532 // This target doesn't specify precompiled headers.
533 {
534 Target no_pch_target(&pch_settings,
535 Label(SourceDir("//foo/"), "no_pch_target"));
536 no_pch_target.set_output_type(Target::SOURCE_SET);
537 no_pch_target.visibility().SetPublic();
538 no_pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
539 no_pch_target.sources().push_back(SourceFile("//foo/input2.c"));
540 no_pch_target.SetToolchain(&pch_toolchain);
541 ASSERT_TRUE(no_pch_target.OnResolved(&err));
542
543 std::ostringstream out;
544 NinjaBinaryTargetWriter writer(&no_pch_target, out);
545 writer.Run();
546
547 const char no_pch_expected[] =
548 "defines =\n"
549 "include_dirs =\n"
550 "cflags =\n"
551 "cflags_c =\n"
552 "cflags_cc =\n"
553 "target_output_name = no_pch_target\n"
554 "\n"
555 "build withpch/obj/foo/no_pch_target.input1.o: "
556 "withpch_cxx ../../foo/input1.cc\n"
557 "build withpch/obj/foo/no_pch_target.input2.o: "
558 "withpch_cc ../../foo/input2.c\n"
559 "\n"
560 "build withpch/obj/foo/no_pch_target.stamp: "
561 "withpch_stamp withpch/obj/foo/no_pch_target.input1.o "
562 "withpch/obj/foo/no_pch_target.input2.o\n";
563 EXPECT_EQ(no_pch_expected, out.str());
564 }
565
566 // This target specifies PCH.
567 {
568 Target pch_target(&pch_settings,
569 Label(SourceDir("//foo/"), "pch_target"));
570 pch_target.config_values().set_precompiled_header("build/precompile.h");
571 pch_target.config_values().set_precompiled_source(
572 SourceFile("//build/precompile.h"));
573 pch_target.config_values().cflags_c().push_back("-std=c99");
574 pch_target.set_output_type(Target::SOURCE_SET);
575 pch_target.visibility().SetPublic();
576 pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
577 pch_target.sources().push_back(SourceFile("//foo/input2.c"));
578 pch_target.SetToolchain(&pch_toolchain);
579 ASSERT_TRUE(pch_target.OnResolved(&err));
580
581 std::ostringstream out;
582 NinjaBinaryTargetWriter writer(&pch_target, out);
583 writer.Run();
584
585 const char pch_gcc_expected[] =
586 "defines =\n"
587 "include_dirs =\n"
588 "cflags =\n"
589 "cflags_c = -std=c99 "
590 "-include withpch/obj/build/pch_target.precompile.h-c\n"
591 "cflags_cc = -include withpch/obj/build/pch_target.precompile.h-cc\n"
592 "target_output_name = pch_target\n"
593 "\n"
594 // Compile the precompiled sources with -x <lang>.
595 "build withpch/obj/build/pch_target.precompile.h-c.gch: "
596 "withpch_cc ../../build/precompile.h\n"
597 " cflags_c = -std=c99 -x c-header\n"
598 "\n"
599 "build withpch/obj/build/pch_target.precompile.h-cc.gch: "
600 "withpch_cxx ../../build/precompile.h\n"
601 " cflags_cc = -x c++-header\n"
602 "\n"
603 "build withpch/obj/foo/pch_target.input1.o: "
604 "withpch_cxx ../../foo/input1.cc | "
605 // Explicit dependency on the PCH build step.
606 "withpch/obj/build/pch_target.precompile.h-cc.gch\n"
607 "build withpch/obj/foo/pch_target.input2.o: "
608 "withpch_cc ../../foo/input2.c | "
609 // Explicit dependency on the PCH build step.
610 "withpch/obj/build/pch_target.precompile.h-c.gch\n"
457 "\n" 611 "\n"
458 "build withpch/obj/foo/pch_target.stamp: " 612 "build withpch/obj/foo/pch_target.stamp: "
459 "withpch_stamp withpch/obj/foo/pch_target.input1.o " 613 "withpch_stamp withpch/obj/foo/pch_target.input1.o "
460 // The precompiled object file was added to the outputs. 614 "withpch/obj/foo/pch_target.input2.o\n";
461 "withpch/obj/build/pch_target.precompile.cc.o\n"; 615 EXPECT_EQ(pch_gcc_expected, out.str());
462 EXPECT_EQ(pch_win_expected, out.str());
463 } 616 }
464 } 617 }
465 618
466 // Should throw an error with the scheduler if a duplicate object file exists. 619 // Should throw an error with the scheduler if a duplicate object file exists.
467 // This is dependent on the toolchain's object file mapping. 620 // This is dependent on the toolchain's object file mapping.
468 TEST(NinjaBinaryTargetWriter, DupeObjFileError) { 621 TEST(NinjaBinaryTargetWriter, DupeObjFileError) {
469 Scheduler scheduler; 622 Scheduler scheduler;
470 623
471 TestWithScope setup; 624 TestWithScope setup;
472 TestTarget target(setup, "//foo:bar", Target::EXECUTABLE); 625 TestTarget target(setup, "//foo:bar", Target::EXECUTABLE);
473 target.sources().push_back(SourceFile("//a.cc")); 626 target.sources().push_back(SourceFile("//a.cc"));
474 target.sources().push_back(SourceFile("//a.cc")); 627 target.sources().push_back(SourceFile("//a.cc"));
475 628
476 EXPECT_FALSE(scheduler.is_failed()); 629 EXPECT_FALSE(scheduler.is_failed());
477 630
478 std::ostringstream out; 631 std::ostringstream out;
479 NinjaBinaryTargetWriter writer(&target, out); 632 NinjaBinaryTargetWriter writer(&target, out);
480 writer.Run(); 633 writer.Run();
481 634
482 // Should have issued an error. 635 // Should have issued an error.
483 EXPECT_TRUE(scheduler.is_failed()); 636 EXPECT_TRUE(scheduler.is_failed());
484 } 637 }
OLDNEW
« no previous file with comments | « tools/gn/ninja_binary_target_writer.cc ('k') | tools/gn/substitution_type.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698