Home | History | Annotate | Download | only in gn
      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
      3 // found in the LICENSE file.
      4 
      5 #include <sstream>
      6 
      7 #include "testing/gtest/include/gtest/gtest.h"
      8 #include "tools/gn/ninja_binary_target_writer.h"
      9 #include "tools/gn/test_with_scope.h"
     10 
     11 TEST(NinjaBinaryTargetWriter, SourceSet) {
     12   TestWithScope setup;
     13   setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
     14   setup.settings()->set_target_os(Settings::WIN);
     15 
     16   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
     17   target.set_output_type(Target::SOURCE_SET);
     18   target.sources().push_back(SourceFile("//foo/input1.cc"));
     19   target.sources().push_back(SourceFile("//foo/input2.cc"));
     20   // Also test object files, which should be just passed through to the
     21   // dependents to link.
     22   target.sources().push_back(SourceFile("//foo/input3.o"));
     23   target.sources().push_back(SourceFile("//foo/input4.obj"));
     24   target.OnResolved();
     25 
     26   // Source set itself.
     27   {
     28     std::ostringstream out;
     29     NinjaBinaryTargetWriter writer(&target, setup.toolchain(), out);
     30     writer.Run();
     31 
     32     // TODO(brettw) I think we'll need to worry about backslashes here
     33     // depending if we're on actual Windows or Linux pretending to be Windows.
     34     const char expected_win[] =
     35         "defines =\n"
     36         "includes =\n"
     37         "cflags =\n"
     38         "cflags_c =\n"
     39         "cflags_cc =\n"
     40         "cflags_objc =\n"
     41         "cflags_objcc =\n"
     42         "\n"
     43         "build obj/foo/bar.input1.obj: cxx ../../foo/input1.cc\n"
     44         "build obj/foo/bar.input2.obj: cxx ../../foo/input2.cc\n"
     45         "\n"
     46         "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.obj "
     47             "obj/foo/bar.input2.obj ../../foo/input3.o ../../foo/input4.obj\n";
     48     std::string out_str = out.str();
     49 #if defined(OS_WIN)
     50     std::replace(out_str.begin(), out_str.end(), '\\', '/');
     51 #endif
     52     EXPECT_EQ(expected_win, out_str);
     53   }
     54 
     55   // A shared library that depends on the source set.
     56   Target shlib_target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
     57   shlib_target.set_output_type(Target::SHARED_LIBRARY);
     58   shlib_target.deps().push_back(LabelTargetPair(&target));
     59   shlib_target.OnResolved();
     60 
     61   {
     62     std::ostringstream out;
     63     NinjaBinaryTargetWriter writer(&shlib_target, setup.toolchain(), out);
     64     writer.Run();
     65 
     66     // TODO(brettw) I think we'll need to worry about backslashes here
     67     // depending if we're on actual Windows or Linux pretending to be Windows.
     68     const char expected_win[] =
     69         "defines =\n"
     70         "includes =\n"
     71         "cflags =\n"
     72         "cflags_c =\n"
     73         "cflags_cc =\n"
     74         "cflags_objc =\n"
     75         "cflags_objcc =\n"
     76         "\n"
     77         "\n"
     78         "manifests = obj/foo/shlib.intermediate.manifest\n"
     79         "ldflags = /MANIFEST /ManifestFile:obj/foo/shlib.intermediate."
     80             "manifest\n"
     81         "libs =\n"
     82         // Ordering of the obj files here is arbitrary. Currently they're put
     83         // in a set and come out sorted.
     84         "build shlib.dll shlib.dll.lib: solink ../../foo/input3.o "
     85             "../../foo/input4.obj obj/foo/bar.input1.obj "
     86             "obj/foo/bar.input2.obj\n"
     87         "  soname = shlib.dll\n"
     88         "  lib = shlib.dll\n"
     89         "  dll = shlib.dll\n"
     90         "  implibflag = /IMPLIB:shlib.dll.lib\n\n";
     91     std::string out_str = out.str();
     92 #if defined(OS_WIN)
     93     std::replace(out_str.begin(), out_str.end(), '\\', '/');
     94 #endif
     95     EXPECT_EQ(expected_win, out_str);
     96   }
     97 
     98   // A static library that depends on the source set (should not link it).
     99   Target stlib_target(setup.settings(), Label(SourceDir("//foo/"), "stlib"));
    100   stlib_target.set_output_type(Target::STATIC_LIBRARY);
    101   stlib_target.deps().push_back(LabelTargetPair(&target));
    102   stlib_target.OnResolved();
    103 
    104   {
    105     std::ostringstream out;
    106     NinjaBinaryTargetWriter writer(&stlib_target, setup.toolchain(), out);
    107     writer.Run();
    108 
    109     // TODO(brettw) I think we'll need to worry about backslashes here
    110     // depending if we're on actual Windows or Linux pretending to be Windows.
    111     const char expected_win[] =
    112         "defines =\n"
    113         "includes =\n"
    114         "cflags =\n"
    115         "cflags_c =\n"
    116         "cflags_cc =\n"
    117         "cflags_objc =\n"
    118         "cflags_objcc =\n"
    119         "\n"
    120         "\n"
    121         "manifests = obj/foo/stlib.intermediate.manifest\n"
    122         "ldflags = /MANIFEST /ManifestFile:obj/foo/stlib.intermediate.manifest\n"
    123         "libs =\n"
    124         // There are no sources so there are no params to alink.
    125         "build obj/foo/stlib.lib: alink\n\n";
    126     std::string out_str = out.str();
    127 #if defined(OS_WIN)
    128     std::replace(out_str.begin(), out_str.end(), '\\', '/');
    129 #endif
    130     EXPECT_EQ(expected_win, out_str);
    131   }
    132 
    133 }
    134 
    135 TEST(NinjaBinaryTargetWriter, ProductExtension) {
    136   TestWithScope setup;
    137   setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
    138   setup.settings()->set_target_os(Settings::LINUX);
    139 
    140   // A shared library w/ the product_extension set to a custom value.
    141   Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
    142   target.set_output_type(Target::SHARED_LIBRARY);
    143   target.set_output_extension(std::string("so.6"));
    144   target.sources().push_back(SourceFile("//foo/input1.cc"));
    145   target.sources().push_back(SourceFile("//foo/input2.cc"));
    146   target.OnResolved();
    147 
    148   std::ostringstream out;
    149   NinjaBinaryTargetWriter writer(&target, setup.toolchain(), out);
    150   writer.Run();
    151 
    152   // TODO(brettw) I think we'll need to worry about backslashes here
    153   // depending if we're on actual Windows or Linux pretending to be Windows.
    154   const char expected[] =
    155       "defines =\n"
    156       "includes =\n"
    157       "cflags =\n"
    158       "cflags_c =\n"
    159       "cflags_cc =\n"
    160       "cflags_objc =\n"
    161       "cflags_objcc =\n"
    162       "\n"
    163       "build obj/foo/shlib.input1.o: cxx ../../foo/input1.cc\n"
    164       "build obj/foo/shlib.input2.o: cxx ../../foo/input2.cc\n"
    165       "\n"
    166       "ldflags =\n"
    167       "libs =\n"
    168       "build lib/libshlib.so.6: solink obj/foo/shlib.input1.o "
    169           "obj/foo/shlib.input2.o\n"
    170       "  soname = libshlib.so.6\n"
    171       "  lib = lib/libshlib.so.6\n"
    172       "\n";
    173 
    174   std::string out_str = out.str();
    175 #if defined(OS_WIN)
    176   std::replace(out_str.begin(), out_str.end(), '\\', '/');
    177 #endif
    178   EXPECT_EQ(expected, out_str);
    179 }
    180 
    181 TEST(NinjaBinaryTargetWriter, EmptyProductExtension) {
    182   TestWithScope setup;
    183   setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
    184   setup.settings()->set_target_os(Settings::LINUX);
    185 
    186   // This test is the same as ProductExtension, except that
    187   // we call set_output_extension("") and ensure that we still get the default.
    188   Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
    189   target.set_output_type(Target::SHARED_LIBRARY);
    190   target.set_output_extension(std::string());
    191   target.sources().push_back(SourceFile("//foo/input1.cc"));
    192   target.sources().push_back(SourceFile("//foo/input2.cc"));
    193 
    194   std::ostringstream out;
    195   NinjaBinaryTargetWriter writer(&target, setup.toolchain(), out);
    196   writer.Run();
    197 
    198   // TODO(brettw) I think we'll need to worry about backslashes here
    199   // depending if we're on actual Windows or Linux pretending to be Windows.
    200   const char expected[] =
    201       "defines =\n"
    202       "includes =\n"
    203       "cflags =\n"
    204       "cflags_c =\n"
    205       "cflags_cc =\n"
    206       "cflags_objc =\n"
    207       "cflags_objcc =\n"
    208       "\n"
    209       "build obj/foo/shlib.input1.o: cxx ../../foo/input1.cc\n"
    210       "build obj/foo/shlib.input2.o: cxx ../../foo/input2.cc\n"
    211       "\n"
    212       "ldflags =\n"
    213       "libs =\n"
    214       "build lib/libshlib.so: solink obj/foo/shlib.input1.o "
    215           "obj/foo/shlib.input2.o\n"
    216       "  soname = libshlib.so\n"
    217       "  lib = lib/libshlib.so\n"
    218       "\n";
    219 
    220   std::string out_str = out.str();
    221 #if defined(OS_WIN)
    222   std::replace(out_str.begin(), out_str.end(), '\\', '/');
    223 #endif
    224   EXPECT_EQ(expected, out_str);
    225 }
    226