11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file.
41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <sstream>
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "tools/gn/ninja_binary_target_writer.h"
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "tools/gn/target.h"
101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "tools/gn/test_with_scope.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST(NinjaBinaryTargetWriter, SourceSet) {
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TestWithScope setup;
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  setup.settings()->set_target_os(Settings::WIN);
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  target.set_output_type(Target::SOURCE_SET);
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  target.visibility().SetPublic();
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input1.cc"));
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input2.cc"));
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Also test object files, which should be just passed through to the
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // dependents to link.
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input3.o"));
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input4.obj"));
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  target.SetToolchain(setup.toolchain());
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(target.OnResolved(&err));
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Source set itself.
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::ostringstream out;
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    NinjaBinaryTargetWriter writer(&target, out);
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    writer.Run();
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const char expected[] =
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "defines =\n"
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "include_dirs =\n"
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "cflags =\n"
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "cflags_c =\n"
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "cflags_cc =\n"
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "cflags_objc =\n"
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "cflags_objcc =\n"
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "root_out_dir = .\n"
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "target_out_dir = obj/foo\n"
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "target_output_name = bar\n"
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "\n"
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc\n"
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc\n"
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "\n"
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n";
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::string out_str = out.str();
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(expected, out_str);
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // A shared library that depends on the source set.
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Target shlib_target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  shlib_target.set_output_type(Target::SHARED_LIBRARY);
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  shlib_target.public_deps().push_back(LabelTargetPair(&target));
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  shlib_target.SetToolchain(setup.toolchain());
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(shlib_target.OnResolved(&err));
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::ostringstream out;
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    NinjaBinaryTargetWriter writer(&shlib_target, out);
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    writer.Run();
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const char expected[] =
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "defines =\n"
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "include_dirs =\n"
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "cflags =\n"
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "cflags_c =\n"
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "cflags_cc =\n"
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "cflags_objc =\n"
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "cflags_objcc =\n"
7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "root_out_dir = .\n"
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "target_out_dir = obj/foo\n"
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "target_output_name = libshlib\n"
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "\n"
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "\n"
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        // Ordering of the obj files here should come out in the order
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        // specified, with the target's first, followed by the source set's, in
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        // order.
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "build ./libshlib.so: solink obj/foo/bar.input1.o "
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n"
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "  ldflags =\n"
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "  libs =\n"
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "  output_extension = .so\n";
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::string out_str = out.str();
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(expected, out_str);
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // A static library that depends on the source set (should not link it).
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  Target stlib_target(setup.settings(), Label(SourceDir("//foo/"), "stlib"));
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  stlib_target.set_output_type(Target::STATIC_LIBRARY);
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  stlib_target.public_deps().push_back(LabelTargetPair(&target));
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  stlib_target.SetToolchain(setup.toolchain());
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(stlib_target.OnResolved(&err));
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  {
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    std::ostringstream out;
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    NinjaBinaryTargetWriter writer(&stlib_target, out);
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    writer.Run();
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const char expected[] =
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "defines =\n"
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "include_dirs =\n"
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "cflags =\n"
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "cflags_c =\n"
11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "cflags_cc =\n"
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "cflags_objc =\n"
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "cflags_objcc =\n"
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "root_out_dir = .\n"
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "target_out_dir = obj/foo\n"
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "target_output_name = libstlib\n"
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "\n"
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "\n"
12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        // There are no sources so there are no params to alink. (In practice
12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        // this will probably fail in the archive tool.)
12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "build obj/foo/libstlib.a: alink\n"
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "  ldflags =\n"
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "  libs =\n"
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "  output_extension = \n";
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    std::string out_str = out.str();
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(expected, out_str);
12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Make the static library 'complete', which means it should be linked.
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  stlib_target.set_complete_static_lib(true);
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  {
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::ostringstream out;
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    NinjaBinaryTargetWriter writer(&stlib_target, out);
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    writer.Run();
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char expected[] =
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "defines =\n"
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "include_dirs =\n"
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "cflags =\n"
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "cflags_c =\n"
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "cflags_cc =\n"
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "cflags_objc =\n"
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "cflags_objcc =\n"
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "root_out_dir = .\n"
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "target_out_dir = obj/foo\n"
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "target_output_name = libstlib\n"
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "\n"
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "\n"
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        // Ordering of the obj files here should come out in the order
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        // specified, with the target's first, followed by the source set's, in
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        // order.
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "build obj/foo/libstlib.a: alink obj/foo/bar.input1.o "
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n"
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "  ldflags =\n"
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "  libs =\n"
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "  output_extension = \n";
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string out_str = out.str();
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(expected, out_str);
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// This tests that output extension overrides apply, and input dependencies
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// are applied.
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(NinjaBinaryTargetWriter, ProductExtensionAndInputDeps) {
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestWithScope setup;
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  setup.settings()->set_target_os(Settings::LINUX);
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // An action for our library to depend on.
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Target action(setup.settings(), Label(SourceDir("//foo/"), "action"));
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  action.set_output_type(Target::ACTION_FOREACH);
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  action.visibility().SetPublic();
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  action.SetToolchain(setup.toolchain());
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(action.OnResolved(&err));
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // A shared library w/ the product_extension set to a custom value.
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  target.set_output_type(Target::SHARED_LIBRARY);
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  target.set_output_extension(std::string("so.6"));
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input1.cc"));
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input2.cc"));
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  target.public_deps().push_back(LabelTargetPair(&action));
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  target.SetToolchain(setup.toolchain());
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(target.OnResolved(&err));
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::ostringstream out;
19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NinjaBinaryTargetWriter writer(&target, out);
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  writer.Run();
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const char expected[] =
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "defines =\n"
19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "include_dirs =\n"
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "cflags =\n"
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "cflags_c =\n"
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "cflags_cc =\n"
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "cflags_objc =\n"
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "cflags_objcc =\n"
20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "root_out_dir = .\n"
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "target_out_dir = obj/foo\n"
20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "target_output_name = libshlib\n"
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "\n"
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "build obj/foo/shlib.inputdeps.stamp: stamp obj/foo/action.stamp\n"
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "build obj/foo/libshlib.input1.o: cxx ../../foo/input1.cc"
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        " || obj/foo/shlib.inputdeps.stamp\n"
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "build obj/foo/libshlib.input2.o: cxx ../../foo/input2.cc"
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        " || obj/foo/shlib.inputdeps.stamp\n"
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "\n"
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "build ./libshlib.so.6: solink obj/foo/libshlib.input1.o "
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // The order-only dependency here is stricly unnecessary since the
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // sources list this as an order-only dep. See discussion in the code
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // that writes this.
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "obj/foo/libshlib.input2.o || obj/foo/action.stamp\n"
21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "  ldflags =\n"
21703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "  libs =\n"
21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "  output_extension = .so.6\n";
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string out_str = out.str();
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(expected, out_str);
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(NinjaBinaryTargetWriter, EmptyProductExtension) {
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestWithScope setup;
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  setup.settings()->set_target_os(Settings::LINUX);
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This test is the same as ProductExtension, except that
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // we call set_output_extension("") and ensure that we still get the default.
233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  target.set_output_type(Target::SHARED_LIBRARY);
235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  target.set_output_extension(std::string());
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input1.cc"));
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input2.cc"));
238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  target.SetToolchain(setup.toolchain());
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(target.OnResolved(&err));
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::ostringstream out;
24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NinjaBinaryTargetWriter writer(&target, out);
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  writer.Run();
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const char expected[] =
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "defines =\n"
24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "include_dirs =\n"
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "cflags =\n"
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "cflags_c =\n"
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "cflags_cc =\n"
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "cflags_objc =\n"
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "cflags_objcc =\n"
25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "root_out_dir = .\n"
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "target_out_dir = obj/foo\n"
25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "target_output_name = libshlib\n"
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "\n"
25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "build obj/foo/libshlib.input1.o: cxx ../../foo/input1.cc\n"
25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "build obj/foo/libshlib.input2.o: cxx ../../foo/input2.cc\n"
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "\n"
26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "build ./libshlib.so: solink obj/foo/libshlib.input1.o "
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          "obj/foo/libshlib.input2.o\n"
26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "  ldflags =\n"
26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "  libs =\n"
26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      "  output_extension = .so\n";
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string out_str = out.str();
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(expected, out_str);
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
270