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 "tools/gn/binary_target_generator.h"
      6 
      7 #include "tools/gn/config_values_generator.h"
      8 #include "tools/gn/deps_iterator.h"
      9 #include "tools/gn/err.h"
     10 #include "tools/gn/functions.h"
     11 #include "tools/gn/scope.h"
     12 #include "tools/gn/value_extractors.h"
     13 #include "tools/gn/variables.h"
     14 
     15 BinaryTargetGenerator::BinaryTargetGenerator(
     16     Target* target,
     17     Scope* scope,
     18     const FunctionCallNode* function_call,
     19     Target::OutputType type,
     20     Err* err)
     21     : TargetGenerator(target, scope, function_call, err),
     22       output_type_(type) {
     23 }
     24 
     25 BinaryTargetGenerator::~BinaryTargetGenerator() {
     26 }
     27 
     28 void BinaryTargetGenerator::DoRun() {
     29   target_->set_output_type(output_type_);
     30 
     31   if (!FillOutputName())
     32     return;
     33 
     34   if (!FillOutputExtension())
     35     return;
     36 
     37   if (!FillSources())
     38     return;
     39 
     40   if (!FillPublic())
     41     return;
     42 
     43   if (!FillCheckIncludes())
     44     return;
     45 
     46   if (!FillInputs())
     47     return;
     48 
     49   if (!FillConfigs())
     50     return;
     51 
     52   if (!FillAllowCircularIncludesFrom())
     53     return;
     54 
     55   if (!FillCompleteStaticLib())
     56     return;
     57 
     58   // Config values (compiler flags, etc.) set directly on this target.
     59   ConfigValuesGenerator gen(&target_->config_values(), scope_,
     60                             scope_->GetSourceDir(), err_);
     61   gen.Run();
     62   if (err_->has_error())
     63     return;
     64 }
     65 
     66 bool BinaryTargetGenerator::FillCheckIncludes() {
     67   const Value* value = scope_->GetValue(variables::kCheckIncludes, true);
     68   if (!value)
     69     return true;
     70   if (!value->VerifyTypeIs(Value::BOOLEAN, err_))
     71     return false;
     72   target_->set_check_includes(value->boolean_value());
     73   return true;
     74 }
     75 
     76 bool BinaryTargetGenerator::FillCompleteStaticLib() {
     77   if (target_->output_type() == Target::STATIC_LIBRARY) {
     78     const Value* value = scope_->GetValue(variables::kCompleteStaticLib, true);
     79     if (!value)
     80       return true;
     81     if (!value->VerifyTypeIs(Value::BOOLEAN, err_))
     82       return false;
     83     target_->set_complete_static_lib(value->boolean_value());
     84   }
     85   return true;
     86 }
     87 
     88 bool BinaryTargetGenerator::FillOutputName() {
     89   const Value* value = scope_->GetValue(variables::kOutputName, true);
     90   if (!value)
     91     return true;
     92   if (!value->VerifyTypeIs(Value::STRING, err_))
     93     return false;
     94   target_->set_output_name(value->string_value());
     95   return true;
     96 }
     97 
     98 bool BinaryTargetGenerator::FillOutputExtension() {
     99   const Value* value = scope_->GetValue(variables::kOutputExtension, true);
    100   if (!value)
    101     return true;
    102   if (!value->VerifyTypeIs(Value::STRING, err_))
    103     return false;
    104   target_->set_output_extension(value->string_value());
    105   return true;
    106 }
    107 
    108 bool BinaryTargetGenerator::FillAllowCircularIncludesFrom() {
    109   const Value* value = scope_->GetValue(
    110       variables::kAllowCircularIncludesFrom, true);
    111   if (!value)
    112     return true;
    113 
    114   UniqueVector<Label> circular;
    115   ExtractListOfUniqueLabels(*value, scope_->GetSourceDir(),
    116                             ToolchainLabelForScope(scope_), &circular, err_);
    117   if (err_->has_error())
    118     return false;
    119 
    120   // Validate that all circular includes entries are in the deps.
    121   for (size_t circular_i = 0; circular_i < circular.size(); circular_i++) {
    122     bool found_dep = false;
    123     for (DepsIterator iter(target_, DepsIterator::LINKED_ONLY);
    124          !iter.done(); iter.Advance()) {
    125       if (iter.label() == circular[circular_i]) {
    126         found_dep = true;
    127         break;
    128       }
    129     }
    130     if (!found_dep) {
    131       *err_ = Err(*value, "Label not in deps.",
    132           "The label \"" + circular[circular_i].GetUserVisibleName(false) +
    133           "\"\nwas not in the deps of this target. "
    134           "allow_circular_includes_from only allows\ntargets present in the "
    135           "deps.");
    136       return false;
    137     }
    138   }
    139 
    140   // Add to the set.
    141   for (size_t i = 0; i < circular.size(); i++)
    142     target_->allow_circular_includes_from().insert(circular[i]);
    143   return true;
    144 }
    145