Add dsymutil and strip support for executable and shared library builders (bug 6003 part 10, r=ds).
authorDavid Anderson <danderson@mozilla.com>
Sat Dec 28 10:22:08 2013 -0500 (2013-12-28)
changeset 21404964bf7d5db
parent 213 4d7dda072a21
child 215 272551b2c1e4
Add dsymutil and strip support for executable and shared library builders (bug 6003 part 10, r=ds).
ambuild2/frontend/amb2/gen.py
ambuild2/frontend/base_gen.py
ambuild2/frontend/cpp.py
scripts/ambuild_dsymutil_wrapper.sh
setup.py
tests/dsymutil/AMBuildScript
tests/dsymutil/configure.py
tests/dsymutil/main.cpp
     1.1 --- a/ambuild2/frontend/amb2/gen.py	Sat Dec 28 10:21:44 2013 -0500
     1.2 +++ b/ambuild2/frontend/amb2/gen.py	Sat Dec 28 10:22:08 2013 -0500
     1.3 @@ -510,20 +510,13 @@
     1.4        )
     1.5        inputs.append(rcNode)
     1.6  
     1.7 -    outputs = [binary.outputFile]
     1.8 -    if binary.pdbFile:
     1.9 -      outputs.append(binary.pdbFile)
    1.10 -  
    1.11 -    linkCmd, binNodes = self.addCommand(
    1.12 +    output_file, debug_file = binary.link(
    1.13        context = cx,
    1.14 -      node_type = nodetypes.Command,
    1.15        folder = folder_node,
    1.16 -      data = binary.argv,
    1.17 -      inputs = inputs,
    1.18 -      outputs = outputs
    1.19 +      inputs = inputs
    1.20      )
    1.21  
    1.22 -    return CppNodes(binNodes[0], binNodes[1:])
    1.23 +    return CppNodes(output_file, debug_file)
    1.24  
    1.25    def addFileOp(self, cmd, context, source, output_path):
    1.26      # Try to detect if our output_path is actually a folder, via trailing
     2.1 --- a/ambuild2/frontend/base_gen.py	Sat Dec 28 10:21:44 2013 -0500
     2.2 +++ b/ambuild2/frontend/base_gen.py	Sat Dec 28 10:22:08 2013 -0500
     2.3 @@ -122,12 +122,13 @@
     2.4    def AddCopy(self, source, output_path):
     2.5      return self.generator.addCopy(self, source, output_path)
     2.6  
     2.7 -  def AddCommand(self, inputs, argv, outputs, dep_type=None, weak_inputs=[]):
     2.8 +  def AddCommand(self, inputs, argv, outputs, folder=-1, dep_type=None, weak_inputs=[]):
     2.9      return self.generator.addShellCommand(
    2.10        self,
    2.11        inputs,
    2.12        argv,
    2.13        outputs,
    2.14 +      folder = folder,
    2.15        dep_type = dep_type,
    2.16        weak_inputs = weak_inputs
    2.17      )
    2.18 @@ -243,7 +244,7 @@
    2.19    def addCopy(self, context, source, output_path):
    2.20      raise Exception('Must be implemented!')
    2.21  
    2.22 -  def addShellCommand(self, context, inputs, argv, outputs, dep_type=None, weak_inputs=[]):
    2.23 +  def addShellCommand(self, context, inputs, argv, outputs, folder=-1, dep_type=None, weak_inputs=[]):
    2.24      raise Exception('Must be implemented!')
    2.25  
    2.26    def addConfigureFile(self, context, path):
     3.1 --- a/ambuild2/frontend/cpp.py	Sat Dec 28 10:21:44 2013 -0500
     3.2 +++ b/ambuild2/frontend/cpp.py	Sat Dec 28 10:22:08 2013 -0500
     3.3 @@ -26,12 +26,13 @@
     3.4      self.behavior = behavior
     3.5      self.command = command
     3.6      self.objSuffix = objSuffix
     3.7 +    self.debuginfo_argv = []
     3.8  
     3.9  class MSVC(Vendor):
    3.10    def __init__(self, command, version):
    3.11      super(MSVC, self).__init__('msvc', version, 'msvc', command, '.obj')
    3.12      self.definePrefix = '/D'
    3.13 -    self.pdbSuffix = '.pdb'
    3.14 +    self.debuginfo_argv = ['/Zi']
    3.15  
    3.16    @staticmethod
    3.17    def IncludePath(outputPath, includePath):
    3.18 @@ -63,7 +64,6 @@
    3.19      self.majorVersion = int(parts[0])
    3.20      self.minorVersion = int(parts[1])
    3.21      self.definePrefix = '-D'
    3.22 -    self.pdbSuffix = None
    3.23  
    3.24    def formatInclude(self, outputPath, includePath):
    3.25      return ['-I', os.path.normpath(includePath)]
    3.26 @@ -74,17 +74,18 @@
    3.27  class GCC(CompatGCC):
    3.28    def __init__(self, command, version):
    3.29      super(GCC, self).__init__('gcc', command, version)
    3.30 +    self.debuginfo_argv = ['-g3', '-ggdb3']
    3.31  
    3.32  class Clang(CompatGCC):
    3.33    def __init__(self, command, version):
    3.34      super(Clang, self).__init__('clang', command, version)
    3.35 +    self.debuginfo_argv = ['-g3']
    3.36  
    3.37  class SunPro(Vendor):
    3.38    def __init__(self, command, version):
    3.39      super(SunPro, self).__init__('sun', version, 'sun', command, '.o')
    3.40 -    parts = version.split('.')
    3.41      self.definePrefix = '-D'
    3.42 -    self.pdbSuffix = None
    3.43 +    self.debuginfo_argv = ['-g3']
    3.44  
    3.45    def formatInclude(self, outputPath, includePath):
    3.46      return ['-I', os.path.normpath(includePath)]
    3.47 @@ -272,6 +273,7 @@
    3.48    def __init__(self, cc, cxx):
    3.49      self.cc = cc
    3.50      self.cxx = cxx
    3.51 +    self.debuginfo = True
    3.52      for attr in Compiler.attrs:
    3.53        setattr(self, attr, [])
    3.54  
    3.55 @@ -279,6 +281,7 @@
    3.56      cc = Compiler(self.cc, self.cxx)
    3.57      cc.cc = self.cc
    3.58      cc.cxx = self.cxx
    3.59 +    cc.debuginfo = self.debuginfo
    3.60      for attr in Compiler.attrs:
    3.61        setattr(cc, attr, copy.copy(getattr(self, attr)))
    3.62      return cc
    3.63 @@ -302,6 +305,8 @@
    3.64    def __init__(self, outputPath, config, compiler):
    3.65      args = compiler.command.split(' ')
    3.66      args += config.cflags
    3.67 +    if config.debuginfo:
    3.68 +      args += compiler.debuginfo_argv
    3.69      if compiler == config.cxx:
    3.70        args += config.cxxflags
    3.71      args += [compiler.definePrefix + define for define in config.defines]
    3.72 @@ -442,7 +447,40 @@
    3.73          self.linker_ = self.compiler.cc
    3.74  
    3.75      files = [out.outputFile for out in self.objects + self.resources]
    3.76 -    self.argv, self.pdbFile = self.generateBinary(cx, files)
    3.77 +    self.argv = self.generateBinary(cx, files)
    3.78 +    self.linker_outputs = [self.outputFile]
    3.79 +    self.debug_entry = None
    3.80 +
    3.81 +    if self.compiler.debuginfo and not isinstance(self, StaticLibrary):
    3.82 +      if isinstance(self.linker_, MSVC):
    3.83 +        self.linker_outputs += [self.name_ + '.pdb']
    3.84 +      elif cx.target_platform is 'mac':
    3.85 +        bundle_folder = os.path.join(self.localFolder, self.outputFile + '.dSYM')
    3.86 +        bundle_entry = cx.AddFolder(bundle_folder)
    3.87 +        bundle_layout = [
    3.88 +          'Contents',
    3.89 +          'Contents/Resources',
    3.90 +          'Contents/Resources/DWARF',
    3.91 +        ]
    3.92 +        for folder in bundle_layout:
    3.93 +          cx.AddFolder(os.path.join(bundle_folder, folder))
    3.94 +        self.linker_outputs += [
    3.95 +          self.outputFile + '.dSYM/Contents/Info.plist',
    3.96 +          self.outputFile + '.dSYM/Contents/Resources/DWARF/' + self.outputFile
    3.97 +        ]
    3.98 +        self.debug_entry = bundle_entry
    3.99 +        self.argv = ['ambuild_dsymutil_wrapper.sh', self.outputFile] + self.argv
   3.100 +
   3.101 +  def link(self, context, folder, inputs):
   3.102 +    ignore, outputs = context.AddCommand(
   3.103 +      inputs = inputs,
   3.104 +      argv = self.argv,
   3.105 +      outputs = self.linker_outputs,
   3.106 +      folder = folder
   3.107 +    )
   3.108 +    if not self.debug_entry and self.compiler.debuginfo:
   3.109 +      self.debug_entry = outputs[-1]
   3.110 +    return outputs[0], self.debug_entry
   3.111  
   3.112  class Program(BinaryBuilder):
   3.113    def __init__(self, compiler, name):
   3.114 @@ -455,20 +493,19 @@
   3.115  
   3.116      if isinstance(self.linker_, MSVC):
   3.117        argv.append('/link')
   3.118 -    argv.extend(self.linkFlags(cx))
   3.119 -    if isinstance(self.linker_, MSVC):
   3.120 -      argv.append('/OUT:' + self.outputFile)
   3.121 -      argv.append('/DEBUG')
   3.122 +      argv.extend(self.linkFlags(cx))
   3.123        argv.append('/nologo')
   3.124 -      argv.append('/PDB:"' + self.name_ + '.pdb"')
   3.125 +      argv += [
   3.126 +        '/OUT:' + self.outputFile,
   3.127 +        '/nologo',
   3.128 +      ]
   3.129 +      if self.compiler.debuginfo:
   3.130 +        argv += ['/DEBUG', '/PDB:"' + self.name_ + '.pdb"']
   3.131      else:
   3.132 +      argv.extend(self.linkFlags(cx))
   3.133        argv.extend(['-o', self.outputFile])
   3.134  
   3.135 -    pdbFile = None
   3.136 -    if self.linker_.pdbSuffix:
   3.137 -      pdbFile = self.name_ + self.linker_.pdbSuffix
   3.138 -
   3.139 -    return argv, pdbFile
   3.140 +    return argv
   3.141  
   3.142  class Library(BinaryBuilder):
   3.143    def __init__(self, compiler, name):
   3.144 @@ -481,25 +518,24 @@
   3.145  
   3.146      if isinstance(self.linker_, MSVC):
   3.147        argv.append('/link')
   3.148 -    argv.extend(self.linkFlags(cx))
   3.149 -    if isinstance(self.linker_, MSVC):
   3.150 -      argv.append('/OUT:' + self.outputFile)
   3.151 -      argv.append('/DEBUG')
   3.152 -      argv.append('/nologo')
   3.153 -      argv.append('/DLL')
   3.154 -      argv.append('/PDB:"' + self.name_ + '.pdb"')
   3.155 +      argv.extend(self.linkFlags(cx))
   3.156 +      argv += [
   3.157 +        '/OUT:' + self.outputFile,
   3.158 +        '/DEBUG',
   3.159 +        '/nologo',
   3.160 +        '/DLL',
   3.161 +      ]
   3.162 +      if self.compiler.debuginfo:
   3.163 +        argv += ['/DEBUG', '/PDB:"' + self.name_ + '.pdb"']
   3.164      elif isinstance(self.linker_, CompatGCC):
   3.165 +      argv.extend(self.linkFlags(cx))
   3.166        if util.IsMac():
   3.167          argv.append('-dynamiclib')
   3.168        else:
   3.169          argv.append('-shared')
   3.170        argv.extend(['-o', self.outputFile])
   3.171  
   3.172 -    pdbFile = None
   3.173 -    if self.linker_.pdbSuffix:
   3.174 -      pdbFile = self.name_ + self.linker_.pdbSuffix
   3.175 -
   3.176 -    return argv, pdbFile
   3.177 +    return argv
   3.178  
   3.179  class StaticLibrary(BinaryBuilder):
   3.180    def __init__(self, compiler, name):
   3.181 @@ -512,4 +548,4 @@
   3.182      else:
   3.183        argv = ['ar', 'rcs', self.outputFile]
   3.184      argv += files
   3.185 -    return argv, None
   3.186 +    return argv
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/scripts/ambuild_dsymutil_wrapper.sh	Sat Dec 28 10:22:08 2013 -0500
     4.3 @@ -0,0 +1,26 @@
     4.4 +#!/bin/bash
     4.5 +
     4.6 +if [ $# -lt 3 ]; then
     4.7 +	echo "Usage: <file> <linker> <...linker args>";
     4.8 +	exit 1;
     4.9 +fi
    4.10 +
    4.11 +LD_FILE=$1
    4.12 +LD_EXEC=$2
    4.13 +
    4.14 +shift;
    4.15 +shift;
    4.16 +
    4.17 +$LD_EXEC $@
    4.18 +if [ $? -ne 0 ]; then
    4.19 +	exit $?
    4.20 +fi
    4.21 +dsymutil $LD_FILE
    4.22 +if [ $? -ne 0 ]; then
    4.23 +	exit $?
    4.24 +fi
    4.25 +strip -S $LD_FILE
    4.26 +if [ $? -ne 0 ]; then
    4.27 +	exit $?
    4.28 +fi
    4.29 +
     5.1 --- a/setup.py	Sat Dec 28 10:21:44 2013 -0500
     5.2 +++ b/setup.py	Sat Dec 28 10:22:08 2013 -0500
     5.3 @@ -9,6 +9,8 @@
     5.4  
     5.5  if sys.platform == 'win32':
     5.6    scripts.append('scripts/ambuild.bat')
     5.7 +elif sys.platform == 'darwin':
     5.8 +  scripts.append('scripts/ambuild_dsymutil_wrapper.sh')
     5.9  
    5.10  setup(
    5.11    name = 'AMBuild',
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tests/dsymutil/AMBuildScript	Sat Dec 28 10:22:08 2013 -0500
     6.3 @@ -0,0 +1,10 @@
     6.4 +# vim: set ts=8 sts=2 tw=99 et ft=python: 
     6.5 +import os, sys
     6.6 +
     6.7 +builder.DetectCompilers()
     6.8 +
     6.9 +program = builder.compiler.Program("hello")
    6.10 +program.sources = [
    6.11 +  'main.cpp'
    6.12 +]
    6.13 +builder.Add(program)
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tests/dsymutil/configure.py	Sat Dec 28 10:22:08 2013 -0500
     7.3 @@ -0,0 +1,6 @@
     7.4 +# vim: set sts=2 ts=8 sw=2 tw=99 et:
     7.5 +import sys
     7.6 +from ambuild2 import run
     7.7 +
     7.8 +builder = run.PrepareBuild(sourcePath = sys.path[0])
     7.9 +builder.Configure()
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tests/dsymutil/main.cpp	Sat Dec 28 10:22:08 2013 -0500
     8.3 @@ -0,0 +1,7 @@
     8.4 +#include <stdio.h>
     8.5 +
     8.6 +int main()
     8.7 +{
     8.8 +  return printf("hello!\n");
     8.9 +}
    8.10 +