Home | History | Annotate | Download | only in gn
      1 // Copyright 2014 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/substitution_type.h"
      6 
      7 #include <stdlib.h>
      8 
      9 #include "tools/gn/err.h"
     10 
     11 const char* kSubstitutionNames[SUBSTITUTION_NUM_TYPES] = {
     12   "<<literal>>",  // SUBSTITUTION_LITERAL
     13 
     14   "{{source}}",  // SUBSTITUTION_SOURCE
     15   "{{output}}",  // SUBSTITUTION_OUTPUT
     16 
     17   "{{source_name_part}}",  // SUBSTITUTION_NAME_PART
     18   "{{source_file_part}}",  // SUBSTITUTION_FILE_PART
     19   "{{source_dir}}",  // SUBSTITUTION_SOURCE_DIR
     20   "{{source_root_relative_dir}}",  // SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR
     21   "{{source_gen_dir}}",  // SUBSTITUTION_SOURCE_GEN_DIR
     22   "{{source_out_dir}}",  // SUBSTITUTION_SOURCE_OUT_DIR
     23 
     24   "{{label}}",  // SUBSTITUTION_LABEL
     25   "{{root_gen_dir}}",  // SUBSTITUTION_ROOT_GEN_DIR
     26   "{{root_out_dir}}",  // SUBSTITUTION_ROOT_OUT_DIR
     27   "{{target_gen_dir}}",  // SUBSTITUTION_TARGET_GEN_DIR
     28   "{{target_out_dir}}",  // SUBSTITUTION_TARGET_OUT_DIR
     29   "{{target_output_name}}",  // SUBSTITUTION_TARGET_OUTPUT_NAME
     30 
     31   "{{cflags}}",  // SUBSTITUTION_CFLAGS
     32   "{{cflags_c}}",  // SUBSTITUTION_CFLAGS_C
     33   "{{cflags_cc}}",  // SUBSTITUTION_CFLAGS_CC
     34   "{{cflags_objc}}",  // SUBSTITUTION_CFLAGS_OBJC
     35   "{{cflags_objcc}}",  // SUBSTITUTION_CFLAGS_OBJCC
     36   "{{defines}}",  // SUBSTITUTION_DEFINES
     37   "{{include_dirs}}",  // SUBSTITUTION_INCLUDE_DIRS
     38 
     39   "{{inputs}}",  // SUBSTITUTION_LINKER_INPUTS
     40   "{{inputs_newline}}",  // SUBSTITUTION_LINKER_INPUTS_NEWLINE
     41   "{{ldflags}}",  // SUBSTITUTION_LDFLAGS
     42   "{{libs}}",  // SUBSTITUTION_LIBS
     43   "{{output_extension}}",  // SUBSTITUTION_OUTPUT_EXTENSION
     44   "{{solibs}}",  // SUBSTITUTION_SOLIBS
     45 };
     46 
     47 const char* kSubstitutionNinjaNames[SUBSTITUTION_NUM_TYPES] = {
     48   NULL,  // SUBSTITUTION_LITERAL
     49 
     50   "in",  // SUBSTITUTION_SOURCE
     51   "out",  // SUBSTITUTION_OUTPUT
     52 
     53   "source_name_part",  // SUBSTITUTION_NAME_PART
     54   "source_file_part",  // SUBSTITUTION_FILE_PART
     55   "source_dir",  // SUBSTITUTION_SOURCE_DIR
     56   "source_root_relative_dir",  // SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR
     57   "source_gen_dir",  // SUBSTITUTION_SOURCE_GEN_DIR
     58   "source_out_dir",  // SUBSTITUTION_SOURCE_OUT_DIR
     59 
     60   "label",  // SUBSTITUTION_LABEL
     61   "root_gen_dir",  // SUBSTITUTION_ROOT_GEN_DIR
     62   "root_out_dir",  // SUBSTITUTION_ROOT_OUT_DIR
     63   "target_gen_dir",  // SUBSTITUTION_TARGET_GEN_DIR
     64   "target_out_dir",  // SUBSTITUTION_TARGET_OUT_DIR
     65   "target_output_name",  // SUBSTITUTION_TARGET_OUTPUT_NAME
     66 
     67   "cflags",  // SUBSTITUTION_CFLAGS
     68   "cflags_c",  // SUBSTITUTION_CFLAGS_C
     69   "cflags_cc",  // SUBSTITUTION_CFLAGS_CC
     70   "cflags_objc",  // SUBSTITUTION_CFLAGS_OBJC
     71   "cflags_objcc",  // SUBSTITUTION_CFLAGS_OBJCC
     72   "defines",  // SUBSTITUTION_DEFINES
     73   "include_dirs",  // SUBSTITUTION_INCLUDE_DIRS
     74 
     75   // LINKER_INPUTS expands to the same Ninja var as SUBSTITUTION_SOURCE. These
     76   // are used in different contexts and are named differently to keep things
     77   // clear, but they both expand to the "set of input files" for a build rule.
     78   "in",  // SUBSTITUTION_LINKER_INPUTS
     79   "in_newline",  // SUBSTITUTION_LINKER_INPUTS_NEWLINE
     80   "ldflags",  // SUBSTITUTION_LDFLAGS
     81   "libs",  // SUBSTITUTION_LIBS
     82   "output_extension",  // SUBSTITUTION_OUTPUT_EXTENSION
     83   "solibs",  // SUBSTITUTION_SOLIBS
     84 };
     85 
     86 SubstitutionBits::SubstitutionBits() : used() {
     87 }
     88 
     89 void SubstitutionBits::MergeFrom(const SubstitutionBits& other) {
     90   for (size_t i = 0; i < SUBSTITUTION_NUM_TYPES; i++)
     91     used[i] |= other.used[i];
     92 }
     93 
     94 void SubstitutionBits::FillVector(std::vector<SubstitutionType>* vect) const {
     95   for (size_t i = SUBSTITUTION_FIRST_PATTERN; i < SUBSTITUTION_NUM_TYPES; i++) {
     96     if (used[i])
     97       vect->push_back(static_cast<SubstitutionType>(i));
     98   }
     99 }
    100 
    101 bool SubstitutionIsInOutputDir(SubstitutionType type) {
    102   return type == SUBSTITUTION_SOURCE_GEN_DIR ||
    103          type == SUBSTITUTION_SOURCE_OUT_DIR ||
    104          type == SUBSTITUTION_ROOT_GEN_DIR ||
    105          type == SUBSTITUTION_ROOT_OUT_DIR ||
    106          type == SUBSTITUTION_TARGET_GEN_DIR ||
    107          type == SUBSTITUTION_TARGET_OUT_DIR;
    108 }
    109 
    110 bool IsValidSourceSubstitution(SubstitutionType type) {
    111   return type == SUBSTITUTION_LITERAL ||
    112          type == SUBSTITUTION_SOURCE ||
    113          type == SUBSTITUTION_SOURCE_NAME_PART ||
    114          type == SUBSTITUTION_SOURCE_FILE_PART ||
    115          type == SUBSTITUTION_SOURCE_DIR ||
    116          type == SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR ||
    117          type == SUBSTITUTION_SOURCE_GEN_DIR ||
    118          type == SUBSTITUTION_SOURCE_OUT_DIR;
    119 }
    120 
    121 bool IsValidToolSubstutition(SubstitutionType type) {
    122   return type == SUBSTITUTION_LITERAL ||
    123          type == SUBSTITUTION_OUTPUT ||
    124          type == SUBSTITUTION_LABEL ||
    125          type == SUBSTITUTION_ROOT_GEN_DIR ||
    126          type == SUBSTITUTION_ROOT_OUT_DIR ||
    127          type == SUBSTITUTION_TARGET_GEN_DIR ||
    128          type == SUBSTITUTION_TARGET_OUT_DIR ||
    129          type == SUBSTITUTION_TARGET_OUTPUT_NAME;
    130 }
    131 
    132 bool IsValidCompilerSubstitution(SubstitutionType type) {
    133   return IsValidToolSubstutition(type) ||
    134          IsValidSourceSubstitution(type) ||
    135          type == SUBSTITUTION_SOURCE ||
    136          type == SUBSTITUTION_CFLAGS ||
    137          type == SUBSTITUTION_CFLAGS_C ||
    138          type == SUBSTITUTION_CFLAGS_CC ||
    139          type == SUBSTITUTION_CFLAGS_OBJC ||
    140          type == SUBSTITUTION_CFLAGS_OBJCC ||
    141          type == SUBSTITUTION_DEFINES ||
    142          type == SUBSTITUTION_INCLUDE_DIRS;
    143 }
    144 
    145 bool IsValidCompilerOutputsSubstitution(SubstitutionType type) {
    146   // All tool types except "output" (which would be infinitely recursive).
    147   return (IsValidToolSubstutition(type) && type != SUBSTITUTION_OUTPUT) ||
    148          IsValidSourceSubstitution(type);
    149 }
    150 
    151 bool IsValidLinkerSubstitution(SubstitutionType type) {
    152   return IsValidToolSubstutition(type) ||
    153          type == SUBSTITUTION_LINKER_INPUTS ||
    154          type == SUBSTITUTION_LINKER_INPUTS_NEWLINE ||
    155          type == SUBSTITUTION_LDFLAGS ||
    156          type == SUBSTITUTION_LIBS ||
    157          type == SUBSTITUTION_OUTPUT_EXTENSION ||
    158          type == SUBSTITUTION_SOLIBS;
    159 }
    160 
    161 bool IsValidLinkerOutputsSubstitution(SubstitutionType type) {
    162   // All valid compiler outputs plus the output extension.
    163   return IsValidCompilerOutputsSubstitution(type) ||
    164          type == SUBSTITUTION_OUTPUT_EXTENSION;
    165 }
    166 
    167 bool IsValidCopySubstitution(SubstitutionType type) {
    168   return IsValidToolSubstutition(type) ||
    169          type == SUBSTITUTION_SOURCE;
    170 }
    171 
    172 bool EnsureValidSourcesSubstitutions(
    173     const std::vector<SubstitutionType>& types,
    174     const ParseNode* origin,
    175     Err* err) {
    176   for (size_t i = 0; i < types.size(); i++) {
    177     if (!IsValidSourceSubstitution(types[i])) {
    178       *err = Err(origin, "Invalid substitution type.",
    179           "The substitution " + std::string(kSubstitutionNames[i]) +
    180           " isn't valid for something\n"
    181           "operating on a source file such as this.");
    182       return false;
    183     }
    184   }
    185   return true;
    186 }
    187