Exemple #1
0
 def GetPostbuildCommand(self, spec, output, output_binary,
                         is_command_start=False):
   """Returns a shell command that runs all the postbuilds, and removes
   |output| if any of them fails. If |is_command_start| is False, then the
   returned string will start with ' && '."""
   if not self.xcode_settings or spec['type'] == 'none' or not output:
     return ''
   output = QuoteShellArgument(output)
   target_postbuilds = self.xcode_settings.GetTargetPostbuilds(
       self.config_name, output, QuoteShellArgument(output_binary), quiet=True)
   postbuilds = gyp.xcode_emulation.GetSpecPostbuildCommands(
       spec, self.GypPathToNinja, quiet=True)
   postbuilds = target_postbuilds + postbuilds
   if not postbuilds:
     return ''
   env = self.ComputeExportEnvString(self.GetXcodePostbuildEnv())
   commands = env + ' F=0; ' + \
       ' '.join([ninja_syntax.escape(command) + ' || F=$$?;'
                                for command in postbuilds])
   command_string = env + commands + ' ((exit $$F) || rm -rf %s) ' % output + \
                    '&& exit $$F)'
   if is_command_start:
     return '(' + command_string + ' && '
   else:
     return '$ && (' + command_string
Exemple #2
0
    def WriteSources(self, config, sources, predepends):
        """Write build rules to compile all of |sources|."""
        if self.toolset == "host":
            self.ninja.variable("cc", "$cc_host")
            self.ninja.variable("cxx", "$cxx_host")

        self.WriteVariableList(
            "defines", ["-D" + MaybeQuoteShellArgument(ninja_syntax.escape(d)) for d in config.get("defines", [])]
        )
        self.WriteVariableList("includes", ["-I" + self.GypPathToNinja(i) for i in config.get("include_dirs", [])])
        self.WriteVariableList("cflags", config.get("cflags"))
        self.WriteVariableList("cflags_c", config.get("cflags_c"))
        self.WriteVariableList("cflags_cc", config.get("cflags_cc"))
        self.ninja.newline()
        outputs = []
        for source in sources:
            filename, ext = os.path.splitext(source)
            ext = ext[1:]
            if ext in ("cc", "cpp", "cxx"):
                command = "cxx"
            elif ext in ("c", "s", "S"):
                command = "cc"
            else:
                # TODO: should we assert here on unexpected extensions?
                continue
            input = self.GypPathToNinja(source)
            output = self.GypPathToUniqueOutput(filename + ".o")
            self.ninja.build(output, command, input, order_only=predepends)
            outputs.append(output)
        self.ninja.newline()
        return outputs
Exemple #3
0
  def WriteSources(self, config, sources, predepends):
    """Write build rules to compile all of |sources|."""
    if self.toolset == 'host':
      self.ninja.variable('cc', '$cc_host')
      self.ninja.variable('cxx', '$cxx_host')

    self.WriteVariableList('defines',
        ['-D' + MaybeQuoteShellArgument(ninja_syntax.escape(d))
         for d in config.get('defines', [])])
    self.WriteVariableList('includes',
                           ['-I' + self.GypPathToNinja(i)
                            for i in config.get('include_dirs', [])])
    self.WriteVariableList('cflags', config.get('cflags'))
    self.WriteVariableList('cflags_c', config.get('cflags_c'))
    self.WriteVariableList('cflags_cc', config.get('cflags_cc'))
    self.ninja.newline()
    outputs = []
    for source in sources:
      filename, ext = os.path.splitext(source)
      ext = ext[1:]
      if ext in ('cc', 'cpp', 'cxx'):
        command = 'cxx'
      elif ext in ('c', 's', 'S'):
        command = 'cc'
      else:
        # TODO: should we assert here on unexpected extensions?
        continue
      input = self.GypPathToNinja(source)
      output = self.GypPathToUniqueOutput(filename + '.o')
      self.ninja.build(output, command, input,
                       order_only=predepends)
      outputs.append(output)
    self.ninja.newline()
    return outputs
Exemple #4
0
 def GetPostbuildCommand(self, spec, output, output_binary,
                         is_command_start=False):
   """Returns a shell command that runs all the postbuilds, and removes
   |output| if any of them fails. If |is_command_start| is False, then the
   returned string will start with ' && '."""
   if not self.xcode_settings or spec['type'] == 'none' or not output:
     return ''
   output = QuoteShellArgument(output, self.flavor)
   target_postbuilds = self.xcode_settings.GetTargetPostbuilds(
       self.config_name,
       output,
       QuoteShellArgument(output_binary, self.flavor),
       quiet=True)
   postbuilds = gyp.xcode_emulation.GetSpecPostbuildCommands(
       spec, self.GypPathToNinja, quiet=True)
   postbuilds = target_postbuilds + postbuilds
   if not postbuilds:
     return ''
   env = self.ComputeExportEnvString(self.GetXcodePostbuildEnv())
   commands = env + ' F=0; ' + \
       ' '.join([ninja_syntax.escape(command) + ' || F=$$?;'
                                for command in postbuilds])
   command_string = env + commands + ' ((exit $$F) || rm -rf %s) ' % output + \
                    '&& exit $$F)'
   if is_command_start:
     return '(' + command_string + ' && '
   else:
     return '$ && (' + command_string
def Define(d, flavor):
    """Takes a preprocessor define and returns a -D parameter that's ninja- and
  shell-escaped."""
    if flavor == 'win':
        # cl.exe replaces literal # characters with = in preprocesor definitions for
        # some reason. Octal-encode to work around that.
        d = d.replace('#', '\\%03o' % ord('#'))
    return QuoteShellArgument(ninja_syntax.escape('-D' + d), flavor)
Exemple #6
0
def Define(d, flavor):
  """Takes a preprocessor define and returns a -D parameter that's ninja- and
  shell-escaped."""
  if flavor == 'win':
    # cl.exe replaces literal # characters with = in preprocesor definitions for
    # some reason. Octal-encode to work around that.
    d = d.replace('#', '\\%03o' % ord('#'))
  return QuoteShellArgument(ninja_syntax.escape('-D' + d), flavor)
Exemple #7
0
 def ComputeExportEnvString(self, env):
   """Given an environment, returns a string looking like
       'export FOO=foo; export BAR="${FOO} bar;'
   that exports |env| to the shell."""
   export_str = []
   for k in gyp.xcode_emulation.TopologicallySortedEnvVarKeys(env):
     export_str.append('export %s=%s;' %
         (k, ninja_syntax.escape(gyp.common.EncodePOSIXShellArgument(env[k]))))
   return ' '.join(export_str)
Exemple #8
0
 def ComputeExportEnvString(self, env):
   """Given an environment, returns a string looking like
       'export FOO=foo; export BAR="${FOO} bar;'
   that exports |env| to the shell."""
   export_str = []
   for k in gyp.xcode_emulation.TopologicallySortedEnvVarKeys(env):
     export_str.append('export %s=%s;' %
         (k, ninja_syntax.escape(gyp.common.EncodePOSIXShellArgument(env[k]))))
   return ' '.join(export_str)
Exemple #9
0
  def WriteSources(self, config, sources, predepends):
    """Write build rules to compile all of |sources|."""
    if self.toolset == 'host':
      self.ninja.variable('cc', '$cc_host')
      self.ninja.variable('cxx', '$cxx_host')

    if self.flavor == 'mac':
      # TODO(jeremya/thakis): Extract these from XcodeSettings instead.
      cflags = []
      cflags_c = []
      cflags_cc = []
      cflags_objc = []
      cflags_objcc = []
    else:
      cflags = config.get('cflags', [])
      cflags_c = config.get('cflags_c', [])
      cflags_cc = config.get('cflags_cc', [])

    self.WriteVariableList('defines',
        [QuoteShellArgument(ninja_syntax.escape('-D' + d))
         for d in config.get('defines', [])])
    self.WriteVariableList('includes',
                           ['-I' + self.GypPathToNinja(i)
                            for i in config.get('include_dirs', [])])
    self.WriteVariableList('cflags', map(self.ExpandSpecial, cflags))
    self.WriteVariableList('cflags_c', map(self.ExpandSpecial, cflags_c))
    self.WriteVariableList('cflags_cc', map(self.ExpandSpecial, cflags_cc))
    if self.flavor == 'mac':
      self.WriteVariableList('cflags_objc', map(self.ExpandSpecial,
                                             cflags_objc))
      self.WriteVariableList('cflags_objcc', map(self.ExpandSpecial,
                                              cflags_objcc))
    self.ninja.newline()
    outputs = []
    for source in sources:
      filename, ext = os.path.splitext(source)
      ext = ext[1:]
      if ext in ('cc', 'cpp', 'cxx'):
        command = 'cxx'
      elif ext in ('c', 's', 'S'):
        command = 'cc'
      elif self.flavor == 'mac' and ext == 'm':
        command = 'objc'
      elif self.flavor == 'mac' and ext == 'mm':
        command = 'objcxx'
      else:
        # TODO: should we assert here on unexpected extensions?
        continue
      input = self.GypPathToNinja(source)
      output = self.GypPathToUniqueOutput(filename + '.o')
      self.ninja.build(output, command, input,
                       order_only=predepends)
      outputs.append(output)
    self.ninja.newline()
    return outputs
Exemple #10
0
  def WriteNewNinjaRule(self, name, args, description, env={}):
    """Write out a new ninja "rule" statement for a given command.

    Returns the name of the new rule."""

    # TODO: we shouldn't need to qualify names; we do it because
    # currently the ninja rule namespace is global, but it really
    # should be scoped to the subninja.
    rule_name = self.name
    if self.toolset == 'target':
      rule_name += '.' + self.toolset
    rule_name += '.' + name
    rule_name = rule_name.replace(' ', '_')

    args = args[:]

    # gyp dictates that commands are run from the base directory.
    # cd into the directory before running, and adjust paths in
    # the arguments to point to the proper locations.
    if self.flavor == 'win':
      cd = 'cmd /s /c "cd %s && ' % self.build_to_base
    else:
      cd = 'cd %s; ' % self.build_to_base
    args = [self.ExpandSpecial(arg, self.base_to_build) for arg in args]
    env = self.ComputeExportEnvString(env)
    if self.flavor == 'win':
      # TODO(scottmg): Really don't want encourage cygwin, but I'm not sure
      # how much sh is depended upon. For now, double quote args to make most
      # things work.
      command = args[0] + ' "' + '" "'.join(args[1:]) + '""'
    else:
      command = gyp.common.EncodePOSIXShellList(args)
    if env:
      # If an environment is passed in, variables in the command should be
      # read from it, instead of from ninja's internal variables.
      command = ninja_syntax.escape(command)

    command = cd + env + command
    # GYP rules/actions express being no-ops by not touching their outputs.
    # Avoid executing downstream dependencies in this case by specifying
    # restat=1 to ninja.
    self.ninja.rule(rule_name, command, description, restat=True)
    self.ninja.newline()

    return rule_name
Exemple #11
0
  def WriteMacInfoPlist(self, bundle_depends):
    """Write build rules for bundle Info.plist files."""
    info_plist, out, defines, extra_env = gyp.xcode_emulation.GetMacInfoPlist(
        self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']),
        self.xcode_settings, self.GypPathToNinja)
    if not info_plist:
      return
    if defines:
      # Create an intermediate file to store preprocessed results.
      intermediate_plist = self.GypPathToUniqueOutput(
          os.path.basename(info_plist))
      defines = ' '.join(
          [QuoteShellArgument(ninja_syntax.escape('-D' + d)) for d in defines])
      info_plist = self.ninja.build(intermediate_plist, 'infoplist', info_plist,
                                    variables=[('defines',defines)])

    env = self.GetXcodeEnv(additional_settings=extra_env)
    env = self.ComputeExportEnvString(env)

    self.ninja.build(out, 'mac_tool', info_plist,
                     variables=[('mactool_cmd', 'copy-info-plist'),
                                ('env', env)])
    bundle_depends.append(out)
Exemple #12
0
  def WriteMacInfoPlist(self, bundle_depends):
    """Write build rules for bundle Info.plist files."""
    info_plist, out, defines, extra_env = gyp.xcode_emulation.GetMacInfoPlist(
        self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']),
        self.xcode_settings, self.GypPathToNinja)
    if not info_plist:
      return
    if defines:
      # Create an intermediate file to store preprocessed results.
      intermediate_plist = self.GypPathToUniqueOutput(
          os.path.basename(info_plist))
      defines = ' '.join(
          [QuoteShellArgument(ninja_syntax.escape('-D' + d)) for d in defines])
      info_plist = self.ninja.build(intermediate_plist, 'infoplist', info_plist,
                                    variables=[('defines',defines)])

    env = self.GetXcodeEnv(additional_settings=extra_env)
    env = self.ComputeExportEnvString(env)

    self.ninja.build(out, 'mac_tool', info_plist,
                     variables=[('mactool_cmd', 'copy-info-plist'),
                                ('env', env)])
    bundle_depends.append(out)
Exemple #13
0
  def WriteNewNinjaRule(self, name, args, description, env={}):
    """Write out a new ninja "rule" statement for a given command.

    Returns the name of the new rule."""

    # TODO: we shouldn't need to qualify names; we do it because
    # currently the ninja rule namespace is global, but it really
    # should be scoped to the subninja.
    rule_name = self.name
    if self.toolset == 'target':
      rule_name += '.' + self.toolset
    rule_name += '.' + name
    rule_name = rule_name.replace(' ', '_')

    args = args[:]

    # gyp dictates that commands are run from the base directory.
    # cd into the directory before running, and adjust paths in
    # the arguments to point to the proper locations.
    cd = 'cd %s; ' % self.build_to_base
    args = [self.ExpandSpecial(arg, self.base_to_build) for arg in args]
    env = self.ComputeExportEnvString(env)
    command = gyp.common.EncodePOSIXShellList(args)
    if env:
      # If an environment is passed in, variables in the command should be
      # read from it, instead of from ninja's internal variables.
      command = ninja_syntax.escape(command)

    command = cd + env + command
    # GYP rules/actions express being no-ops by not touching their outputs.
    # Avoid executing downstream dependencies in this case by specifying
    # restat=1 to ninja.
    self.ninja.rule(rule_name, command, description, restat=True)
    self.ninja.newline()

    return rule_name
Exemple #14
0
  def WriteSources(self, config_name, config, sources, predepends,
                   precompiled_header):
    """Write build rules to compile all of |sources|."""
    if self.toolset == 'host':
      self.ninja.variable('cc', '$cc_host')
      self.ninja.variable('cxx', '$cxx_host')

    if self.flavor == 'mac':
      cflags = self.xcode_settings.GetCflags(config_name)
      cflags_c = self.xcode_settings.GetCflagsC(config_name)
      cflags_cc = self.xcode_settings.GetCflagsCC(config_name)
      cflags_objc = ['$cflags_c'] + \
                    self.xcode_settings.GetCflagsObjC(config_name)
      cflags_objcc = ['$cflags_cc'] + \
                     self.xcode_settings.GetCflagsObjCC(config_name)
    else:
      cflags = config.get('cflags', [])
      cflags_c = config.get('cflags_c', [])
      cflags_cc = config.get('cflags_cc', [])

    self.WriteVariableList('defines',
        [QuoteShellArgument(ninja_syntax.escape('-D' + d), self.flavor)
         for d in config.get('defines', [])])
    self.WriteVariableList('includes',
                           ['-I' + self.GypPathToNinja(i)
                            for i in config.get('include_dirs', [])])

    pch_commands = precompiled_header.GetGchBuildCommands()
    if self.flavor == 'mac':
      self.WriteVariableList('cflags_pch_c',
                             [precompiled_header.GetInclude('c')])
      self.WriteVariableList('cflags_pch_cc',
                             [precompiled_header.GetInclude('cc')])
      self.WriteVariableList('cflags_pch_objc',
                             [precompiled_header.GetInclude('m')])
      self.WriteVariableList('cflags_pch_objcc',
                             [precompiled_header.GetInclude('mm')])

    self.WriteVariableList('cflags', map(self.ExpandSpecial, cflags))
    self.WriteVariableList('cflags_c', map(self.ExpandSpecial, cflags_c))
    self.WriteVariableList('cflags_cc', map(self.ExpandSpecial, cflags_cc))
    if self.flavor == 'mac':
      self.WriteVariableList('cflags_objc', map(self.ExpandSpecial,
                                                cflags_objc))
      self.WriteVariableList('cflags_objcc', map(self.ExpandSpecial,
                                                 cflags_objcc))
    self.ninja.newline()
    outputs = []
    for source in sources:
      filename, ext = os.path.splitext(source)
      ext = ext[1:]
      if ext in ('cc', 'cpp', 'cxx'):
        command = 'cxx'
      elif ext in ('c', 's', 'S'):
        command = 'cc'
      elif self.flavor == 'mac' and ext == 'm':
        command = 'objc'
      elif self.flavor == 'mac' and ext == 'mm':
        command = 'objcxx'
      else:
        # TODO: should we assert here on unexpected extensions?
        continue
      input = self.GypPathToNinja(source)
      output = self.GypPathToUniqueOutput(filename + self.obj_ext)
      implicit = precompiled_header.GetObjDependencies([input], [output])
      self.ninja.build(output, command, input,
                       implicit=[gch for _, _, gch in implicit],
                       order_only=predepends)
      outputs.append(output)

    self.WritePchTargets(pch_commands)

    self.ninja.newline()
    return outputs
Exemple #15
0
  def WriteSources(self, config_name, config, sources, predepends,
                   precompiled_header):
    """Write build rules to compile all of |sources|."""
    if self.toolset == 'host':
      self.ninja.variable('cc', '$cc_host')
      self.ninja.variable('cxx', '$cxx_host')

    if self.flavor == 'mac':
      cflags = self.xcode_settings.GetCflags(config_name)
      cflags_c = self.xcode_settings.GetCflagsC(config_name)
      cflags_cc = self.xcode_settings.GetCflagsCC(config_name)
      cflags_objc = ['$cflags_c'] + \
                    self.xcode_settings.GetCflagsObjC(config_name)
      cflags_objcc = ['$cflags_cc'] + \
                     self.xcode_settings.GetCflagsObjCC(config_name)
    else:
      cflags = config.get('cflags', [])
      cflags_c = config.get('cflags_c', [])
      cflags_cc = config.get('cflags_cc', [])

    self.WriteVariableList('defines',
        [QuoteShellArgument(ninja_syntax.escape('-D' + d))
         for d in config.get('defines', [])])
    self.WriteVariableList('includes',
                           ['-I' + self.GypPathToNinja(i)
                            for i in config.get('include_dirs', [])])

    pch_commands = precompiled_header.GetGchBuildCommands()
    if self.flavor == 'mac':
      self.WriteVariableList('cflags_pch_c',
                             [precompiled_header.GetInclude('c')])
      self.WriteVariableList('cflags_pch_cc',
                             [precompiled_header.GetInclude('cc')])
      self.WriteVariableList('cflags_pch_objc',
                             [precompiled_header.GetInclude('m')])
      self.WriteVariableList('cflags_pch_objcc',
                             [precompiled_header.GetInclude('mm')])

    self.WriteVariableList('cflags', map(self.ExpandSpecial, cflags))
    self.WriteVariableList('cflags_c', map(self.ExpandSpecial, cflags_c))
    self.WriteVariableList('cflags_cc', map(self.ExpandSpecial, cflags_cc))
    if self.flavor == 'mac':
      self.WriteVariableList('cflags_objc', map(self.ExpandSpecial,
                                                cflags_objc))
      self.WriteVariableList('cflags_objcc', map(self.ExpandSpecial,
                                                 cflags_objcc))
    self.ninja.newline()
    outputs = []
    for source in sources:
      filename, ext = os.path.splitext(source)
      ext = ext[1:]
      if ext in ('cc', 'cpp', 'cxx'):
        command = 'cxx'
      elif ext in ('c', 's', 'S'):
        command = 'cc'
      elif self.flavor == 'mac' and ext == 'm':
        command = 'objc'
      elif self.flavor == 'mac' and ext == 'mm':
        command = 'objcxx'
      else:
        # TODO: should we assert here on unexpected extensions?
        continue
      input = self.GypPathToNinja(source)
      output = self.GypPathToUniqueOutput(filename + self.obj_ext)
      implicit = precompiled_header.GetObjDependencies([input], [output])
      self.ninja.build(output, command, input,
                       implicit=[gch for _, _, gch in implicit],
                       order_only=predepends)
      outputs.append(output)

    self.WritePchTargets(pch_commands)

    self.ninja.newline()
    return outputs