Add dsymutil and strip support for executable and shared library builders (bug 5997 part 10, r=ds).
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 +