1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file. 4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <algorithm> 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <sstream> 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "tools/gn/ninja_action_target_writer.h" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "tools/gn/substitution_list.h" 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "tools/gn/target.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "tools/gn/test_with_scope.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST(NinjaActionTargetWriter, WriteOutputFilesForBuildLine) { 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) TestWithScope setup; 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Err err; 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target.set_output_type(Target::ACTION_FOREACH); 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.action_values().outputs() = SubstitutionList::MakeForTest( 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "//out/Debug/gen/a b{{source_name_part}}.h", 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "//out/Debug/gen/{{source_name_part}}.cc"); 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target.SetToolchain(setup.toolchain()); 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(target.OnResolved(&err)); 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::ostringstream out; 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaActionTargetWriter writer(&target, out); 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SourceFile source("//foo/bar.in"); 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::vector<OutputFile> output_files; 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) writer.WriteOutputFilesForBuildLine(source, &output_files); 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(" gen/a$ bbar.h gen/bar.cc", out.str()); 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Tests an action with no sources. 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST(NinjaActionTargetWriter, ActionNoSources) { 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) TestWithScope setup; 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Err err; 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); 466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) target.set_output_type(Target::ACTION); 476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) target.action_values().set_script(SourceFile("//foo/script.py")); 496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) target.inputs().push_back(SourceFile("//foo/included.txt")); 506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) target.action_values().outputs() = 526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SubstitutionList::MakeForTest("//out/Debug/foo.out"); 536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target.SetToolchain(setup.toolchain()); 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(target.OnResolved(&err)); 5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) setup.settings()->set_target_os(Settings::LINUX); 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "/usr/bin/python"))); 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::ostringstream out; 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaActionTargetWriter writer(&target, out); 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) writer.Run(); 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const char expected[] = 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "rule __foo_bar___rule\n" 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) " command = /usr/bin/python ../../foo/script.py\n" 686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) " description = ACTION //foo:bar()\n" 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) " restat = 1\n" 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "../../foo/included.txt\n" 726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "\n" 736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n" 746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "\n" 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "build obj/foo/bar.stamp: stamp foo.out\n"; 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(expected, out.str()); 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Makes sure that we write sources as input dependencies for actions with 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// both sources and inputs (ACTION_FOREACH treats the sources differently). 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST(NinjaActionTargetWriter, ActionWithSources) { 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) TestWithScope setup; 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Err err; 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); 8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) target.set_output_type(Target::ACTION); 8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) target.action_values().set_script(SourceFile("//foo/script.py")); 9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) target.sources().push_back(SourceFile("//foo/source.txt")); 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) target.inputs().push_back(SourceFile("//foo/included.txt")); 9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.action_values().outputs() = 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SubstitutionList::MakeForTest("//out/Debug/foo.out"); 9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target.SetToolchain(setup.toolchain()); 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(target.OnResolved(&err)); 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Posix. 10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) { 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) setup.settings()->set_target_os(Settings::LINUX); 10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "/usr/bin/python"))); 10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::ostringstream out; 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaActionTargetWriter writer(&target, out); 10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) writer.Run(); 10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const char expected_linux[] = 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "rule __foo_bar___rule\n" 11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) " command = /usr/bin/python ../../foo/script.py\n" 11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) " description = ACTION //foo:bar()\n" 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) " restat = 1\n" 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "../../foo/included.txt ../../foo/source.txt\n" 11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "\n" 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n" 11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "\n" 12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "build obj/foo/bar.stamp: stamp foo.out\n"; 12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(expected_linux, out.str()); 12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Windows. 12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) { 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Note: we use forward slashes here so that the output will be the same on 12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Linux and Windows. 12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "C:/python/python.exe"))); 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) setup.settings()->set_target_os(Settings::WIN); 13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::ostringstream out; 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaActionTargetWriter writer(&target, out); 13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) writer.Run(); 13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const char expected_win[] = 13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "rule __foo_bar___rule\n" 1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu " command = C$:/python/python.exe gyp-win-tool action-wrapper environment.x86 __foo_bar___rule.$unique_name.rsp\n" 13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) " description = ACTION //foo:bar()\n" 14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) " restat = 1\n" 14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) " rspfile = __foo_bar___rule.$unique_name.rsp\n" 1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu " rspfile_content = C$:/python/python.exe ../../foo/script.py\n" 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "../../foo/included.txt ../../foo/source.txt\n" 14523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "\n" 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n" 14723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "\n" 14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "build obj/foo/bar.stamp: stamp foo.out\n"; 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(expected_win, out.str()); 15023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 15223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST(NinjaActionTargetWriter, ForEach) { 15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) TestWithScope setup; 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Err err; 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 15723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Some dependencies that the action can depend on. Use actions for these 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // so they have a nice platform-independent stamp file that can appear in the 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // output (rather than having to worry about how the current platform names 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // binaries). 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Target dep(setup.settings(), Label(SourceDir("//foo/"), "dep")); 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dep.set_output_type(Target::ACTION); 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dep.visibility().SetPublic(); 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dep.SetToolchain(setup.toolchain()); 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(dep.OnResolved(&err)); 16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Target datadep(setup.settings(), Label(SourceDir("//foo/"), "datadep")); 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) datadep.set_output_type(Target::ACTION); 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci datadep.visibility().SetPublic(); 17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) datadep.SetToolchain(setup.toolchain()); 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(datadep.OnResolved(&err)); 174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); 17623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) target.set_output_type(Target::ACTION_FOREACH); 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci target.private_deps().push_back(LabelTargetPair(&dep)); 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci target.data_deps().push_back(LabelTargetPair(&datadep)); 179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) target.sources().push_back(SourceFile("//foo/input1.txt")); 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) target.sources().push_back(SourceFile("//foo/input2.txt")); 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) target.action_values().set_script(SourceFile("//foo/script.py")); 184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.action_values().args() = SubstitutionList::MakeForTest( 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "-i", 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "{{source}}", 188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "--out=foo bar{{source_name_part}}.o"); 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.action_values().outputs() = SubstitutionList::MakeForTest( 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "//out/Debug/{{source_name_part}}.out"); 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) target.inputs().push_back(SourceFile("//foo/included.txt")); 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target.SetToolchain(setup.toolchain()); 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(target.OnResolved(&err)); 19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Posix. 198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) { 199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) setup.settings()->set_target_os(Settings::LINUX); 2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "/usr/bin/python"))); 202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::ostringstream out; 20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaActionTargetWriter writer(&target, out); 205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) writer.Run(); 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const char expected_linux[] = 208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "rule __foo_bar___rule\n" 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) " command = /usr/bin/python ../../foo/script.py -i ${in} " 21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Escaping is different between Windows and Posix. 21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_WIN) 2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "\"--out=foo$ bar${source_name_part}.o\"\n" 21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else 21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) "--out=foo\\$ bar${source_name_part}.o\n" 21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 21623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) " description = ACTION //foo:bar()\n" 217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) " restat = 1\n" 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "../../foo/included.txt obj/foo/dep.stamp\n" 220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "\n" 2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "build input1.out: __foo_bar___rule ../../foo/input1.txt | " 222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "obj/foo/bar.inputdeps.stamp\n" 223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) " source_name_part = input1\n" 2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "build input2.out: __foo_bar___rule ../../foo/input2.txt | " 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "obj/foo/bar.inputdeps.stamp\n" 226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) " source_name_part = input2\n" 227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "\n" 228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "build obj/foo/bar.stamp: " 22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "stamp input1.out input2.out || obj/foo/datadep.stamp\n"; 230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string out_str = out.str(); 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_WIN) 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::replace(out_str.begin(), out_str.end(), '\\', '/'); 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(expected_linux, out_str); 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Windows. 239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) { 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "C:/python/python.exe"))); 242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) setup.settings()->set_target_os(Settings::WIN); 243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::ostringstream out; 24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaActionTargetWriter writer(&target, out); 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) writer.Run(); 247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const char expected_win[] = 249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "rule __foo_bar___rule\n" 2505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu " command = C$:/python/python.exe gyp-win-tool action-wrapper " 2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "environment.x86 __foo_bar___rule.$unique_name.rsp\n" 25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) " description = ACTION //foo:bar()\n" 253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) " restat = 1\n" 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) " rspfile = __foo_bar___rule.$unique_name.rsp\n" 2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu " rspfile_content = C$:/python/python.exe ../../foo/script.py -i " 25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_WIN) 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "${in} \"--out=foo$ bar${source_name_part}.o\"\n" 25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "${in} --out=foo\\$ bar${source_name_part}.o\n" 26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "../../foo/included.txt obj/foo/dep.stamp\n" 263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "\n" 2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "build input1.out: __foo_bar___rule ../../foo/input1.txt | " 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "obj/foo/bar.inputdeps.stamp\n" 266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) " unique_name = 0\n" 267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) " source_name_part = input1\n" 2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "build input2.out: __foo_bar___rule ../../foo/input2.txt | " 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "obj/foo/bar.inputdeps.stamp\n" 270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) " unique_name = 1\n" 271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) " source_name_part = input2\n" 272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "\n" 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "build obj/foo/bar.stamp: " 27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "stamp input1.out input2.out || obj/foo/datadep.stamp\n"; 27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(expected_win, out.str()); 276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 27923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST(NinjaActionTargetWriter, ForEachWithDepfile) { 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TestWithScope setup; 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Err err; 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); 28523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) target.set_output_type(Target::ACTION_FOREACH); 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) target.sources().push_back(SourceFile("//foo/input1.txt")); 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) target.sources().push_back(SourceFile("//foo/input2.txt")); 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 29023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) target.action_values().set_script(SourceFile("//foo/script.py")); 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target.SetToolchain(setup.toolchain()); 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(target.OnResolved(&err)); 29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SubstitutionPattern depfile; 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_TRUE( 2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) depfile.Parse("//out/Debug/gen/{{source_name_part}}.d", NULL, &err)); 2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.action_values().set_depfile(depfile); 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.action_values().args() = SubstitutionList::MakeForTest( 3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "-i", 3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "{{source}}", 3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "--out=foo bar{{source_name_part}}.o"); 3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.action_values().outputs() = SubstitutionList::MakeForTest( 305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "//out/Debug/{{source_name_part}}.out"); 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) target.inputs().push_back(SourceFile("//foo/included.txt")); 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Posix. 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) setup.settings()->set_target_os(Settings::LINUX); 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "/usr/bin/python"))); 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::ostringstream out; 31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaActionTargetWriter writer(&target, out); 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) writer.Run(); 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char expected_linux[] = 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "rule __foo_bar___rule\n" 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) " command = /usr/bin/python ../../foo/script.py -i ${in} " 32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_WIN) 323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "\"--out=foo$ bar${source_name_part}.o\"\n" 32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else 32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) "--out=foo\\$ bar${source_name_part}.o\n" 32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 32723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) " description = ACTION //foo:bar()\n" 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " restat = 1\n" 329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "../../foo/included.txt\n" 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "\n" 332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "build input1.out: __foo_bar___rule ../../foo/input1.txt" 333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) " | obj/foo/bar.inputdeps.stamp\n" 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " source_name_part = input1\n" 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " depfile = gen/input1.d\n" 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "build input2.out: __foo_bar___rule ../../foo/input2.txt" 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) " | obj/foo/bar.inputdeps.stamp\n" 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " source_name_part = input2\n" 339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " depfile = gen/input2.d\n" 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "\n" 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; 34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(expected_linux, out.str()); 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Windows. 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "C:/python/python.exe"))); 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) setup.settings()->set_target_os(Settings::WIN); 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::ostringstream out; 35203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaActionTargetWriter writer(&target, out); 353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) writer.Run(); 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char expected_win[] = 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "rule __foo_bar___rule\n" 3575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu " command = C$:/python/python.exe gyp-win-tool action-wrapper " 358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "environment.x86 __foo_bar___rule.$unique_name.rsp\n" 35923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) " description = ACTION //foo:bar()\n" 360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " restat = 1\n" 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " rspfile = __foo_bar___rule.$unique_name.rsp\n" 3625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu " rspfile_content = C$:/python/python.exe ../../foo/script.py -i " 36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_WIN) 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "${in} \"--out=foo$ bar${source_name_part}.o\"\n" 36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else 3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "${in} --out=foo\\$ bar${source_name_part}.o\n" 36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "../../foo/included.txt\n" 370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "\n" 371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "build input1.out: __foo_bar___rule ../../foo/input1.txt" 372010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) " | obj/foo/bar.inputdeps.stamp\n" 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " unique_name = 0\n" 374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " source_name_part = input1\n" 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " depfile = gen/input1.d\n" 376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "build input2.out: __foo_bar___rule ../../foo/input2.txt" 377010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) " | obj/foo/bar.inputdeps.stamp\n" 378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " unique_name = 1\n" 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " source_name_part = input2\n" 380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) " depfile = gen/input2.d\n" 381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "\n" 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; 38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(expected_win, out.str()); 384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 386